show/hide info box and filter, languages

This commit is contained in:
louai98 2024-06-06 15:55:38 +02:00
parent 07638628ea
commit f9ea03e64c
12 changed files with 523 additions and 490 deletions

View File

@ -74,7 +74,6 @@ class ControlInAfricaMap extends React.Component {
super(props);
this.mapRef = createRef(); // Create a ref to store the MapContainer instance
this.state = {
africaCountries: null,
countriesNames: [],
@ -88,8 +87,9 @@ class ControlInAfricaMap extends React.Component {
error: null,
center: [3, 15],
zoom: 4,
scrollWheelZoom: false,
zoom: this.getZoomLevel(window.innerWidth),
scrollWheelZoom: true,
zoomControl: false,
openedTooltipLayer: null,
@ -112,116 +112,18 @@ class ControlInAfricaMap extends React.Component {
infoBox: [],
showInfoBox: false,
};
}
regional_organisations = [
{ name: "AU", color: "#b2df8a" },
{ name: "EAC", color: "#33a02c" },
{ name: "IGAD", color: "#fb9a99" },
{ name: "UMA", color: "#e31a1c" },
{ name: "COMESA", color: "#fdbf6f" },
{ name: "ECOWAS", color: "#ff7f00" },
{ name: "CEN-SAD", color: "#cab2d6" },
{ name: "SADC", color: "#6a3d9a" },
{ name: "ECCAS", color: "#ffff99" },
{ name: "ICGLR", color: "#b15928" },
{ name: "RECSA", color: "#a6cee3" },
{ name: "SARCOM", color: "#1f78b4" },
];
regional_treaties = [
{
name: "Bamako Declaration",
name2: "BamakoDeclaration",
icon_eligible: Icon26,
icon_signed: Icon24,
icon_ratified: null,
},
{
name: "Kinshasa Convention",
name2: "KinshasaConvention",
icon_eligible: Icon4,
icon_signed: Icon6,
icon_ratified: Icon5,
},
{
name: "ECOWAS Convention",
name2: "ECOWASConvention",
icon_eligible: Icon2,
icon_signed: Icon3,
icon_ratified: null,
},
{
name: "Khartoum Declaration",
name2: "KhartoumDeclaration",
icon_eligible: Icon21,
icon_signed: Icon23,
icon_ratified: null,
},
{
name: "Nairobi Protocol",
name2: "NairobiProtocol",
icon_eligible: Icon22,
icon_signed: Icon25,
icon_ratified: null,
},
{
name: "SADC Firearms Protocol",
name2: "SADCFirearmsProtocol",
icon_eligible: Icon8,
icon_signed: Icon7,
icon_ratified: Icon9,
},
];
international_treaties = [
{
name: "Arms Trade Treaty",
name2: "ArmsTradeTreaty",
icon_eligible: Icon19,
icon_signed: Icon17,
icon_ratified: Icon18,
},
{
name: "Firearms Protocol",
name2: "FirearmsProtocol",
icon_eligible: Icon12,
icon_signed: Icon10,
icon_ratified: Icon11,
},
{
name: "Wassenaar Agreement",
name2: "WassenaarAgreement",
icon_eligible: Icon15,
icon_signed: Icon13,
icon_ratified: Icon14,
},
];
intsruments = [
{
name2: "UNProgrammeofAction",
name: "UN Programme of Action",
icon: Icon20,
},
{
name2: "InternationalTracingInstrument",
name: "International Tracing Instrument",
icon: Icon16,
},
{
name2: "StG-PoA",
name: "Silencing the Guns in Africa Programme of Action",
icon: Icon1,
},
];
componentDidMount() {
this.fetchData();
this.calculateZoomLevel();
window.addEventListener("resize", this.calculateZoomLevel);
window.addEventListener("resize", this.handleResize);
}
componentWillUnmount() {}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
fetchData = async () => {
try {
@ -251,7 +153,6 @@ class ControlInAfricaMap extends React.Component {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Replace icon names with actual icon objects
const regional_treaties = data.regional_treaties.map((treaty) => ({
...treaty,
@ -290,17 +191,25 @@ class ControlInAfricaMap extends React.Component {
}
};
calculateZoomLevel = () => {
getZoomLevel = () => {
const screenWidth = window.innerWidth;
if (screenWidth <= 768) {
this.setState({ zoom: 3 });
console.log(screenWidth);
if (screenWidth <= 800) {
console.log("small screen");
return 3;
} else if (screenWidth <= 1024) {
this.setState({ zoom: 4 });
return 4;
} else {
this.setState({ zoom: 4 });
return 4;
}
};
handleResize = () => {
this.setState({
zoom: this.getZoomLevel(window.innerWidth),
});
};
resetMap = () => {
if (this.mapRef.current) {
this.mapRef.current.setView(this.state.center, this.state.zoom); // Set the center and zoom to initial values
@ -585,6 +494,7 @@ class ControlInAfricaMap extends React.Component {
selectedCountriesFeaturesRegions,
regional_treaties,
international_treaties,
intsruments,
} = this.state;
// Helper function to process treaties
@ -619,7 +529,7 @@ class ControlInAfricaMap extends React.Component {
international_treaties
);
const organisationsInstruments = this.intsruments.map((instrument) => {
const organisationsInstruments = intsruments.map((instrument) => {
const countris = selectedCountriesFeaturesRegions.filter(
(feature) => feature.properties[instrument.name2] === 1
);
@ -678,6 +588,10 @@ class ControlInAfricaMap extends React.Component {
africaCountries,
loading,
error,
zoom,
zoomControl,
center,
scrollWheelZoom,
countriesNames,
selectedCountry,
selectedCountriesNamesRegions,
@ -701,7 +615,7 @@ class ControlInAfricaMap extends React.Component {
return (
<Container fluid>
<Row>
<Col sm={3}>
<Col className="filter-section" sm={3} >
<FilterBox
selectedCountry={selectedCountry}
countriesNames={countriesNames}
@ -714,15 +628,15 @@ class ControlInAfricaMap extends React.Component {
international_treaties={international_treaties}
></FilterBox>
</Col>
<Col sm={9}>
<Col className="map-section" sm={9}>
<div id="map" className="map-container">
<MapContainer
center={this.state.center}
zoom={this.state.zoom}
center={center}
zoom={zoom}
ref={this.mapRef}
zoomControl={false}
zoomControl={zoomControl}
style={{ width: "100%", height: "100%" }}
scrollWheelZoom={this.state.scrollWheelZoom}
scrollWheelZoom={scrollWheelZoom}
>
{africaCountries && (
<>
@ -800,6 +714,7 @@ class ControlInAfricaMap extends React.Component {
<button onClick={this.zoomOut}>-</button>
<button onClick={this.resetMap}>*</button>
</div>
<div className="country-select">
<select
onChange={this.handleCountryChange}
@ -813,6 +728,7 @@ class ControlInAfricaMap extends React.Component {
))}
</select>
</div>
{this.state.showInfoBox && (
<MapInfoBox
className="info-box"

View File

@ -1,14 +1,27 @@
import React from "react";
import React, { useState } from "react";
import Col from "react-bootstrap/Col";
import "../../../Styles/main.scss";
import Geo_Org_Filter from "./Geo_Org_Filter";
import Reg_Org_Filter from "./Reg_Org_Filter";
import Treaties_Filter from "./Treaties_Filter";
import LanguageSelect from "./LanguageSelect";
import Icon1 from "../../../Icons/icon1.svg";
import Icon16 from "../../../Icons/icon16.svg";
import Icon20 from "../../../Icons/icon20.svg";
import Button from "react-bootstrap/Button";
import Offcanvas from "react-bootstrap/Offcanvas";
const FilterBox = (props) => {
const [language, setLanguage] = useState("en");
const [show, setShow] = useState(false);
const handleLanguageChange = (language) => {
setLanguage(language);
};
const handleClose = () => setShow(false);
const toggleShow = () => setShow((s) => !s);
console.log(show);
const {
handleOrganizationClick,
handleTreatiesClick,
@ -19,25 +32,40 @@ const FilterBox = (props) => {
} = props;
return (
<>
<Button variant="primary" className="d-lg-none" onClick={toggleShow}>
Filters
</Button>
<Offcanvas show={show} onHide={handleClose} backdrop={false} scroll={true} responsive="lg">
<Offcanvas.Header closeButton>
<Offcanvas.Title>Filter Box</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<div className={`filters-box`}>
<LanguageSelect onLanguageChange={handleLanguageChange} />
<hr />
<Geo_Org_Filter
handleOrganizationClick={handleOrganizationClick}
geographical_organisations={geographical_organisations}
language={language}
/>
<hr />
<Reg_Org_Filter
handleOrganizationClick={handleOrganizationClick}
regional_organisations={regional_organisations}
language={language}
/>
<hr />
<Treaties_Filter
regional_treaties={regional_treaties}
international_treaties={international_treaties}
handleTreatiesClick={handleTreatiesClick}
language={language}
/>
</div>
</Offcanvas.Body>
</Offcanvas>
</>
);
};

View File

@ -1,18 +1,21 @@
import React from 'react'
import React from "react";
const Geo_Org_Filter = (props) => {
const {
handleOrganizationClick,
geographical_organisations,
} = props;
const headings = {
en: "Geographical Organisations",
fr: "Organisations Géographiques",
ar: "المنظمات الجغرافية",
};
const { handleOrganizationClick, geographical_organisations, language } =
props;
return (
<div>
<h5>Geographical Organisations</h5>
<div className="regional-organisations">
<>
<h5>{headings[language] || headings['en']} </h5>
<div className="geographical-organisations">
{geographical_organisations.map((org, index) => (
<div
key={org.name}
className="organization-item p-2"
className="organization-item p-1"
style={{ backgroundColor: org.color }}
onClick={() => handleOrganizationClick(org.name, "", org.color)}
>
@ -20,8 +23,8 @@ const Geo_Org_Filter = (props) => {
</div>
))}
</div>
</div>
)
}
</>
);
};
export default Geo_Org_Filter
export default Geo_Org_Filter;

View File

@ -0,0 +1,41 @@
import React, {useState} from "react";
import Button from 'react-bootstrap/Button';
import ButtonGroup from "react-bootstrap/ButtonGroup";
import ToggleButton from "react-bootstrap/ToggleButton";
const LanguageSelect = ({onLanguageChange}) => {
const [languageValue, setLanguageValue] = useState("en")
const languages = [
{ lang: "En", value: "en" },
{ lang: "Fr", value: "fr" },
{ lang: "ع", value: "ar" },
];
const handleLanguageChange = (language) => {
setLanguageValue(language);
onLanguageChange(language);
};
return (
<>
<ButtonGroup>
<Button variant="secondary" disabled>Language:</Button>{' '}
{languages.map((language, idx) => (
<ToggleButton
key={idx}
id={`language-${idx}`}
type="radio"
variant={"outline-secondary"}
name="language"
value={language.value}
checked={languageValue === language.value}
onChange={(e) => handleLanguageChange(e.currentTarget.value)}
>
{language.lang}
</ToggleButton>
))}
</ButtonGroup>
</>
);
};
export default LanguageSelect;

View File

@ -1,13 +1,27 @@
import React from "react";
import React, { useState } from "react";
import Button from "react-bootstrap/Button";
import Collapse from "react-bootstrap/Collapse";
const MapInfoBox = (props) => {
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);
return (
<div className={props.className}>
<h3>{props.selectedRegion}</h3>
<div
onClick={() => {setOpen(!open); setIsHidden(!isHidden);}}
aria-controls="example-collapse-text"
aria-expanded={open}
style={{ display: "flex", justifyContent: "space-between" }}
>
<span><h3>{props.selectedRegion}</h3></span>
<span><h3>{isHidden ? 'Show' : 'Hide'}</h3></span>
</div>
<Collapse in={open}>
<div className="example-collapse-text">
<p>Number of countries</p>
<div className="table-responsive-sm">
<table className="table table-sm table-striped">
@ -152,30 +166,9 @@ const MapInfoBox = (props) => {
);
})}
</div>
</Collapse>
</div>
);
};
export default MapInfoBox;
//{regional_treaties &&
// regional_treaties.map((item, index) => {
// return (
// <div key={index}>
// <p>
// <strong>{item.name}</strong> Signed: {item.signed}, Eligible:{" "}
// {item.eligible}, Ratified: {item.ratified}
// </p>
// </div>
// );
// })}
// {international_treaties &&
// international_treaties.map((item, index) => {
// return (
// <div key={index}>
// <p>
// <strong>{item.name}</strong> Signed: {item.signed}, Eligible:{" "}
// {item.eligible}, Ratified: {item.ratified}
// </p>
// </div>
// );
// })}

View File

@ -1,11 +1,12 @@
import React from "react";
const Reg_Org_Filter = (props) => {
const { handleOrganizationClick, regional_organisations } = props;
const { handleOrganizationClick, regional_organisations, language } = props;
return (
<div>
<h5>Regional Organisations</h5>
<h6>Organisations internationales / المنظمات الإقليمية</h6>
{language === "en" && <h5>Regional Organisations</h5>}
{language === "fr" && <h5>Organisations internationales</h5>}
{language === "ar" && <h5>المنظمات الإقليمية</h5>}
<div className="regional-organisations">
{regional_organisations.map((org, index) => (
<div

View File

@ -4,31 +4,60 @@ import Icon16 from "../../../Icons/icon16.svg";
import Icon20 from "../../../Icons/icon20.svg";
const Treaties_Filter = (props) => {
const { international_treaties, handleTreatiesClick, regional_treaties } = props;
const regionalTreatiesHeadings = {
en: "Regional Treaties",
fr: "Traités régionales",
ar: "المعاهدات الأقليمية",
};
const internationalTreatiesHeadings = {
en: "International Treaties",
fr: "Traités internationales",
ar: "المعاهدات الدولية",
};
const africanGuidelinesHeadings = {
en: "African Guidelines & Instrumentss",
fr: "Directives & instruments africains",
ar: "المبادىء التوجيهية و الأدوات السياسية في افريقيا",
}
const {
international_treaties,
handleTreatiesClick,
regional_treaties,
language,
} = props;
return (
<div>
<div>
<h5>Regional Treaties</h5>
<h6>Traités régionales / المعاهدات الأقليمية</h6>
<h5>
{regionalTreatiesHeadings[language] || regionalTreatiesHeadings["en"]}
</h5>
<div className="regional-treaties">
<div className="treaty-item mb-0">
{language === "en" && (
<div className="treaty-item">
<div className="treaty-item-name">Eligible</div>
<div className="treaty-item-name">Signed</div>
<div className="treaty-item-name">Ratified</div>
<div className="treaty-item-name"></div>
</div>
<div className="treaty-item mb-0">
)}
{language === "fr" && (
<div className="treaty-item">
<div className="treaty-item-name">Eligible</div>
<div className="treaty-item-name">Signé</div>
<div className="treaty-item-name">Ratifié</div>
<div className="treaty-item-name"></div>
</div>
)}
{language === "ar" && (
<div className="treaty-item">
<div className="treaty-item-name">المتفق عليها</div>
<div className="treaty-item-name">موقعة</div>
<div className="treaty-item-name">مصدق عليها</div>
<div className="treaty-item-name"></div>
</div>
)}
{regional_treaties.map((treaty) => (
<div key={treaty.name} className="treaty-item">
{treaty.icon_eligible ? (
@ -74,8 +103,10 @@ const Treaties_Filter = (props) => {
<hr />
</div>
<div>
<h5>International Treaties</h5>
<h6>Traités internationales / المعاهدات الدولية</h6>
<h5>
{internationalTreatiesHeadings[language] ||
internationalTreatiesHeadings["en"]}
</h5>
{international_treaties.map((treaty) => (
<div key={treaty.name} className="treaty-item">
{treaty.icon_eligible ? (
@ -120,18 +151,18 @@ const Treaties_Filter = (props) => {
<hr />
</div>
<div>
<h5>
{language === "en" && <h5>
International Guidelines & Instruments <br />
<small>(countries with recent activities only, 2014 - 2019)</small>
</h5>
<h6>
</h5>}
{language === "fr" && <h5>
Directives & instruments internationaux <br />
<small>(pays avec activité récente uniquement, 2014 - 2019)</small>
</h6>
<h6>
</h5>}
{language === "ar" && <h5>
المبادىء التوجيهية و الأدوات الدولية <br />
<small>(فقط الدول ذات النشاطات الحديثة 2014-2019)</small>
</h6>
</h5>}
<div className="treaty-item-2">
<img
src={Icon20}
@ -159,9 +190,8 @@ const Treaties_Filter = (props) => {
<hr />
</div>
<div>
<h5>African Guidelines & Instrumentss</h5>
<h6>Directives & instruments africains</h6>
<h6>المبادىء التوجيهية و الأدوات السياسية في افريقيا</h6>
<h5>{africanGuidelinesHeadings[language] || africanGuidelinesHeadings['en']}</h5>
<div className="treaty-item-2">
<img
src={Icon1}

View File

@ -12,6 +12,14 @@
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;

View File

@ -8,8 +8,8 @@
.map-container {
border: 1px solid $border-color;
width: 100%;
height: 100vh;
width: $map-width;
height: $map-height;
margin-top: 0px;
}
@ -17,11 +17,21 @@
position: absolute;
top: 20px;
left: 20px;
// 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;
}
@media (min-width: 200px) {
.col-sm-9 {
flex: 0 0 auto;
width: 100% !important;
}
}
@media (min-width: 990px) {
.col-sm-9 {
flex: 0 0 auto;
width: 75% !important;
}
}

View File

@ -8,5 +8,15 @@
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 1000;
//width: 250px;
}
@media screen and (min-width: 200px) {
.info-box{
width: 80%;
}
}
@media screen and (min-width: 810px) {
.info-box{
width: 350px;
}
}

View File

@ -20,3 +20,5 @@ $font-size-small: 12px;
$icon-size-large: 50px;
$icon-size-small: 35px;
$opacity-hover: 0.8;
$map-width: 100%;
$map-height: 100vh;

View File

@ -1,109 +1,100 @@
"regional_organisations": [
{ "name": "AU", "color": "#b2df8a" },
{ "name": "EAC", "color": "#33a02c" },
{ "name": "IGAD", "color": "#fb9a99" },
{ "name": "UMA", "color": "#e31a1c" },
{ "name": "COMESA", "color": "#fdbf6f" },
{ "name": "ECOWAS", "color": "#ff7f00" },
{ "name": "CEN-SAD", "color": "#cab2d6" },
{ "name": "SADC", "color": "#6a3d9a" },
{ "name": "ECCAS", "color": "#ffff99" },
{ "name": "ICGLR", "color": "#b15928" },
{ "name": "RECSA", "color": "#a6cee3" },
{ "name": "SARCOM", "color": "#1f78b4" }
],
regional_organisations = [
{ name: "AU", color: "#b2df8a" },
{ name: "EAC", color: "#33a02c" },
{ name: "IGAD", color: "#fb9a99" },
{ name: "UMA", color: "#e31a1c" },
{ name: "COMESA", color: "#fdbf6f" },
{ name: "ECOWAS", color: "#ff7f00" },
{ name: "CEN-SAD", color: "#cab2d6" },
{ name: "SADC", color: "#6a3d9a" },
{ name: "ECCAS", color: "#ffff99" },
{ name: "ICGLR", color: "#b15928" },
{ name: "RECSA", color: "#a6cee3" },
{ name: "SARCOM", color: "#1f78b4" },
];
"geographical_organisations": [
{ "name": "Northern-Africa", "color": "#e3e3e3" },
{ "name": "Eastern-Africa", "color": "#e3e3e3" },
{ "name": "Southern-Africa", "color": "#e3e3e3" },
{ "name": "Western-Africa", "color": "#e3e3e3" },
{ "name": "Central-Africa", "color": "#e3e3e3" }
],
regional_treaties = [
{
name: "Bamako Declaration",
name2: "BamakoDeclaration",
icon_eligible: Icon26,
icon_signed: Icon24,
icon_ratified: null,
},
{
name: "Kinshasa Convention",
name2: "KinshasaConvention",
icon_eligible: Icon4,
icon_signed: Icon6,
icon_ratified: Icon5,
},
{
name: "ECOWAS Convention",
name2: "ECOWASConvention",
icon_eligible: Icon2,
icon_signed: Icon3,
icon_ratified: null,
},
{
name: "Khartoum Declaration",
name2: "KhartoumDeclaration",
icon_eligible: Icon21,
icon_signed: Icon23,
icon_ratified: null,
},
{
name: "Nairobi Protocol",
name2: "NairobiProtocol",
icon_eligible: Icon22,
icon_signed: Icon25,
icon_ratified: null,
},
{
name: "SADC Firearms Protocol",
name2: "SADCFirearmsProtocol",
icon_eligible: Icon8,
icon_signed: Icon7,
icon_ratified: Icon9,
},
];
"regional_treaties": [
international_treaties = [
{
"name": "Bamako Declaration",
"name2": "BamakoDeclaration",
"icon_eligible": "Icon26",
"icon_signed": "Icon24",
"icon_ratified": "none"
name: "Arms Trade Treaty",
name2: "ArmsTradeTreaty",
icon_eligible: Icon19,
icon_signed: Icon17,
icon_ratified: Icon18,
},
{
"name": "Kinshasa Convention",
"name2": "KinshasaConvention",
"icon_eligible": "Icon4",
"icon_signed": "Icon6",
"icon_ratified": "Icon5"
name: "Firearms Protocol",
name2: "FirearmsProtocol",
icon_eligible: Icon12,
icon_signed: Icon10,
icon_ratified: Icon11,
},
{
"name": "ECOWAS Convention",
"name2": "ECOWASConvention",
"icon_eligible": "Icon2",
"icon_signed": "Icon3",
"icon_ratified": "none"
name: "Wassenaar Agreement",
name2: "WassenaarAgreement",
icon_eligible: Icon15,
icon_signed: Icon13,
icon_ratified: Icon14,
},
];
intsruments = [
{
name2: "UNProgrammeofAction",
name: "UN Programme of Action",
icon: Icon20,
},
{
"name": "Khartoum Declaration",
"name2": "KhartoumDeclaration",
"icon_eligible": "Icon21",
"icon_signed": "Icon23",
"icon_ratified": "none"
name2: "InternationalTracingInstrument",
name: "International Tracing Instrument",
icon: Icon16,
},
{
"name": "Nairobi Protocol",
"name2": "NairobiProtocol",
"icon_eligible": "Icon22",
"icon_signed": "Icon25",
"icon_ratified": "none"
name2: "StG-PoA",
name: "Silencing the Guns in Africa Programme of Action",
icon: Icon1,
},
{
"name": "SADC Firearms Protocol",
"name2": "SADCFirearmsProtocol",
"icon_eligible": "Icon8",
"icon_signed": "Icon7",
"icon_ratified": "Icon9"
}
],
"international_treaties": [
{
"name": "Arms Trade Treaty",
"name2": "ArmsTradeTreaty",
"icon_eligible": "Icon19",
"icon_signed": "Icon17",
"icon_ratified": "Icon18"
},
{
"name": "Firearms Protocol",
"name2": "FirearmsProtocol",
"icon_eligible": "Icon12",
"icon_signed": "Icon10",
"icon_ratified": "Icon11"
},
{
"name": "Wassenaar Agreement",
"name2": "WassenaarAgreement",
"icon_eligible": "Icon15",
"icon_signed": "Icon13",
"icon_ratified": "Icon14"
}
],
"intsruments": [
{
"name2": "UNProgrammeofAction",
"name": "UN Programme of Action",
"icon": "Icon20"
},
{
"name2": "InternationalTracingInstrument",
"name": "International Tracing Instrument",
"icon": "Icon16"
},
{
"name2": "StG-PoA",
"name": "Silencing the Guns in Africa Programme of Action",
"icon": "Icon1"
}
]
];