From a1037291e5b35b3378f505c121c46c71cfcb4a33 Mon Sep 17 00:00:00 2001 From: louai98 Date: Mon, 10 Jun 2024 14:58:08 +0200 Subject: [PATCH] treaty info box --- package-lock.json | 6 + package.json | 1 + .../ControlInAfrica/ControlInAfricaMap.js | 163 +++++++++--------- .../Layout/ControlInAfrica/FilterBox.jsx | 2 - .../Layout/ControlInAfrica/MapInfoBox.jsx | 1 - .../Layout/ControlInAfrica/Reg_Org_Filter.jsx | 2 +- .../ControlInAfrica/SelectedFilters.jsx | 4 +- .../ControlInAfrica/Treaties_Filter.jsx | 4 +- .../Layout/ControlInAfrica/TreatyInfoBox.jsx | 54 ++++++ src/Styles/Layout/_filters.scss | 137 ++++++++------- src/Styles/Layout/_map_info_box2.scss | 20 +++ src/Styles/main.scss | 1 + 12 files changed, 239 insertions(+), 156 deletions(-) create mode 100644 src/Components/Layout/ControlInAfrica/TreatyInfoBox.jsx create mode 100644 src/Styles/Layout/_map_info_box2.scss diff --git a/package-lock.json b/package-lock.json index 3037fdb..e43e1bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index ea618b1..fb09e2a 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/Components/Layout/ControlInAfrica/ControlInAfricaMap.js b/src/Components/Layout/ControlInAfrica/ControlInAfricaMap.js index 90d799c..46fd78d 100644 --- a/src/Components/Layout/ControlInAfrica/ControlInAfricaMap.js +++ b/src/Components/Layout/ControlInAfrica/ControlInAfricaMap.js @@ -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 = `
Selected: ${countryName}
`; 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 ( - + - +
+ +
@@ -798,8 +784,19 @@ class ControlInAfricaMap extends React.Component { ) : ( <> )} + {selectedRegion && selectedTreaty && ( + + )} - {this.state.showInfoBox && ( + {showInfoBox && ( { const handleClose = () => setShow(false); const toggleShow = () => setShow((s) => !s); - console.log(show); - const { handleOrganizationClick, handleTreatiesClick, diff --git a/src/Components/Layout/ControlInAfrica/MapInfoBox.jsx b/src/Components/Layout/ControlInAfrica/MapInfoBox.jsx index de4033b..7782de7 100644 --- a/src/Components/Layout/ControlInAfrica/MapInfoBox.jsx +++ b/src/Components/Layout/ControlInAfrica/MapInfoBox.jsx @@ -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); diff --git a/src/Components/Layout/ControlInAfrica/Reg_Org_Filter.jsx b/src/Components/Layout/ControlInAfrica/Reg_Org_Filter.jsx index ab4ef98..248d280 100644 --- a/src/Components/Layout/ControlInAfrica/Reg_Org_Filter.jsx +++ b/src/Components/Layout/ControlInAfrica/Reg_Org_Filter.jsx @@ -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)} >
{org.name}
diff --git a/src/Components/Layout/ControlInAfrica/SelectedFilters.jsx b/src/Components/Layout/ControlInAfrica/SelectedFilters.jsx index 9c7714a..9792eda 100644 --- a/src/Components/Layout/ControlInAfrica/SelectedFilters.jsx +++ b/src/Components/Layout/ControlInAfrica/SelectedFilters.jsx @@ -6,8 +6,8 @@ const SelectedFilters = (props) => { return (
Selected Filter/s:
- {selectedRegion &&
  • {selectedRegion}
  • } - {selectedTreatyOfficialName &&
  • {selectedTreatyOfficialName}
  • } + {selectedRegion &&
  • {selectedRegion}
  • } + {selectedTreatyOfficialName &&
  • {selectedTreatyOfficialName}
  • }
    ); }; diff --git a/src/Components/Layout/ControlInAfrica/Treaties_Filter.jsx b/src/Components/Layout/ControlInAfrica/Treaties_Filter.jsx index f0085c7..2d75e02 100644 --- a/src/Components/Layout/ControlInAfrica/Treaties_Filter.jsx +++ b/src/Components/Layout/ControlInAfrica/Treaties_Filter.jsx @@ -185,7 +185,7 @@ const Treaties_Filter = (props) => { )} {internationalIntsruments.map((instrument) => ( -
    +
    {instrument.name} { {africanIntsruments.map((instrument) => ( -
    +
    {instrument.name} { + const [open, setOpen] = useState(true); + const [isHidden, setIsHidden] = useState(false); + const { + selectedRegion, + currentStatuesTreaty, + selectedTreatyOfficialName, + selectedCountriesNamesTreaties, + handleCountryChange, + } = props; + return ( + +
    setOpen(!open)} + aria-controls="example-collapse-text" + aria-expanded={open} + > +
    + {selectedRegion} members {currentStatuesTreaty}{" "} + {selectedTreatyOfficialName} +
    +
    + +
    + {selectedCountriesNamesTreaties.length > 0 ? ( +
      + {selectedCountriesNamesTreaties.map((country, index) => ( +
    • + {country} +
    • + ))} +
    + ) : ( +

    + No {selectedRegion} members have {currentStatuesTreaty}{" "} + {selectedTreatyOfficialName} +

    + )} +
    +
    +
    + ); +}; + +export default TreatyInfoBox; diff --git a/src/Styles/Layout/_filters.scss b/src/Styles/Layout/_filters.scss index e5c6b22..4a514e2 100644 --- a/src/Styles/Layout/_filters.scss +++ b/src/Styles/Layout/_filters.scss @@ -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; - } \ No newline at end of file +// _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; +} diff --git a/src/Styles/Layout/_map_info_box2.scss b/src/Styles/Layout/_map_info_box2.scss new file mode 100644 index 0000000..44885bf --- /dev/null +++ b/src/Styles/Layout/_map_info_box2.scss @@ -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; +} diff --git a/src/Styles/main.scss b/src/Styles/main.scss index 3c65e0d..62bea58 100644 --- a/src/Styles/main.scss +++ b/src/Styles/main.scss @@ -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