pssm legend - select

This commit is contained in:
louai98 2024-06-10 17:16:53 +02:00
parent a1037291e5
commit f2c0c1ab3c
9 changed files with 326 additions and 136 deletions

View File

@ -759,7 +759,6 @@ class ControlInAfricaMap extends React.Component {
<button onClick={this.zoomIn}>+</button> <button onClick={this.zoomIn}>+</button>
<button onClick={this.zoomOut}>-</button> <button onClick={this.zoomOut}>-</button>
<button onClick={this.resetMap}>*</button> <button onClick={this.resetMap}>*</button>
</div> </div>
<div className="country-select"> <div className="country-select">

View File

@ -3,6 +3,7 @@ import Card_ from "../../UI/Card_/Card_";
import DOMPurify from "dompurify"; import DOMPurify from "dompurify";
import parse from "html-react-parser"; import parse from "html-react-parser";
import TruncateContent from "../../Helpers/TruncateContent/TruncateContent"; import TruncateContent from "../../Helpers/TruncateContent/TruncateContent";
import Collapse from "react-bootstrap/Collapse";
const Blurb = () => { const Blurb = () => {
DOMPurify.addHook("afterSanitizeAttributes", function (node) { DOMPurify.addHook("afterSanitizeAttributes", function (node) {
@ -30,15 +31,14 @@ const Blurb = () => {
return ( return (
<Card_ className="p-3"> <Card_ className="p-3">
<TruncateContent> <MainText footnotes={footnotes} />
<MainText footnotes={footnotes} />
<Footnotes footnotes={footnotes} />
</TruncateContent>
</Card_> </Card_>
); );
}; };
const MainText = ({ footnotes }) => { const MainText = ({ footnotes }) => {
const [open, setOpen] = useState(false);
const [isHidden, setIsHidden] = useState(true);
return ( return (
<div> <div>
<h3>Physical Security and Stockpile Management (PSSM)</h3> <h3>Physical Security and Stockpile Management (PSSM)</h3>
@ -61,100 +61,110 @@ const MainText = ({ footnotes }) => {
</sup> </sup>
. .
</p> </p>
<p>
Physical Security and Stockpile Management (PSSM) consists of the
procedures and activities that are necessary for the safe and secure
accounting, storage, transportation and handling of SALW
<sup>
<a href="#footnote-3">3</a>
</sup>
. It can therefore be viewed as a key element of practical weapons and
ammunition management, and it significantly decreases the risk of
illicit proliferation, trafficking and diversion of firearms,
ammunition, and explosives as well as reduces the risk of Unintentional
Munitions Explosions.
</p>
<p>
Responsible management of stockpiles can therefore positively impact on
efforts to reduce armed violence and contribute towards enhancing the
security of the surrounding communities as well as the security at the
local, national and regional level.
</p>
<h3>Regional PSSM Training of Trainers (ToT) processes</h3> <Collapse in={open}>
<p> <div id="example-collapse-text">
Since 2016, the bicc advisory team on Weapons and Ammunition Management <p>
(WAM) has been supporting two multi-stakeholder regional PSSM Training Physical Security and Stockpile Management (PSSM) consists of the
of Trainers (ToT) processes; one in East Africa (with the Regional procedures and activities that are necessary for the safe and
Centre on Small Arms in the Great Lakes Region, the Horn of Africa and secure accounting, storage, transportation and handling of SALW
Bordering States, RECSA) and one in West Africa (with the Economic <sup>
Community of West African States, ECOWAS). <a href="#footnote-3">3</a>
</p> </sup>
<p> . It can therefore be viewed as a key element of practical weapons
The aim of both processes was to support and enhance regional ownership, and ammunition management, and it significantly decreases the risk
strengthen PSSM capacities, establish sustainable structures by creating of illicit proliferation, trafficking and diversion of firearms,
a regional trainer pool whose trainers can independently train more ammunition, and explosives as well as reduces the risk of
trainers that equally possess the necessary regional and local Unintentional Munitions Explosions.
knowledge, thereby decreasing a dependency on foreign experts. The focus </p>
on regional ownership and sustainability represents a crucial piece of <p>
the peace and security puzzle, in alignment with SDG 16. Responsible management of stockpiles can therefore positively impact
</p> on efforts to reduce armed violence and contribute towards enhancing
<p> the security of the surrounding communities as well as the security
Based on the UN Programme of Action, and acknowledging PSSM as a key at the local, national and regional level.
element of WAM, the Multinational Small Arms and Ammunition Group (MSAG) </p>
initiated a training programme on the security and stockpile management
of weapons, ammunition, and explosives for East African states in Kenya
in 2012. Participants of the ToT processes derived from among the
military, police and wildlife service sectors. Up until March 2024, 469
participants have been trained, out of which 42 were certified as PSSM
Instructors and 13 as Senior Instructors. The map below shows their
geographical distribution.
</p>
<p>
In the meantime, the need for another regional PSSM ToT process was
identified in the ECOWAS region (West Africa), which was established in
2018 and completed in 2023. Based on the identified need for a regional
trainer pool and more accountable PSSM practices, this process also took
into account lessons learned from the East Africa ToT process. Between
2018 and 2023, a total of 000 participants have been trained, out of
which 000 were certified as PSSM Instructors and 000 as Senior
Instructors. The map below shows their geographical distribution.
</p>
<p>Stakeholders implementing the regional PSSM ToT trainings were:</p>
<ul>
<li>
RECSA, MSAG nations (namely the Bundeswehr Verification Centre, the
Austrian Verification Centre, Denmark, among others), IPSTC
(International Peace Support Training Centre) in Nairobi/Kenya and
bicc.
</li>
<li>ECOWAS, MSAG (the Bundeswehr Verification Centre) and bicc.</li>
</ul>
<p>
Each of these partners brings a unique skillset that complements that of
the other stakeholders.
</p>
</div>
);
};
const Footnotes = ({ footnotes }) => { <h3>Regional PSSM Training of Trainers (ToT) processes</h3>
return ( <p>
<div> Since 2016, the bicc advisory team on Weapons and Ammunition
<h4> Management (WAM) has been supporting two multi-stakeholder regional
<hr /> PSSM Training of Trainers (ToT) processes; one in East Africa (with
</h4> the Regional Centre on Small Arms in the Great Lakes Region, the
{footnotes.map((footnote) => ( Horn of Africa and Bordering States, RECSA) and one in West Africa
<ul> (with the Economic Community of West African States, ECOWAS).
<li </p>
className="list-unstyled" <p>
key={footnote.id} The aim of both processes was to support and enhance regional
id={`footnote-${footnote.id}`} ownership, strengthen PSSM capacities, establish sustainable
> structures by creating a regional trainer pool whose trainers can
<small>{parse(`${footnote.id}. ${footnote.text}`)}</small> independently train more trainers that equally possess the necessary
</li> regional and local knowledge, thereby decreasing a dependency on
</ul> foreign experts. The focus on regional ownership and sustainability
))} represents a crucial piece of the peace and security puzzle, in
alignment with SDG 16.
</p>
<p>
Based on the UN Programme of Action, and acknowledging PSSM as a key
element of WAM, the Multinational Small Arms and Ammunition Group
(MSAG) initiated a training programme on the security and stockpile
management of weapons, ammunition, and explosives for East African
states in Kenya in 2012. Participants of the ToT processes derived
from among the military, police and wildlife service sectors. Up
until March 2024, 469 participants have been trained, out of which
42 were certified as PSSM Instructors and 13 as Senior Instructors.
The map below shows their geographical distribution.
</p>
<p>
In the meantime, the need for another regional PSSM ToT process was
identified in the ECOWAS region (West Africa), which was established
in 2018 and completed in 2023. Based on the identified need for a
regional trainer pool and more accountable PSSM practices, this
process also took into account lessons learned from the East Africa
ToT process. Between 2018 and 2023, a total of 000 participants have
been trained, out of which 000 were certified as PSSM Instructors
and 000 as Senior Instructors. The map below shows their
geographical distribution.
</p>
<p>Stakeholders implementing the regional PSSM ToT trainings were:</p>
<ul>
<li>
RECSA, MSAG nations (namely the Bundeswehr Verification Centre,
the Austrian Verification Centre, Denmark, among others), IPSTC
(International Peace Support Training Centre) in Nairobi/Kenya and
bicc.
</li>
<li>ECOWAS, MSAG (the Bundeswehr Verification Centre) and bicc.</li>
</ul>
<p>
Each of these partners brings a unique skillset that complements
that of the other stakeholders.
</p>
<div>
<h4>
<hr />
</h4>
{footnotes.map((footnote) => (
<ul>
<li
className="list-unstyled"
key={footnote.id}
id={`footnote-${footnote.id}`}
>
<small>{parse(`${footnote.id}. ${footnote.text}`)}</small>
</li>
</ul>
))}
</div>
</div>
</Collapse>
<a
href="#"
onClick={() => {setOpen(!open); setIsHidden(!isHidden);}}
aria-controls="example-collapse-text"
aria-expanded={open}
>
{isHidden ? "Read more" : "Read less"}
</a>
</div> </div>
); );
}; };

View File

@ -0,0 +1,18 @@
import React from "react";
const Legend = () => {
return (
<div className="legend-container">
<div className="legend-item">
<div className="legend-recsa"></div>
<span>RECSA</span>
</div>
<div className="legend-item">
<div className="legend-ecowas"></div>
<span>ECOWAS</span>
</div>
</div>
);
};
export default Legend;

View File

@ -0,0 +1,52 @@
import React from "react";
import { Marker, Tooltip } from "react-leaflet";
import Person from "../../../Icons/person.svg";
import Person2 from "../../../Icons/person2.svg";
import Person3 from "../../../Icons/person3.svg";
const MarkerCustom = (props) => {
const { feature } = props;
return (
<Marker
position={[feature.properties.y, feature.properties.x]}
>
<Tooltip
direction="bottom"
offset={[-13, 27]}
opacity={1}
permanent
className="tooltip-custom"
>
<h5>{feature.properties.name}</h5>
<div>
<ul className="list-unstyled tooltip-text">
<li>
<img src={Person3} className="person-icon" /> Number of
participants trained:{" "}
<span className="tooltip-text-number">
{feature.properties["Trained-Participants"] || "-"}
</span>
</li>
<li>
<img src={Person2} className="person-icon" /> Number of PSSM
instractors:{" "}
<span className="tooltip-text-number">
{feature.properties["PSSM-Instructors"] || "-"}
</span>
</li>
<li>
<img src={Person} className="person-icon" /> Number of senior PSSM
instractors:{" "}
<span className="tooltip-text-number">
{feature.properties["PSSM-Senior-Instructors"] || "-"}
</span>
</li>
</ul>
</div>
</Tooltip>
</Marker>
);
};
export default MarkerCustom;

View File

@ -1,16 +1,33 @@
import React from "react"; import React, { useEffect } from "react";
import ReactDOM from 'react-dom';
import { MapContainer, GeoJSON, Marker, Tooltip } from "react-leaflet"; import { MapContainer, GeoJSON, useMap } from "react-leaflet";
import L, { control } from "leaflet"; import L from "leaflet";
import Africa from "../../../Data/PSSM.geojson"; import Africa from "../../../Data/PSSM.geojson";
import "../../../Styles/main.scss"; import "../../../Styles/main.scss";
import Card_ from "../../UI/Card_/Card_"; import Card_ from "../../UI/Card_/Card_";
import { CountrySelectedStyle, NotPSSMCountryStyle } from "./countryStyles"; import { CountrySelectedStyle, NotPSSMCountryStyle } from "./countryStyles";
import MarkerCustom from "./MarkerCustom";
import SelectMenu from "./SelectMenu";
import Legend from "./Legend";
import Person from "../../../Icons/person.svg"; // Custom Zoom Control Component
import Person2 from "../../../Icons/person2.svg"; const CustomZoomControl = React.memo(() => {
import Person3 from "../../../Icons/person3.svg"; const map = useMap();
useEffect(() => {
const zoomControl = L.control.zoom({
position: 'topright' // Change the position to bottom right
});
map.addControl(zoomControl);
// Clean up the control on component unmount
return () => {
map.removeControl(zoomControl);
};
}, [map]);
return null;
});
class PSSM extends React.Component { class PSSM extends React.Component {
constructor(props) { constructor(props) {
@ -20,6 +37,8 @@ class PSSM extends React.Component {
africaCountries: null, africaCountries: null,
countriesNames: [], countriesNames: [],
pssmCountries: [], pssmCountries: [],
recsaCountries: [],
ecowasCountries: [],
loading: true, loading: true,
error: null, error: null,
selectedCountry: "", selectedCountry: "",
@ -27,6 +46,7 @@ class PSSM extends React.Component {
center: [3, 15], center: [3, 15],
zoom: 4, zoom: 4,
scrollWheelZoom: false, scrollWheelZoom: false,
zoomControl: false,
}; };
} }
@ -48,6 +68,12 @@ class PSSM extends React.Component {
(feature) => (feature) =>
feature.properties.RECSA === 1 || feature.properties.ECOWAS === 1 feature.properties.RECSA === 1 || feature.properties.ECOWAS === 1
), ),
recsaCountries: data.features.filter(
(feature) => feature.properties.RECSA === 1
),
ecowasCountries: data.features.filter(
(feature) => feature.properties.ECOWAS === 1
),
loading: false, loading: false,
}, },
() => {} () => {}
@ -58,8 +84,6 @@ class PSSM extends React.Component {
loading: false, loading: false,
}); });
} }
console.log(this.state.pssmCountries);
}; };
onEachFeature = (feature, layer) => { onEachFeature = (feature, layer) => {
@ -82,14 +106,26 @@ class PSSM extends React.Component {
this.setState({ selectedCountry: countryName }); this.setState({ selectedCountry: countryName });
}; };
handleCountryChange = (e) => {
const countryName = e.target.value;
const { selectedCountry } = this.state;
if (countryName === selectedCountry) {
this.setState({ selectedCountry: "" });
return;
}
this.setState({ selectedCountry: countryName });
};
render() { render() {
const { const {
africaCountries, africaCountries,
countriesNames,
pssmCountries, pssmCountries,
loading, loading,
error, error,
selectedCountry, selectedCountry,
recsaCountries,
ecowasCountries,
zoomControl,
} = this.state; } = this.state;
if (loading) { if (loading) {
return <div>Loading...</div>; return <div>Loading...</div>;
@ -105,6 +141,7 @@ class PSSM extends React.Component {
zoom={this.state.zoom} zoom={this.state.zoom}
style={{ width: "100%", height: "100%" }} style={{ width: "100%", height: "100%" }}
scrollWheelZoom={this.state.scrollWheelZoom} scrollWheelZoom={this.state.scrollWheelZoom}
zoomControl={zoomControl}
> >
{africaCountries && ( {africaCountries && (
<> <>
@ -137,39 +174,24 @@ class PSSM extends React.Component {
pssmCountries.map((feature) => { pssmCountries.map((feature) => {
if (feature.properties.name === selectedCountry) { if (feature.properties.name === selectedCountry) {
return ( return (
<Marker <MarkerCustom
key={feature.properties.name} key={feature.properties.name}
position={[feature.properties.y, feature.properties.x]} feature={feature}
> ></MarkerCustom>
<Tooltip
direction="bottom"
offset={[-13, 27]}
opacity={1}
permanent
className="tooltip-custom"
>
<h5>{feature.properties.name}</h5>
<div>
<ul className="list-unstyled tooltip-text">
<li>
<img src={Person3} className="person-icon"/> Number of participants trained:{" "}
<span className="tooltip-text-number">{feature.properties["Trained-Participants"] || "-"}</span>
</li>
<li>
<img src={Person2} className="person-icon"/> Number of PSSM instractors:{" "}
<span className="tooltip-text-number">{feature.properties["PSSM-Instructors"] || "-"}</span>
</li>
<li>
<img src={Person} className="person-icon"/> Number of senior PSSM instractors:{" "}
<span className="tooltip-text-number">{feature.properties["PSSM-Senior-Instructors"] || "-"}</span>
</li>
</ul>
</div>
</Tooltip>
</Marker>
); );
} }
})} })}
<CustomZoomControl />
<SelectMenu
ecowasCountries={ecowasCountries}
recsaCountries={recsaCountries}
selectedCountry={selectedCountry}
handleCountryChange={this.handleCountryChange}
></SelectMenu>
<Legend />
</MapContainer> </MapContainer>
</Card_> </Card_>
); );

View File

@ -0,0 +1,37 @@
import React from "react";
const SelectMenu = (props) => {
const {
ecowasCountries,
recsaCountries,
selectedCountry,
handleCountryChange,
} = props;
return (
<div className="country-select">
<select onChange={handleCountryChange} value={selectedCountry}>
<option value="">Select a country</option>
<option className="options-title" value="" disabled>
<h2>RECSA</h2>
</option>
{recsaCountries.map((feature, index) => (
<option className="" key={feature.properties.name} value={feature.properties.name}>
{feature.properties.name}
</option>
))}
<option className="options-title" value="" disabled>
ECOWAS
</option>
{ecowasCountries.map((feature, index) => (
<option className="" key={feature.properties.name} value={feature.properties.name}>
{feature.properties.name}
</option>
))}
</select>
</div>
);
};
export default SelectMenu;

View File

@ -0,0 +1,36 @@
.legend-container {
display: flex;
flex-direction: column;
font-size: 16px;
font-weight: bold;
position: absolute;
bottom: 20px;
left: 20px;
background-color: #f0f0f0;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 1000;
}
.legend-item {
display: flex;
align-items: center;
margin-bottom: 8px; /* Adjust as needed */
}
.legend-recsa,
.legend-ecowas {
width: 30px; /* Adjust width as needed */
height: 15px; /* Adjust height as needed */
margin-right: 8px; /* Adjust space between div and span as needed */
}
.legend-recsa {
background-color: #ffffcc; /* Replace with your color */
}
.legend-ecowas {
background-color: #ffcccd; /* Replace with your color */
}

View File

@ -9,4 +9,18 @@
.person-icon{ .person-icon{
height: 1.3rem; height: 1.3rem;
}
.country-select option{
font-size: 14px;
}
.options-title{
font-size: 20px !important;
font-weight: bold;
color: $primary-accent-color;
}
.options-title-recsa{
color: #ffffcc;
}
.options-title-ecowas{
color: #ffcccd;
} }

View File

@ -16,6 +16,8 @@
@import 'Layout/info_section'; @import 'Layout/info_section';
@import 'Layout/_map_info_box'; @import 'Layout/_map_info_box';
@import 'Layout/_map_info_box2'; @import 'Layout/_map_info_box2';
@import 'Layout/_legend';
// Import other layout partials... // Import other layout partials...
// Components // Components