if column == 'testo':
return escape('{0}'.format(row.testo))
if column == 'mod':
- return '<a class="btn btn-sm btn-primary" href="#" ><i class="fas fa-edit"></i></a>' #% row.pk
+ return '<a class="btn btn-sm btn-primary" href="/mod_percorso/%s/" ><i class="fas fa-edit"></i></a>' % row.pk
if column == 'del':
- return '<a class="btn btn-sm btn-danger" href="#" ><i class="fas fa-trash"></i></a>' #% row.pk
+ return '<a class="btn btn-sm btn-danger" href="DeletePercorso(%s)" ><i class="fas fa-trash"></i></a>' % row.pk
else:
return super(PercorsoDatatables, self).render_column(row, column)
--- /dev/null
+{% extends 'base.html' %}
+{% load static %}
+{% block content %}
+
+ <div class="row">
+ <div class="col-12 col-md-12 col-lg-12">
+ <h1 class="line-listini"><i class="fa-solid fa-route clr-listini mr-2" aria-hidden="true"></i> Gestione
+ percorsi </h1>
+ <div class="card">
+ <div class="card-header">
+ {% if form.instance.pk %}
+ <h4 class="clr-config">Modifica il percorso #{{ form.instance.pk }}</h4>
+ {% else %}
+ <h4 class="clr-config">Crea una nuovo percorso nel sistema</h4>
+ {% endif %}
+ </div>
+
+ <div class="card-body">
+ <div class="row">
+ <div id="sel-localita" class="col-lg-3 col-md-3 col-sm-3 col-xs-3 pr-0 pt-3">
+ <h4>Seleziona i punti di interesse</h4>
+ <br>
+ <div id="sidebar">
+ <b>Partenza</b>
+ <select class="form-select" id="select-start">
+ </select>
+
+ <br>
+ <b>Tappe</b>
+ <select class="form-select" multiple id="select-tappe">
+ </select>
+
+ <br>
+ <b>Arrivo</b>
+ <select class="form-select" id="select-end">
+ </select>
+
+ <br />
+ <button class="btn-sm btn-primary" onclick="getCoordinates()">Genera Percorso</button>
+ <button class="btn-sm btn-primary" onclick="">Reset</button>
+
+ <br>
+ <br>
+ <button class="btn-sm btn-success" onclick="">Salva</button>
+
+ </div>
+ </div>
+ <div id="map-div" class="col-lg-9 col-md-9 col-sm-9 col-xs-9 pr-0 pt-3">
+ <div id="map" style="height: 650px"></div>
+ <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDzVvxHi5OWsa7R7Rg5lrXQynqPgU0oiD0&callback=initMap"
+ async></script>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+
+
+ <script>
+ var list_tappe = [];
+ var selected_items = []
+
+ $(document).ready(function () {
+ updateSelect();
+ });
+
+ function updateSelect(){
+ $('#select-start').append($("<option></option>").attr("value", 0).text(''));
+ $('#select-end').append($("<option></option>").attr("value", 0).text(''));
+ //$('#select-tappe').append($("<option></option>").attr("value", 0).text(''));
+
+ {% for poi in poi_list %}
+ $('#select-start').append($("<option></option>")
+ .attr("value", {{ poi.id }}).text('{{ poi.nome|safe }}'));
+
+ $('#select-end').append($("<option></option>")
+ .attr("value", {{ poi.id }}).text('{{ poi.nome|safe }}'));
+
+ $('#select-tappe').append($("<option></option>")
+ .attr("value", {{ poi.id }}).text('{{ poi.nome|safe }}'));
+ {% endfor %}
+ }
+
+
+ function initMap() {
+ const uluru = {lat: 41.9109, lng: 12.4818};
+
+ const map = new google.maps.Map(document.getElementById("map"), {
+ zoom: 6,
+ center: uluru,
+ });
+
+ }
+
+ $("#select-tappe").on('click','option',function(){
+ list_tappe.push($(this).val())
+ });
+
+
+ window.initMap = initMap;
+
+
+ function getCoordinates(){
+ selected_items = $("#select-tappe").val()
+ selected_items_list = list_tappe.filter(value => selected_items.includes(value));
+
+ $.ajax({
+ type: "GET",
+ url: "{% url 'sistema:get_coordinates' %}",
+ data: { 'poi': selected_items_list,
+ 'start': $("#select-start").val(),
+ 'end': $("#select-end").val(),
+ },
+ })
+ .done(function (response) {
+ drawRoutes(response.response.start_coords, response.response.end_coords, response.response.tappe)
+ })
+ .fail(function (jqXHR, textStatus, errorThrown) {
+ errore = ''
+ if (typeof jqXHR.responseText.reason === 'string' || jqXHR.responseText.reason instanceof String) {
+ errore = jqXHR.responseText
+ } else {
+ for (var i = 0; i < jqXHR.responseJSON.reason.length; i++) {
+ errore += jqXHR.responseJSON.reason[i]
+ errore += '<br>'
+ }
+ }
+ Swal.fire("Attenzione!", errore, "error")
+
+ });
+ }
+
+ function drawRoutes(start, end, poi){
+ var directionsService = new google.maps.DirectionsService;
+ var directionsDisplay = new google.maps.DirectionsRenderer;
+
+ const uluru = {lat: 41.9109, lng: 12.4818};
+ const map = new google.maps.Map(document.getElementById("map"), {
+ zoom: 6,
+ center: uluru,
+ });
+
+ directionsDisplay.setMap(map);
+
+ list_poi = []
+ for (var k in poi){
+ dict = {
+ stopover: true,
+ location: new google.maps.LatLng(poi[k].lat, poi[k].long)
+ }
+
+ list_poi.push(dict)
+ }
+
+ directionsService.route({
+ origin: new google.maps.LatLng(start.lat, start.long),
+ destination: new google.maps.LatLng(end.lat, end.long),
+ waypoints: list_poi,
+ optimizeWaypoints: true,
+ travelMode: 'BICYCLING'
+ }, function(response, status) {
+ if (status === 'OK') {
+ directionsDisplay.setDirections(response);
+
+ } else {
+ window.alert('Directions request failed due to ' + status);
+ }
+ });
+
+ }
+
+ </script>
+
+
+{% endblock %}
\ No newline at end of file
</li>
<li class="dropdown voce_menu" id="poi-menu">
- <a href="#" class="nav-link color-listini">
+ <a href="{% url 'sistema:percorsi_list' %}" class="nav-link color-listini">
<i class="fa-solid fa-route"></i><span>Percorsi</span></a>
</li>
</ul>
integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
+
+<script src="https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js"></script>
+<script src="https://rawgit.com/basarat/typescript-script/master/transpiler.js"></script>
</div>
{% block content %}
<div class="row">
<div class="col-12">
- <h1 class="line-bolle"><i class="fa-solid fa-tree-city clr-bolle mr-2" aria-hidden="true"></i> Gestione località </h1>
+ <h1 class="line-dipendenti"><i class="fa-solid fa-tree-city clr-dipendenti mr-2" aria-hidden="true"></i> Gestione località </h1>
<div class="card">
<div class="card-header justify-content-between">
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title>Title</title>
-</head>
-<body>
-
-</body>
-</html>
\ No newline at end of file
+{% extends 'base.html' %}
+{% load static %}
+{% block content %}
+ <div class="row">
+ <div class="col-12">
+ <h1 class="line-listini"><i class="fa-solid fa-route clr-listini mr-2" aria-hidden="true"></i> Gestione Percorsi </h1>
+
+ <div class="card">
+ <div class="card-header justify-content-between">
+ <h4 class="clr-bolle">Lista percorsi</h4>
+ <a href="{% url 'sistema:percorso' %}">
+ <button class="btn-sm btn-primary"><i class="fa-solid fa-plus"></i> Aggiungi un nuovo percorso</button>
+ </a>
+ </div>
+
+ <div class="card-body">
+ <div class="row">
+ <div class="table-responsive">
+ <table id="percorsi-table"
+ class="table table-sm table-bordered table-striped dataTables_wrapper dt-bootstrap4 no-footer" style="width: 100% !important;">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Nome</th>
+ <th>Descrizione</th>
+ <th>Testo</th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </div>
+
+ <script>
+ $(document).ready(function () {
+ $('#percorsi-table').dataTable({
+ processing: true,
+ serverSide: true,
+ ajax: {
+ "url": "{% url 'sistema:percorso_datatables' %}",
+ "type": 'GET',
+ },
+ language: {
+ url: "//cdn.datatables.net/plug-ins/1.10.20/i18n/Italian.json"
+ },
+ columnDefs: [
+ {"targets": 4, "orderable": false, "width": "5%"},
+ {"targets": 5, "orderable": false, "width": "5%"},
+ ],
+ "order": []
+ });
+ });
+
+ function DeletePercorso(pk){
+ Swal.fire({
+ title: "Sei sicuro?",
+ text: "Una volta eliminata non sarà più possibile accedere all'informazione!",
+ icon: "warning",
+ showCancelButton: true,
+ confirmButtonColor: '#3085d6',
+ cancelButtonColor: '#d33',
+ confirmButtonText: 'Conferma',
+ cancelButtonText: 'Annulla',
+ }).then((willDelete) => {
+ if (willDelete.value) {
+ $.ajax({
+ type: 'GET',
+ data: {
+ 'pk': pk,
+ 'method': 'del',
+ },
+ url: '{% url 'sistema:percorso' %}',
+ success: function (response) {
+ Swal.fire("Fatto!", response.response, "success")
+ .then((value) => {
+ location.reload();
+ });
+ },
+ error: () => {
+ Swal.fire("Attenzione!", response.response, "error")
+ }
+ })
+ } else if (
+ willDelete.dismiss === Swal.DismissReason.cancel
+ ) {
+ Swal.fire(
+ 'Annullato',
+ 'Rimozione annullata.',
+ 'error'
+ )
+ }
+ });
+ }
+
+ </script>
+{% endblock %}
\ No newline at end of file
{% block content %}
<div class="row">
<div class="col-12">
- <h1 class="line-bolle"><i class="fa-solid fa-location-dot clr-bolle mr-2" aria-hidden="true"></i> Gestione punti di interesse </h1>
+ <h1 class="line-config"><i class="fa-solid fa-location-dot clr-config mr-2" aria-hidden="true"></i> Gestione punti di interesse </h1>
<div class="card">
<div class="card-header justify-content-between">
{% block content %}
<div class="row">
<div class="col-12">
- <h1 class="line-bolle"><i class="fa-solid fa-cogs clr-bolle mr-2" aria-hidden="true"></i> Gestione tipologia multimedia </h1>
+ <h1 class="line-config"><i class="fa-solid fa-location-dot clr-config mr-2" aria-hidden="true"></i> Gestione tipologia multimedia </h1>
<div class="card">
<div class="card-header justify-content-between">
from sistema.datatables import LocalitaDatatables, MultimediaDatatables, TipoMultimediaDatatables, PercorsoDatatables, \
PoiDatatables, FeedbackDatatables, GestisceLocalitaDatatables
from sistema.views import Home, LocalitaListView, MultimediaListView, PuntiInteresseListView, \
- TipologiaMultimediaListView, PercorsiListView, LocalitaView, TipoMultimediaView, PoiView
+ TipologiaMultimediaListView, PercorsiListView, LocalitaView, TipoMultimediaView, PoiView, PercorsoView
urlpatterns = [
path('', Home.as_view(), name='home'),
## PUNTO DI INTERESSE ##
path('poi/', PoiView.as_view(), name='poi'),
path('mod_poi/<int:pk>/', PoiView.as_view(), name='mod_poi'),
+ path('get_coordinates/', PoiView.get_coordinates, name='get_coordinates'),
-
-
+ ## PERCORSO ##
+ path('percorso/', PercorsoView.as_view(), name='percorso'),
+ path('mod_percorso/<int:pk>/', PercorsoView.as_view(), name='mod_percorso'),
]
from rest_framework import status
from sistema.forms import LocalitaForm, TipoMultimediaForm, PoiForm
-from sistema.models import Localita, TipologiaMultimedia, PointOfInterest
+from sistema.models import Localita, TipologiaMultimedia, PointOfInterest, Percorso
from utenti.mixins import CustomLoginRequiredMixin
class PoiView(View):
+ def get_coordinates(self):
+ start = int(self.GET.get('start'))
+ end = int(self.GET.get('end'))
+ poi = self.GET.getlist('poi[]')
+
+ poi_coords = {}
+
+ start_coords = PointOfInterest.objects.get(pk=start)
+ end_coords = PointOfInterest.objects.get(pk=end)
+ poi_coords['start_coords'] = {'lat': start_coords.lat, 'long': start_coords.long}
+ poi_coords['end_coords'] = {'lat': end_coords.lat, 'long': end_coords.long}
+
+ tappe = []
+ for point in poi:
+ list = {}
+ cord = PointOfInterest.objects.get(pk=int(point))
+ list['lat'] = cord.lat
+ list['long'] = cord.long
+
+ tappe.append(list)
+
+ poi_coords['tappe'] = tappe
+
+ return JsonResponse({'response': poi_coords}, status=status.HTTP_200_OK)
+
def add_poi(self, request):
form = PoiForm(request.POST)
if form.is_valid():
else:
self.add_poi(request)
- return redirect(reverse('sistema:poi_list'))
\ No newline at end of file
+ return redirect(reverse('sistema:poi_list'))
+
+
+class PercorsoView(View):
+
+ def del_poi(self, request):
+ percorso = Percorso.objects.get(pk=int(request.GET.get('pk')))
+ percorso.is_active = False
+ percorso.save()
+
+ def get(self, request, *args, **kwargs):
+ if request.GET.get('method') == 'del':
+ self.del_poi(request)
+ return JsonResponse({'response': 'Percorso eliminato con successo'}, status=status.HTTP_200_OK)
+ elif 'pk' in kwargs:
+ return render(request, 'add_mod_percorso.html', {'poi_list': PointOfInterest.objects.filter(is_active=True).values('id', 'nome')})
+ else:
+ return render(request, 'add_mod_percorso.html', {'poi_list': PointOfInterest.objects.filter(is_active=True).values('id', 'nome')})
+
+ def post(self, request, *args, **kwargs):
+ if 'mod' in request.POST:
+ print('modifica')
+ else:
+ print('inserimento')
\ No newline at end of file
{% block content %}
<div class="row">
<div class="col-12">
- <h1 class="line-bolle"><i class="fa-solid fa-crown clr-bolle mr-2" aria-hidden="true"></i> Gestione amministratori</h1>
+ <h1 class="line-clients"><i class="fa-solid fa-crown clr-clients mr-2" aria-hidden="true"></i> Gestione amministratori</h1>
<div class="card">
<div class="card-header justify-content-between">
{% block content %}
<div class="row">
<div class="col-12">
- <h1 class="line-bolle"><i class="fa-solid fa-user clr-bolle mr-2" aria-hidden="true"></i> Gestione clienti</h1>
+ <h1 class="line-clients"><i class="fa-solid fa-user clr-clients mr-2" aria-hidden="true"></i> Gestione clienti</h1>
<div class="card">
<div class="card-header justify-content-between">
{% block content %}
<div class="row">
<div class="col-12">
- <h1 class="line-bolle"><i class="fa-solid fa-handshake-angle clr-bolle mr-2" aria-hidden="true"></i> Gestione tour operator</h1>
+ <h1 class="line-clients"><i class="fa-solid fa-handshake-angle clr-clients mr-2" aria-hidden="true"></i> Gestione tour operator</h1>
<div class="card">
<div class="card-header justify-content-between">