feat: add club map
This commit is contained in:
parent
0f96554ce2
commit
52973d189f
@ -10,6 +10,7 @@ import fr.titionfire.ffsaf.data.repository.CombRepository;
|
||||
import fr.titionfire.ffsaf.net2.ServerCustom;
|
||||
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
||||
import fr.titionfire.ffsaf.net2.request.SReqClub;
|
||||
import fr.titionfire.ffsaf.rest.data.ClubMapData;
|
||||
import fr.titionfire.ffsaf.rest.data.DeskMember;
|
||||
import fr.titionfire.ffsaf.rest.data.RenewAffData;
|
||||
import fr.titionfire.ffsaf.rest.data.SimpleClubList;
|
||||
@ -25,6 +26,7 @@ import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||
import io.quarkus.panache.common.Page;
|
||||
import io.quarkus.panache.common.Sort;
|
||||
import io.quarkus.vertx.VertxContextSupport;
|
||||
import io.smallrye.mutiny.Multi;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
@ -121,7 +123,8 @@ public class ClubService {
|
||||
}
|
||||
|
||||
public Uni<ClubModel> getOfUser(SecurityCtx securityCtx) {
|
||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult().invoke(Unchecked.consumer(m -> {
|
||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
||||
.invoke(Unchecked.consumer(m -> {
|
||||
if (m == null || m.getClub() == null)
|
||||
throw new DNotFoundException("Club non trouvé");
|
||||
}))
|
||||
@ -143,7 +146,8 @@ public class ClubService {
|
||||
TypeReference<HashMap<Contact, String>> typeRef = new TypeReference<>() {
|
||||
};
|
||||
|
||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult().invoke(Unchecked.consumer(m -> {
|
||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
||||
.invoke(Unchecked.consumer(m -> {
|
||||
if (m == null || m.getClub() == null)
|
||||
throw new DNotFoundException("Club non trouvé");
|
||||
if (!securityCtx.isInClubGroup(m.getClub().getId()))
|
||||
@ -279,4 +283,31 @@ public class ClubService {
|
||||
.toList()))
|
||||
.map(o -> data);
|
||||
}
|
||||
|
||||
public Uni<List<ClubMapData>> getMapData() {
|
||||
return repository.list("international", false).toMulti().flatMap(list -> Multi.createFrom().iterable(list))
|
||||
.call(clubModel -> Mutiny.fetch(clubModel.getContact()))
|
||||
.map(clubModel -> {
|
||||
ClubMapData data = new ClubMapData();
|
||||
|
||||
data.setName(clubModel.getName());
|
||||
data.setUuid(clubModel.getClubId());
|
||||
if (clubModel.getTraining_location() != null) {
|
||||
try {
|
||||
MAPPER.readTree(clubModel.getTraining_location()).forEach(l -> {
|
||||
ClubMapData.Location loc = new ClubMapData.Location();
|
||||
loc.setLat(l.get("lat").asDouble());
|
||||
loc.setLng(l.get("lng").asDouble());
|
||||
loc.setAddr(l.get("text").asText());
|
||||
data.training_location.add(loc);
|
||||
});
|
||||
} catch (JsonProcessingException ignored) {
|
||||
}
|
||||
}
|
||||
data.setTraining_day_time(clubModel.getTraining_day_time());
|
||||
data.setContact(clubModel.getContact());
|
||||
|
||||
return data;
|
||||
}).collect().asList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,7 @@ package fr.titionfire.ffsaf.rest;
|
||||
import fr.titionfire.ffsaf.data.model.ClubModel;
|
||||
import fr.titionfire.ffsaf.domain.service.ClubService;
|
||||
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
||||
import fr.titionfire.ffsaf.rest.data.DeskMember;
|
||||
import fr.titionfire.ffsaf.rest.data.RenewAffData;
|
||||
import fr.titionfire.ffsaf.rest.data.SimpleClub;
|
||||
import fr.titionfire.ffsaf.rest.data.SimpleClubList;
|
||||
import fr.titionfire.ffsaf.rest.data.*;
|
||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
||||
import fr.titionfire.ffsaf.rest.from.FullClubForm;
|
||||
@ -315,4 +312,10 @@ public class ClubEndpoints {
|
||||
}));
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("get_map_data")
|
||||
public Uni<List<ClubMapData>> getMapData() {
|
||||
return clubService.getMapData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
27
src/main/java/fr/titionfire/ffsaf/rest/data/ClubMapData.java
Normal file
27
src/main/java/fr/titionfire/ffsaf/rest/data/ClubMapData.java
Normal file
@ -0,0 +1,27 @@
|
||||
package fr.titionfire.ffsaf.rest.data;
|
||||
|
||||
import fr.titionfire.ffsaf.utils.Contact;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@RegisterForReflection
|
||||
public class ClubMapData {
|
||||
public String name;
|
||||
public String uuid;
|
||||
public List<Location> training_location = new ArrayList<>();
|
||||
public String training_day_time;
|
||||
public Map<Contact, String> contact;
|
||||
|
||||
@Data
|
||||
@RegisterForReflection
|
||||
public static class Location {
|
||||
public double lat;
|
||||
public double lng;
|
||||
public String addr;
|
||||
}
|
||||
}
|
||||
22
src/main/webapp/public/club-maps.html
Normal file
22
src/main/webapp/public/club-maps.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Où pratiquer le MSF ?</title>
|
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""/>
|
||||
<!-- Make sure you put this AFTER Leaflet's CSS -->
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||
crossorigin=""></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" style="width: 100%; height: 95vh"></div>
|
||||
|
||||
<div id="club_map_data" style="width: 100%; min-height: 0; background-color: #00000011; padding: 0.5em"></div>
|
||||
|
||||
<script src="club-maps.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
134
src/main/webapp/public/club-maps.js
Normal file
134
src/main/webapp/public/club-maps.js
Normal file
@ -0,0 +1,134 @@
|
||||
const div_map = document.getElementById('map');
|
||||
//const div_info = document.getElementById('club_map_data');
|
||||
|
||||
const api_url = "http://localhost:5173";
|
||||
|
||||
let map = L.map('map').setView([46.631196, 2.456000], 6);
|
||||
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
|
||||
const getMeta = async (url) => {
|
||||
const img = new Image();
|
||||
img.src = url;
|
||||
await img.decode();
|
||||
return img
|
||||
};
|
||||
|
||||
function timeNumberToSting(nbMin) {
|
||||
return String(Math.floor(nbMin / 60)).padStart(2, '0') + ":" + String(nbMin % 60).padStart(2, '0')
|
||||
}
|
||||
|
||||
const sortHoraire = (a, b) => {
|
||||
if (a.day === b.day)
|
||||
return a.time_start - b.time_start;
|
||||
return a.day - b.day;
|
||||
}
|
||||
|
||||
//let last_info_show = null;
|
||||
|
||||
async function getData() {
|
||||
const response = await fetch(`${api_url}/api/club/get_map_data`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Response status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
for (const d of data) {
|
||||
console.log(d);
|
||||
|
||||
if (d.training_location.length === 0)
|
||||
continue;
|
||||
|
||||
let icon = null;
|
||||
if (d.uuid !== null) {
|
||||
console.log("logo");
|
||||
|
||||
const img = await getMeta(`http://localhost:5173/api/club/${d.uuid}/logo`);
|
||||
let ratio = img.naturalHeight / img.naturalWidth;
|
||||
|
||||
icon = L.icon({
|
||||
iconUrl: `http://localhost:5173/api/club/${d.uuid}/logo`,
|
||||
|
||||
iconSize: [50, 50 * ratio], // size of the icon
|
||||
//shadowSize: [50, 64], // size of the shadow
|
||||
iconAnchor: [25, 50 * ratio], // point of the icon which will correspond to marker's location
|
||||
//shadowAnchor: [4, 62], // the same for the shadow
|
||||
popupAnchor: [0, -50 * ratio] // point from which the popup should open relative to the iconAnchor
|
||||
});
|
||||
}
|
||||
|
||||
for (const m of d.training_location) {
|
||||
console.log(m);
|
||||
let marker;
|
||||
if (icon === null)
|
||||
marker = L.marker([m.lat, m.lng]);
|
||||
else
|
||||
marker = L.marker([m.lat, m.lng], {icon: icon});
|
||||
marker.addTo(map);
|
||||
|
||||
const div_info = document.createElement("div");
|
||||
let tmp = document.createElement("h3");
|
||||
tmp.textContent = d.name;
|
||||
div_info.appendChild(tmp);
|
||||
|
||||
div_info.appendChild(document.createTextNode(`Adresse: `));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
for (const m of d.training_location) {
|
||||
div_info.appendChild(document.createTextNode(m.addr));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
}
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
|
||||
div_info.appendChild(document.createTextNode(`Horaire: `));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
if (!d.training_day_time || JSON.parse(d.training_day_time).length === 0) {
|
||||
div_info.appendChild(document.createTextNode("Pas d'horaire disponible"));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
} else {
|
||||
for (const m of JSON.parse(d.training_day_time).sort(sortHoraire)) {
|
||||
console.log(m);
|
||||
let days = ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"];
|
||||
|
||||
div_info.appendChild(document.createTextNode(`${days[m.day]}: ${timeNumberToSting(m.time_start)} - ${timeNumberToSting(m.time_end)}`));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
}
|
||||
}
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
|
||||
div_info.appendChild(document.createTextNode(`Contact: `));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
if (d.contact === null || Object.keys(d.contact).length === 0) {
|
||||
div_info.appendChild(document.createTextNode("Pas de contact disponible"));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
} else {
|
||||
for (const [key, value] of Object.entries(d.contact)) {
|
||||
div_info.appendChild(document.createTextNode(`${key.charAt(0).toUpperCase() + key.slice(1).toLowerCase()}: ${value}`));
|
||||
div_info.appendChild(document.createElement("br"));
|
||||
}
|
||||
}
|
||||
marker.bindPopup(div_info.innerHTML);
|
||||
|
||||
//marker.on('click', e => {
|
||||
//console.log("click");
|
||||
//if (div_map.style.height !== "95vh" && last_info_show === d.name) {
|
||||
//div_map.style.height = "95vh";
|
||||
//div_info.style.minHeight = "0";
|
||||
//div_info.replaceChildren();
|
||||
//} else {
|
||||
//div_map.style.height = "80vh";
|
||||
//div_info.style.minHeight = "15vh";
|
||||
//div_info.replaceChildren();
|
||||
|
||||
//last_info_show = d.name;
|
||||
//}
|
||||
//})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getData().then(() => console.log("end loading"));
|
||||
|
||||
console.log("test");
|
||||
Loading…
x
Reference in New Issue
Block a user