Enhance PollutionMap component with Voronoi layer toggle; add GeoJSON data for visualization
This commit is contained in:
BIN
frontend/public/images/voro.png
Normal file
BIN
frontend/public/images/voro.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
727
frontend/public/voronoi_sevilla_geovoronoi.geojson
Normal file
727
frontend/public/voronoi_sevilla_geovoronoi.geojson
Normal file
@@ -0,0 +1,727 @@
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 3
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.975220574710803,
|
||||
37.358725234526325
|
||||
],
|
||||
[
|
||||
-5.956629501395188,
|
||||
37.34271453941203
|
||||
],
|
||||
[
|
||||
-5.90939488095618,
|
||||
37.339843612523126
|
||||
],
|
||||
[
|
||||
-5.927653856389463,
|
||||
37.35123031855536
|
||||
],
|
||||
[
|
||||
-5.9677328204994975,
|
||||
37.36945244319422
|
||||
],
|
||||
[
|
||||
-5.975220574710803,
|
||||
37.358725234526325
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 5
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.969424709766254,
|
||||
37.37478267183256
|
||||
],
|
||||
[
|
||||
-5.963298496465492,
|
||||
37.38284229005861
|
||||
],
|
||||
[
|
||||
-5.927653856389463,
|
||||
37.35123031855536
|
||||
],
|
||||
[
|
||||
-5.9677328204994975,
|
||||
37.36945244319422
|
||||
],
|
||||
[
|
||||
-5.969424709766254,
|
||||
37.37478267183256
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 16
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.9062693851557535,
|
||||
37.33903066950347
|
||||
],
|
||||
[
|
||||
-5.9402008847769965,
|
||||
37.39163172552388
|
||||
],
|
||||
[
|
||||
-5.939432400548112,
|
||||
37.41302637751862
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.42131204097132
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.30641403730114
|
||||
],
|
||||
[
|
||||
-5.9062693851557535,
|
||||
37.33903066950347
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 18
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.953484151391864,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-5.892547063477412,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.43338874148842
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.42131204097132
|
||||
],
|
||||
[
|
||||
-5.939432400548112,
|
||||
37.41302637751862
|
||||
],
|
||||
[
|
||||
-5.950157126973102,
|
||||
37.42313784097292
|
||||
],
|
||||
[
|
||||
-5.953484151391864,
|
||||
37.45
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 2
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-6.042673351034033,
|
||||
37.31235131332692
|
||||
],
|
||||
[
|
||||
-5.956629501395188,
|
||||
37.34271453941203
|
||||
],
|
||||
[
|
||||
-5.975220574710803,
|
||||
37.358725234526325
|
||||
],
|
||||
[
|
||||
-5.991667436508618,
|
||||
37.359093048817556
|
||||
],
|
||||
[
|
||||
-6.042673351034033,
|
||||
37.31235131332692
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 1
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-6.056335292289438,
|
||||
37.30350028295088
|
||||
],
|
||||
[
|
||||
-6.042673351034033,
|
||||
37.31235131332692
|
||||
],
|
||||
[
|
||||
-5.956629501395188,
|
||||
37.34271453941203
|
||||
],
|
||||
[
|
||||
-5.90939488095618,
|
||||
37.339843612523126
|
||||
],
|
||||
[
|
||||
-5.9062693851557535,
|
||||
37.33903066950347
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.30641403730114
|
||||
],
|
||||
[
|
||||
-5.85,
|
||||
37.3
|
||||
],
|
||||
[
|
||||
-6.061145744247712,
|
||||
37.3
|
||||
],
|
||||
[
|
||||
-6.056335292289438,
|
||||
37.30350028295088
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 6
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-6.006210657955016,
|
||||
37.39204750434759
|
||||
],
|
||||
[
|
||||
-5.999699040810209,
|
||||
37.38464226854157
|
||||
],
|
||||
[
|
||||
-6.056335292289438,
|
||||
37.30350028295088
|
||||
],
|
||||
[
|
||||
-6.061145744247712,
|
||||
37.3
|
||||
],
|
||||
[
|
||||
-6.1,
|
||||
37.3
|
||||
],
|
||||
[
|
||||
-6.1,
|
||||
37.39522072259649
|
||||
],
|
||||
[
|
||||
-6.006210657955016,
|
||||
37.39204750434759
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 17
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.996638048161243,
|
||||
37.42409467426387
|
||||
],
|
||||
[
|
||||
-6.011677116677642,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-5.953484151391864,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-5.950157126973102,
|
||||
37.42313784097292
|
||||
],
|
||||
[
|
||||
-5.965724477190091,
|
||||
37.41053204103079
|
||||
],
|
||||
[
|
||||
-5.996638048161243,
|
||||
37.42409467426387
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 13
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-6.1,
|
||||
37.416037697292964
|
||||
],
|
||||
[
|
||||
-6.1,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-6.057485769579995,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-6.011677116677642,
|
||||
37.45
|
||||
],
|
||||
[
|
||||
-5.996638048161243,
|
||||
37.42409467426387
|
||||
],
|
||||
[
|
||||
-5.9941297848131985,
|
||||
37.406630612305094
|
||||
],
|
||||
[
|
||||
-6.006210657955016,
|
||||
37.39204750434759
|
||||
],
|
||||
[
|
||||
-6.1,
|
||||
37.39522072259649
|
||||
],
|
||||
[
|
||||
-6.1,
|
||||
37.416037697292964
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 12
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.966630745640582,
|
||||
37.40714989057746
|
||||
],
|
||||
[
|
||||
-5.953473975522407,
|
||||
37.39083552675785
|
||||
],
|
||||
[
|
||||
-5.963175863543545,
|
||||
37.38403450765386
|
||||
],
|
||||
[
|
||||
-5.975285181668732,
|
||||
37.39565697942774
|
||||
],
|
||||
[
|
||||
-5.966630745640582,
|
||||
37.40714989057746
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 10
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.953473975522407,
|
||||
37.39083552675785
|
||||
],
|
||||
[
|
||||
-5.9402008847769965,
|
||||
37.39163172552388
|
||||
],
|
||||
[
|
||||
-5.9062693851557535,
|
||||
37.33903066950347
|
||||
],
|
||||
[
|
||||
-5.90939488095618,
|
||||
37.339843612523126
|
||||
],
|
||||
[
|
||||
-5.927653856389463,
|
||||
37.35123031855536
|
||||
],
|
||||
[
|
||||
-5.963298496465492,
|
||||
37.38284229005861
|
||||
],
|
||||
[
|
||||
-5.963175863543545,
|
||||
37.38403450765386
|
||||
],
|
||||
[
|
||||
-5.953473975522407,
|
||||
37.39083552675785
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 15
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.966630745640582,
|
||||
37.40714989057746
|
||||
],
|
||||
[
|
||||
-5.965724477190091,
|
||||
37.41053204103079
|
||||
],
|
||||
[
|
||||
-5.950157126973102,
|
||||
37.42313784097292
|
||||
],
|
||||
[
|
||||
-5.939432400548112,
|
||||
37.41302637751862
|
||||
],
|
||||
[
|
||||
-5.9402008847769965,
|
||||
37.39163172552388
|
||||
],
|
||||
[
|
||||
-5.953473975522407,
|
||||
37.39083552675785
|
||||
],
|
||||
[
|
||||
-5.966630745640582,
|
||||
37.40714989057746
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 14
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.966630745640582,
|
||||
37.40714989057746
|
||||
],
|
||||
[
|
||||
-5.965724477190091,
|
||||
37.41053204103079
|
||||
],
|
||||
[
|
||||
-5.996638048161243,
|
||||
37.42409467426387
|
||||
],
|
||||
[
|
||||
-5.9941297848131985,
|
||||
37.406630612305094
|
||||
],
|
||||
[
|
||||
-5.981314881430654,
|
||||
37.393898393584536
|
||||
],
|
||||
[
|
||||
-5.975285181668732,
|
||||
37.39565697942774
|
||||
],
|
||||
[
|
||||
-5.966630745640582,
|
||||
37.40714989057746
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 8
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.995965602200496,
|
||||
37.3834658156984
|
||||
],
|
||||
[
|
||||
-5.990194183397561,
|
||||
37.36441485314666
|
||||
],
|
||||
[
|
||||
-5.9792132087914,
|
||||
37.37663853816038
|
||||
],
|
||||
[
|
||||
-5.98303912784847,
|
||||
37.390051246464104
|
||||
],
|
||||
[
|
||||
-5.995965602200496,
|
||||
37.3834658156984
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 4
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.990194183397561,
|
||||
37.36441485314666
|
||||
],
|
||||
[
|
||||
-5.991667436508618,
|
||||
37.359093048817556
|
||||
],
|
||||
[
|
||||
-5.975220574710803,
|
||||
37.358725234526325
|
||||
],
|
||||
[
|
||||
-5.9677328204994975,
|
||||
37.36945244319422
|
||||
],
|
||||
[
|
||||
-5.969424709766254,
|
||||
37.37478267183256
|
||||
],
|
||||
[
|
||||
-5.9792132087914,
|
||||
37.37663853816038
|
||||
],
|
||||
[
|
||||
-5.990194183397561,
|
||||
37.36441485314666
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 9
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.98303912784847,
|
||||
37.390051246464104
|
||||
],
|
||||
[
|
||||
-5.981314881430654,
|
||||
37.393898393584536
|
||||
],
|
||||
[
|
||||
-5.975285181668732,
|
||||
37.39565697942774
|
||||
],
|
||||
[
|
||||
-5.963175863543545,
|
||||
37.38403450765386
|
||||
],
|
||||
[
|
||||
-5.963298496465492,
|
||||
37.38284229005861
|
||||
],
|
||||
[
|
||||
-5.969424709766254,
|
||||
37.37478267183256
|
||||
],
|
||||
[
|
||||
-5.9792132087914,
|
||||
37.37663853816038
|
||||
],
|
||||
[
|
||||
-5.98303912784847,
|
||||
37.390051246464104
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 7
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.995965602200496,
|
||||
37.3834658156984
|
||||
],
|
||||
[
|
||||
-5.999699040810209,
|
||||
37.38464226854157
|
||||
],
|
||||
[
|
||||
-6.056335292289438,
|
||||
37.30350028295088
|
||||
],
|
||||
[
|
||||
-6.042673351034033,
|
||||
37.31235131332692
|
||||
],
|
||||
[
|
||||
-5.991667436508618,
|
||||
37.359093048817556
|
||||
],
|
||||
[
|
||||
-5.990194183397561,
|
||||
37.36441485314666
|
||||
],
|
||||
[
|
||||
-5.995965602200496,
|
||||
37.3834658156984
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"groupId": 11
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-5.995965602200496,
|
||||
37.3834658156984
|
||||
],
|
||||
[
|
||||
-5.999699040810209,
|
||||
37.38464226854157
|
||||
],
|
||||
[
|
||||
-6.006210657955016,
|
||||
37.39204750434759
|
||||
],
|
||||
[
|
||||
-5.9941297848131985,
|
||||
37.406630612305094
|
||||
],
|
||||
[
|
||||
-5.981314881430654,
|
||||
37.393898393584536
|
||||
],
|
||||
[
|
||||
-5.98303912784847,
|
||||
37.390051246464104
|
||||
],
|
||||
[
|
||||
-5.995965602200496,
|
||||
37.3834658156984
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import { useDataContext } from '@/hooks/useDataContext';
|
||||
import L from "leaflet";
|
||||
import "leaflet.heat";
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
|
||||
const PollutionMap = ({ groupId, deviceId }) => {
|
||||
const { config, configLoading, configError } = useConfig();
|
||||
@@ -39,13 +39,16 @@ const PollutionMapContent = () => {
|
||||
const { config, configLoading, configError } = useConfig();
|
||||
const { data, dataLoading, dataError } = useDataContext();
|
||||
|
||||
const mapRef = useRef(null); // Referencia al mapa
|
||||
const voronoiLayerRef = useRef(null); // Referencia al layer de Voronoi
|
||||
const [showVoronoi, setShowVoronoi] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data || !config) return;
|
||||
|
||||
const isToday = (timestamp) => {
|
||||
const today = new Date();
|
||||
const date = new Date(timestamp * 1000); // si viene en segundos
|
||||
|
||||
const date = new Date(timestamp * 1000);
|
||||
return (
|
||||
today.getFullYear() === date.getFullYear() &&
|
||||
today.getMonth() === date.getMonth() &&
|
||||
@@ -53,19 +56,55 @@ const PollutionMapContent = () => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const mapContainer = document.getElementById("map");
|
||||
if (!mapContainer) return;
|
||||
|
||||
const getFillColor = (feature) => {
|
||||
const index = feature.properties.index || Math.floor(Math.random() * 10);
|
||||
const colors = [
|
||||
"#FFCDD2", "#F8BBD0", "#E1BEE7", "#D1C4E9",
|
||||
"#C5CAE9", "#B3E5FC", "#B2DFDB", "#DCEDC8",
|
||||
"#FFF9C4", "#FFE0B2"
|
||||
];
|
||||
return colors[index % colors.length];
|
||||
};
|
||||
|
||||
|
||||
const SEVILLA = config.userConfig.city;
|
||||
|
||||
const map = L.map(mapContainer).setView(SEVILLA, 12);
|
||||
mapRef.current = map;
|
||||
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution:
|
||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
fetch("/voronoi_sevilla_geovoronoi.geojson")
|
||||
.then(res => res.json())
|
||||
.then(geojson => {
|
||||
const voronoiLayer = L.geoJSON(geojson, {
|
||||
style: (feature) => ({
|
||||
color: "#007946",
|
||||
weight: 1.0,
|
||||
opacity: 0.8,
|
||||
fillOpacity: 0.3,
|
||||
fillColor: getFillColor(feature),
|
||||
dashArray: '5, 5'
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
voronoiLayerRef.current = voronoiLayer;
|
||||
|
||||
if (showVoronoi) {
|
||||
voronoiLayer.addTo(map);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error cargando el GeoJSON:", err);
|
||||
});
|
||||
|
||||
const points = data
|
||||
.filter(p => isToday(p.timestamp))
|
||||
.map(p => [p.lat, p.lon, p.carbonMonoxide]);
|
||||
@@ -77,18 +116,69 @@ const PollutionMapContent = () => {
|
||||
};
|
||||
}, [data, config]);
|
||||
|
||||
// Esta parte gestiona el toggle del voronoi
|
||||
const toggleVoronoi = () => {
|
||||
const map = mapRef.current;
|
||||
const voronoiLayer = voronoiLayerRef.current;
|
||||
|
||||
if (!map || !voronoiLayer) return;
|
||||
|
||||
if (map.hasLayer(voronoiLayer)) {
|
||||
map.removeLayer(voronoiLayer);
|
||||
setShowVoronoi(false);
|
||||
} else {
|
||||
voronoiLayer.addTo(map);
|
||||
setShowVoronoi(true);
|
||||
}
|
||||
};
|
||||
|
||||
if (configLoading) return <p>Cargando configuración...</p>;
|
||||
if (configError) return <p>Error al cargar configuración: {configError}</p>;
|
||||
if (!config) return <p>Configuración no disponible.</p>;
|
||||
|
||||
if (dataLoading) return <p>Cargando datos...</p>;
|
||||
if (dataError) return <p>Error al cargar datos: {configError}</p>;
|
||||
if (dataError) return <p>Error al cargar datos: {dataError}</p>;
|
||||
if (!data) return <p>Datos no disponibles.</p>;
|
||||
|
||||
return (
|
||||
<div id="map" className='rounded-4' style={{ height: "60vh" }}></div>
|
||||
<div style={{ position: "relative" }}>
|
||||
<div id="map" className='rounded-4' style={{ height: "60vh" }}></div>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "80px",
|
||||
left: "10px",
|
||||
zIndex: 1000,
|
||||
border: "2px solid rgba(0,0,0,0.2)",
|
||||
padding: "0",
|
||||
cursor: "pointer",
|
||||
backgroundColor: "transparent",
|
||||
borderRadius: "4px",
|
||||
backgroundClip: "padding-box",
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={toggleVoronoi}
|
||||
style={{
|
||||
|
||||
zIndex: 1000,
|
||||
width: "30px",
|
||||
height: "30px",
|
||||
padding: "0",
|
||||
cursor: "pointer",
|
||||
backgroundColor: "#ffffff",
|
||||
borderRadius: "2px",
|
||||
border: "none",
|
||||
}}
|
||||
onMouseOver={(e) => e.currentTarget.style.backgroundColor = "#f4f4f4"}
|
||||
onMouseOut={(e) => e.currentTarget.style.backgroundColor = "#ffffff"}
|
||||
>
|
||||
<img src='/images/voro.png' width={30} height={30} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
PollutionMap.propTypes = {
|
||||
groupId: PropTypes.number.isRequired,
|
||||
|
||||
Reference in New Issue
Block a user