treaty info box

This commit is contained in:
louai98 2024-06-10 14:58:08 +02:00
parent 9d861a9768
commit a1037291e5
12 changed files with 239 additions and 156 deletions

6
package-lock.json generated
View File

@ -18,6 +18,7 @@
"dompurify": "^3.1.4",
"html-react-parser": "^5.1.10",
"leaflet": "^1.9.4",
"leaflet.bigimage": "^1.0.1",
"node-sass": "^7.0.3",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
@ -13177,6 +13178,11 @@
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
},
"node_modules/leaflet.bigimage": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/leaflet.bigimage/-/leaflet.bigimage-1.0.1.tgz",
"integrity": "sha512-ZCqvjgudLau5WevjFjMN4pXjAZV0BUtf3sYnXD1p+uviza9GLx218ckj5lHE+bcakkIufFR7ZSSt1iiUY+9AZA=="
},
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",

View File

@ -13,6 +13,7 @@
"dompurify": "^3.1.4",
"html-react-parser": "^5.1.10",
"leaflet": "^1.9.4",
"leaflet.bigimage": "^1.0.1",
"node-sass": "^7.0.3",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",

View File

@ -13,6 +13,7 @@ import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import SelectedFilters from "./SelectedFilters";
import TreatyInfoBox from "./TreatyInfoBox";
import Icon1 from "../../../Icons/icon1.svg";
import Icon2 from "../../../Icons/icon2.svg";
@ -40,6 +41,7 @@ import Icon23 from "../../../Icons/icon23.svg";
import Icon24 from "../../../Icons/icon24.svg";
import Icon25 from "../../../Icons/icon25.svg";
import Icon26 from "../../../Icons/icon26.svg";
import Card_ from "../../UI/Card_/Card_";
const iconMap = {
Icon1: Icon1,
@ -76,41 +78,40 @@ class ControlInAfricaMap extends React.Component {
this.mapRef = createRef(); // Create a ref to store the MapContainer instance
this.state = {
africaCountries: null,
countriesNames: [],
regional_organisations: [],
geographical_organisations: [],
regional_treaties: [],
international_treaties: [],
intsruments: [],
internationalIntsruments: [],
africanIntsruments: [],
africaCountries: null, // The GeoJSON data for the African countries
countriesNames: [], // The names of the countries for select list
regional_organisations: [], // The regional organisations data
geographical_organisations: [], // The geographical organisations data
regional_treaties: [], // The regional treaties data
international_treaties: [], // The international treaties data
internationalIntsruments: [], // The international instruments data
africanIntsruments: [], // The african instruments data
loading: true,
error: null,
center: [3, 15],
zoom: this.getZoomLevel(window.innerWidth),
scrollWheelZoom: true,
scrollWheelZoom: false,
zoomControl: false,
openedTooltipLayer: null,
selectedCountry: "",
selectedRegion: "",
selectedTreaty: "",
selectedCountry: "", // The name of the selected country
selectedRegion: "", // The name of the selected region
selectedTreaty: "", // The name of the selected treaty
selectedTreatyOfficialName: "", // For the Slescted filters box
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountriesFeaturesRegions: [],
selectedCountriesFeaturesTreaties: [],
selectedCountriesIntersections: [],
selectedCommonCountries: [],
selectedCountryColor: "yellow",
selectedIcon: "none",
prevStatuesRegion: "",
currentStatuesTreaty: "",
prevStatuesTreaty: "",
infoBox: [],
@ -121,6 +122,9 @@ class ControlInAfricaMap extends React.Component {
componentDidMount() {
this.fetchData();
window.addEventListener("resize", this.handleResize);
if (L.control.bigImage) {
L.control.bigImage({ position: 'topright' }).addTo(this.mapRef);
}
}
componentWillUnmount() {
@ -149,7 +153,7 @@ class ControlInAfricaMap extends React.Component {
}
try {
console.log("fetching data");
//console.log("fetching data");
const response = await fetch(Orgs); // Ensure this is a valid URL
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
@ -184,10 +188,6 @@ class ControlInAfricaMap extends React.Component {
icon: iconMap[instrument.icon] || null,
}));
const intsruments = data.intsruments.map((instrument) => ({
...instrument,
icon: iconMap[instrument.icon] || null,
}));
this.setState(
{
regional_organisations: data.regional_organisations,
@ -196,22 +196,21 @@ class ControlInAfricaMap extends React.Component {
international_treaties,
internationalIntsruments,
africanIntsruments,
intsruments,
},
() => {
// Callback after state has been updated (optional)
}
);
} catch (error) {
console.error("Error fetching the JSON file:", error);
//console.error("Error fetching the JSON file:", error);
}
};
getZoomLevel = () => {
const screenWidth = window.innerWidth;
console.log(screenWidth);
//console.log(screenWidth);
if (screenWidth <= 800) {
console.log("small screen");
//console.log("small screen");
return 3;
} else if (screenWidth <= 1024) {
return 4;
@ -243,9 +242,14 @@ class ControlInAfricaMap extends React.Component {
};
handleCountryChange = (e) => {
const countryName = e.target.value;
const countryName = e.target.value || e.target.getAttribute("data-country");
const { selectedCountry } = this.state;
if (countryName === selectedCountry) {
this.setState({ selectedCountry: "" });
return;
}
this.setState({ selectedCountry: countryName }, () => {
this.openTooltipForCountry(countryName);
//this.openTooltipForCountry(countryName);
});
};
@ -257,7 +261,7 @@ class ControlInAfricaMap extends React.Component {
click: this.onMouseClick,
});
};
// To Do: Delete this function
openTooltipForCountry = (countryName) => {
const { africaCountries } = this.state;
if (!africaCountries) return;
@ -272,15 +276,7 @@ class ControlInAfricaMap extends React.Component {
openedTooltipLayer.closeTooltip(); // Close the previously opened tooltip
}
const popupContent = `<h5>Selected: ${countryName}</h5>`;
const layer = L.geoJSON(feature);
const tooltip = L.tooltip({
permanent: true,
direction: "top",
className: "tooltip-custom",
}).setContent(popupContent);
layer.bindTooltip(tooltip).openTooltip();
// Update the state to store the currently opened tooltip
this.setState({ openedTooltipLayer: layer });
@ -299,11 +295,9 @@ class ControlInAfricaMap extends React.Component {
selectedCountriesNamesTreaties: [],
selectedCountriesFeaturesRegions: [],
selectedCountriesFeaturesTreaties: [],
selectedCountriesIntersections: [],
selectedCountryColor: "yellow",
prevStatuesRegion: "",
prevStatuesTreaty: "",
infoBox: [],
@ -323,11 +317,9 @@ class ControlInAfricaMap extends React.Component {
selectedCountriesNamesTreaties: [],
selectedCountriesFeaturesRegions: [],
selectedCountriesFeaturesTreaties: [],
selectedCountriesIntersections: [],
selectedCountryColor: "yellow",
prevStatuesRegion: "",
prevStatuesTreaty: "",
infoBox: [],
@ -337,33 +329,29 @@ class ControlInAfricaMap extends React.Component {
this.props.updateCountryID(e.target.feature.properties.id);
};
handleOrganizationClick = (name, status, color) => {
const {
selectedRegion,
prevStatuesRegion,
prevStatuesTreaty,
africaCountries,
} = this.state;
handleOrganizationClick = (name, color) => {
const { selectedRegion, prevStatuesTreaty, africaCountries } = this.state;
if (selectedRegion === name && prevStatuesRegion === status) {
console.log("same");
if (selectedRegion === name) {
//console.log("same");
this.setState({
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
selectedCountryColor: "yellow",
selectedCountry: "",
selectedRegion: "",
prevStatuesRegion: "",
showInfoBox: false,
currentStatuesTreaty: "",
});
return;
}
if (prevStatuesTreaty) {
console.log("change");
//console.log("change");
this.setState({
selectedCountriesNamesTreaties: [],
selectedCountry: "",
currentStatuesTreaty: "",
});
}
@ -382,7 +370,6 @@ class ControlInAfricaMap extends React.Component {
selectedCountryColor: color,
selectedCountry: "",
selectedRegion: name,
prevStatuesRegion: status,
selectedCountriesFeaturesRegions,
selectedTreaty: "",
selectedTreatyOfficialName: "",
@ -394,19 +381,18 @@ class ControlInAfricaMap extends React.Component {
const {
selectedRegion,
selectedTreaty,
selectedTreatyOfficialName,
selectedCountriesNamesRegions,
prevStatuesTreaty,
africaCountries,
regional_treaties,
international_treaties,
intsruments,
internationalIntsruments,
africanIntsruments,
currentStatuesTreaty,
} = this.state;
// get the icon of the selected treaty based on the name and status of the treaty
console.log(name, status);
//console.log(name, status);
let org =
regional_treaties.find((org) => org.name2 === name) ||
@ -417,10 +403,6 @@ class ControlInAfricaMap extends React.Component {
(instrument) => instrument.name2 === name
) || africanIntsruments.find((instrument) => instrument.name2 === name);
let instrument_ = intsruments.find(
(instrument) => instrument.name2 === name
);
const selectedIcon = org
? org[`icon_${status.toLowerCase()}`] || "none"
: instrument
@ -429,8 +411,11 @@ class ControlInAfricaMap extends React.Component {
this.setState({
selectedIcon,
currentStatuesTreaty: status,
});
// console.log(status, ":", currentStatuesTreaty, prevStatuesTreaty);
// if the same treaty is selected previously and the region is not selected
// then the treaty will be deselected
if (
@ -438,7 +423,7 @@ class ControlInAfricaMap extends React.Component {
prevStatuesTreaty === status &&
selectedRegion === ""
) {
console.log("1");
//console.log("1");
this.setState({
selectedCountriesNamesRegions: [],
selectedCountriesNamesTreaties: [],
@ -446,6 +431,7 @@ class ControlInAfricaMap extends React.Component {
selectedCountry: "",
selectedTreaty: "",
selectedTreatyOfficialName: "",
currentStatuesTreaty: "",
prevStatuesTreaty: "",
prevStatuesRegion: "",
selectedIcon: "none",
@ -457,13 +443,14 @@ class ControlInAfricaMap extends React.Component {
// if the same treaty is selected previously and the region is selected
// then the treaty will be deselected
if (selectedTreaty === name && prevStatuesTreaty === status) {
console.log("2");
//console.log("2");
this.setState({
selectedCountriesNamesTreaties: [],
selectedCountry: "",
selectedTreaty: "",
selectedTreatyOfficialName: "",
prevStatuesTreaty: "",
currentStatuesTreaty: "",
selectedIcon: "none",
showInfoBox: true,
});
@ -485,17 +472,25 @@ class ControlInAfricaMap extends React.Component {
// if the region is selected then the treaty will be selected based on the
// intersection of the region and the treaty
if (selectedRegion) {
console.log("intersect");
//console.log("intersect");
const intersection = selectedCountriesNamesTreaties.filter((country) =>
selectedCountriesNamesRegions.includes(country)
);
const selectedCommonCountries = selectedCountriesNamesTreaties
.filter((country) => selectedCountriesNamesRegions.includes(country))
.map((country) => ({
country,
status,
}));
this.setState({
selectedCountriesNamesTreaties: intersection,
selectedCountry: "",
selectedTreaty: name,
selectedTreatyOfficialName: official_name,
currentStatuesTreaty: status,
prevStatuesTreaty: status,
showInfoBox: true,
selectedCommonCountries,
});
return;
}
@ -505,6 +500,7 @@ class ControlInAfricaMap extends React.Component {
selectedCountry: "",
selectedTreaty: name,
selectedTreatyOfficialName: official_name,
currentStatuesTreaty: status,
prevStatuesTreaty: status,
selectedCountriesFeaturesTreaties,
});
@ -517,6 +513,7 @@ class ControlInAfricaMap extends React.Component {
this.setState({
selectedTreaty: name,
selectedTreatyOfficialName: official_name,
currentStatuesTreaty: status,
});
}
};
@ -528,7 +525,6 @@ class ControlInAfricaMap extends React.Component {
international_treaties,
internationalIntsruments,
africanIntsruments,
intsruments,
} = this.state;
// Helper function to process treaties
@ -581,20 +577,9 @@ class ControlInAfricaMap extends React.Component {
);
const africanIntsruments_ = processInstruments(africanIntsruments);
const organisationsInstruments = intsruments.map((instrument) => {
const countris = selectedCountriesFeaturesRegions.filter(
(feature) => feature.properties[instrument.name2] === 1
);
return {
name: instrument.name,
countries: countris.length,
};
});
return {
organisationsRegionalTreaties,
organisationsInternationalTreaties,
organisationsInstruments,
internationalIntsruments_,
africanIntsruments_,
};
@ -611,7 +596,7 @@ class ControlInAfricaMap extends React.Component {
const { name } = feature.properties;
// select one country
if (name === selectedCountry) {
console.log("one country selected");
//console.log("one country selected");
return CountrySelectedStyle(selectedCountryColor);
}
@ -619,21 +604,21 @@ class ControlInAfricaMap extends React.Component {
const inSelectedTreaties = selectedCountriesNamesTreaties.includes(name);
// select one region
if (inSelectedRegions && !selectedCountriesNamesTreaties.length) {
console.log("region selected");
//console.log("region selected");
return CountrySelectedStyle(selectedCountryColor);
}
// select one treaty
if (inSelectedRegions && !inSelectedTreaties) {
console.log("region and treaty selected 1");
//console.log("region and treaty selected 1");
return CountrySelectedStyle(selectedCountryColor);
}
// select region and treaty
if (inSelectedRegions && inSelectedTreaties) {
console.log("region and treaty selected 2");
//console.log("region and treaty selected 2");
return CountrySelectedStyle(selectedCountryColor, 0.7);
}
// default style
console.log("default");
//console.log("default");
return CountryStyle();
};
@ -646,10 +631,12 @@ class ControlInAfricaMap extends React.Component {
zoomControl,
center,
scrollWheelZoom,
showInfoBox,
countriesNames,
selectedCountry,
selectedCountriesNamesRegions,
selectedCountriesNamesTreaties,
currentStatuesTreaty,
selectedCountryColor,
selectedRegion,
selectedTreaty,
@ -661,7 +648,6 @@ class ControlInAfricaMap extends React.Component {
international_treaties,
internationalIntsruments,
africanIntsruments,
intsruments,
} = this.state;
if (loading) {
@ -673,7 +659,7 @@ class ControlInAfricaMap extends React.Component {
return (
<Container fluid>
<Row>
<Col className="filter-section" sm={3}>
<Col className="filter-section" sm={2}>
<FilterBox
selectedCountry={selectedCountry}
countriesNames={countriesNames}
@ -686,10 +672,9 @@ class ControlInAfricaMap extends React.Component {
international_treaties={international_treaties}
internationalIntsruments={internationalIntsruments}
africanIntsruments={africanIntsruments}
intsruments={intsruments}
></FilterBox>
</Col>
<Col className="map-section" sm={9}>
<Col className="map-section" sm={10}>
<div id="map" className="map-container">
<MapContainer
center={center}
@ -774,6 +759,7 @@ class ControlInAfricaMap extends React.Component {
<button onClick={this.zoomIn}>+</button>
<button onClick={this.zoomOut}>-</button>
<button onClick={this.resetMap}>*</button>
</div>
<div className="country-select">
@ -798,8 +784,19 @@ class ControlInAfricaMap extends React.Component {
) : (
<></>
)}
{selectedRegion && selectedTreaty && (
<TreatyInfoBox
selectedRegion={selectedRegion}
selectedTreatyOfficialName={selectedTreatyOfficialName}
currentStatuesTreaty={currentStatuesTreaty}
selectedCountriesNamesTreaties={
selectedCountriesNamesTreaties
}
handleCountryChange={this.handleCountryChange}
></TreatyInfoBox>
)}
{this.state.showInfoBox && (
{showInfoBox && (
<MapInfoBox
className="info-box"
selectedCountryColor={selectedCountryColor}

View File

@ -20,8 +20,6 @@ const FilterBox = (props) => {
const handleClose = () => setShow(false);
const toggleShow = () => setShow((s) => !s);
console.log(show);
const {
handleOrganizationClick,
handleTreatiesClick,

View File

@ -6,7 +6,6 @@ const MapInfoBox = (props) => {
const { internationalIntsruments_, africanIntsruments_ } = props.info;
const regional_treaties = props.info.organisationsRegionalTreaties;
const international_treaties = props.info.organisationsInternationalTreaties;
const instruments = props.info.organisationsInstruments;
const [open, setOpen] = useState(true);
const [isHidden, setIsHidden] = useState(false);

View File

@ -13,7 +13,7 @@ const Reg_Org_Filter = (props) => {
key={org.name}
className="organization-item"
style={{ backgroundColor: org.color }}
onClick={() => handleOrganizationClick(org.name, "", org.color)}
onClick={() => handleOrganizationClick(org.name, org.color)}
>
<div className="name">{org.name}</div>
</div>

View File

@ -6,8 +6,8 @@ const SelectedFilters = (props) => {
return (
<Card_ className="selected-filters p-2">
<h5>Selected Filter/s:</h5>
{selectedRegion && <li>{selectedRegion}</li>}
{selectedTreatyOfficialName && <li>{selectedTreatyOfficialName}</li>}
{selectedRegion && <li><i>{selectedRegion}</i></li>}
{selectedTreatyOfficialName && <li><i>{selectedTreatyOfficialName}</i></li>}
</Card_>
);
};

View File

@ -185,7 +185,7 @@ const Treaties_Filter = (props) => {
</h5>
)}
{internationalIntsruments.map((instrument) => (
<div key={instrument.name} className="treaty-item">
<div key={instrument.name} className="instrument-item">
<img
src={instrument.icon}
alt={instrument.name}
@ -212,7 +212,7 @@ const Treaties_Filter = (props) => {
</h5>
{africanIntsruments.map((instrument) => (
<div key={instrument.name} className="treaty-item">
<div key={instrument.name} className="instrument-item">
<img
src={instrument.icon}
alt={instrument.name}

View File

@ -0,0 +1,54 @@
import React, {useState} from "react";
import Card_ from "../../UI/Card_/Card_";
import Collapse from "react-bootstrap/Collapse";
const TreatyInfoBox = (props) => {
const [open, setOpen] = useState(true);
const [isHidden, setIsHidden] = useState(false);
const {
selectedRegion,
currentStatuesTreaty,
selectedTreatyOfficialName,
selectedCountriesNamesTreaties,
handleCountryChange,
} = props;
return (
<Card_ className="selected-treaty-card">
<div
onClick={() => setOpen(!open)}
aria-controls="example-collapse-text"
aria-expanded={open}
>
<h5>
{selectedRegion} members {currentStatuesTreaty}{" "}
{selectedTreatyOfficialName}
</h5>
</div>
<Collapse in={open}>
<div id="example-collapse-text">
{selectedCountriesNamesTreaties.length > 0 ? (
<ul>
{selectedCountriesNamesTreaties.map((country, index) => (
<li
onClick={handleCountryChange}
data-country={country}
key={index}
className="countries-list"
>
{country}
</li>
))}
</ul>
) : (
<p>
No {selectedRegion} members have {currentStatuesTreaty}{" "}
{selectedTreatyOfficialName}
</p>
)}
</div>
</Collapse>
</Card_>
);
};
export default TreatyInfoBox;

View File

@ -1,67 +1,74 @@
.filters-box {
padding: $gap;
border: 1px solid $border-color;
//height: 100vh;
}
// _organizations
.regional-organisations {
display: grid;
grid-template-columns: repeat(3, $organization-item-width);
grid-template-rows: repeat(2, $organization-item-height);
gap: $gap;
}
padding: $gap;
border: 1px solid $border-color;
//height: 100vh;
}
// _organizations
.geographical-organisations {
display: grid;
grid-template-columns: repeat(3, $organization-item-width);
//grid-template-rows: repeat(2, $organization-item-height);
gap: $gap;
}
.organization-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
border-radius: 5px;
}
.organization-item:hover {
opacity: $opacity-hover;
}
.name {
font-size: $font-size-small;
}
// _treaties
.treaty-item {
display: grid;
grid-template-columns: repeat(4, 25%);
margin-bottom: 15px;
}
.treaty-item-name {
font-size: $font-size-small;
}
.icon {
width: $icon-size-large;
height: $icon-size-large;
cursor: pointer;
}
.icon-2 {
width: $icon-size-small;
height: $icon-size-small;
cursor: pointer;
}
.treaty-item-2 {
display: grid;
grid-template-columns: repeat(2, 25%);
margin-bottom: 15px;
}
// _organizations
.regional-organisations {
display: grid;
grid-template-columns: repeat(3, $organization-item-width);
grid-template-rows: repeat(2, $organization-item-height);
gap: $gap;
}
// _organizations
.geographical-organisations {
display: grid;
grid-template-columns: repeat(3, $organization-item-width);
//grid-template-rows: repeat(2, $organization-item-height);
gap: $gap;
}
.organization-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
border-radius: 5px;
}
.organization-item:hover {
opacity: $opacity-hover;
}
.name {
font-size: $font-size-small;
}
// _treaties
.treaty-item {
display: grid;
grid-template-columns: 20% 20% 20% 40%;
margin-bottom: 15px;
}
// _treaties
.instrument-item {
display: grid;
grid-template-columns: 25% 75%;
margin-bottom: 15px;
}
.treaty-item-name {
font-size: $font-size-small;
}
.icon {
width: $icon-size-large;
height: $icon-size-large;
cursor: pointer;
}
.icon-2 {
width: $icon-size-small;
height: $icon-size-small;
cursor: pointer;
}
.treaty-item-2 {
display: grid;
grid-template-columns: repeat(2, 25%);
margin-bottom: 15px;
}

View File

@ -0,0 +1,20 @@
.selected-treaty-card {
position: absolute;
bottom: 20px;
left: 400px;
background-color: white;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 1000;
}
.countries-list {
cursor: pointer;
text-decoration: underline;
}
.countries-list:hover {
color: $primary-accent-color;
}

View File

@ -15,6 +15,7 @@
@import 'Layout/map_pssm';
@import 'Layout/info_section';
@import 'Layout/_map_info_box';
@import 'Layout/_map_info_box2';
// Import other layout partials...
// Components