PSSM Pictures Gallery

This commit is contained in:
louai98 2024-06-11 15:20:43 +02:00
parent f2c0c1ab3c
commit cc6300ff99
25 changed files with 229 additions and 29 deletions

View File

@ -1,10 +1,9 @@
import React from "react"; import React from "react";
import { BrowserRouter as Router, Route, Link, Switch, Routes } from "react-router-dom"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Container from "react-bootstrap/Container"; import Container from "react-bootstrap/Container";
import Nav from "react-bootstrap/Nav"; import Nav from "react-bootstrap/Nav";
import Navbar from "react-bootstrap/Navbar"; import Navbar from "react-bootstrap/Navbar";
import NavDropdown from "react-bootstrap/NavDropdown";
import Home from "../../Pages/Home"; import Home from "../../Pages/Home";
import About from "../../Pages/About"; import About from "../../Pages/About";
import ControlInAfrica from "../../Pages/ControlInAfrica"; import ControlInAfrica from "../../Pages/ControlInAfrica";
@ -14,16 +13,17 @@ const NavBarSalw = () => {
return ( return (
<> <>
<Router> <Router>
<Navbar expand="lg" className="bg-body-tertiary"> <Navbar expand="lg" className="bg-body-tertiary nav-bar">
<Container> <Container fluid className="ps-5">
<Navbar.Brand href="#home">SALW Guide</Navbar.Brand> <Navbar.Brand className="nav-bar-title" href="#home">SALW Guide |</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav"> <Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto"> <Nav className="me-auto">
<Nav.Link href="home">Home</Nav.Link> <Nav.Link className="nav-bar-item" href="home">Home</Nav.Link>
<Nav.Link href="ControlInAfrica">SALW Control in Africa</Nav.Link> <Nav.Link className="nav-bar-item" href="ControlInAfrica">SALW Control in Africa</Nav.Link>
<Nav.Link href="pssm">PSSM</Nav.Link> <Nav.Link className="nav-bar-item" href="pssm">PSSM</Nav.Link>
<Nav.Link href="about">About</Nav.Link> <Nav.Link className="nav-bar-item" href="about">About</Nav.Link>
</Nav> </Nav>
</Navbar.Collapse> </Navbar.Collapse>
</Container> </Container>

View File

@ -2,7 +2,6 @@ import React, { useState } from "react";
import Card_ from "../../UI/Card_/Card_"; 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 Collapse from "react-bootstrap/Collapse"; import Collapse from "react-bootstrap/Collapse";
const Blurb = () => { const Blurb = () => {
@ -30,14 +29,14 @@ const Blurb = () => {
]); ]);
return ( return (
<Card_ className="p-3"> <Card_ className="blurb p-3">
<MainText footnotes={footnotes} /> <MainText footnotes={footnotes} />
</Card_> </Card_>
); );
}; };
const MainText = ({ footnotes }) => { const MainText = ({ footnotes }) => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(true);
const [isHidden, setIsHidden] = useState(true); const [isHidden, setIsHidden] = useState(true);
return ( return (
<div> <div>
@ -157,14 +156,17 @@ const MainText = ({ footnotes }) => {
</div> </div>
</div> </div>
</Collapse> </Collapse>
<a {/* <a
href="#" href="#"
onClick={() => {setOpen(!open); setIsHidden(!isHidden);}} onClick={() => {
setOpen(!open);
setIsHidden(!isHidden);
}}
aria-controls="example-collapse-text" aria-controls="example-collapse-text"
aria-expanded={open} aria-expanded={open}
> >
{isHidden ? "Read more" : "Read less"} {isHidden ? "Read more" : "Read less"}
</a> </a> */}
</div> </div>
); );
}; };

View File

@ -0,0 +1,53 @@
import React, { useState } from "react";
import images from "./ImportImages";
import Card_ from "../../UI/Card_/Card_";
const ImageGallery = () => {
const [selectedImage, setSelectedImage] = useState(null);
const handleThumbnailClick = (image) => {
setSelectedImage(image);
};
const handleCloseModal = () => {
setSelectedImage(null);
};
return (
<Card_ className="mt-3 p-3">
<div className="image-gallery">
{Object.keys(images).map((key, index) => (
<img
key={index}
src={images[key]}
alt={key}
className="thumbnail"
onClick={() => handleThumbnailClick(images[key])}
/>
))}
</div>
{selectedImage && (
<div className="modal" onClick={handleCloseModal}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
<span className="close" onClick={handleCloseModal}>
&times;
</span>
<img
src={selectedImage}
alt="Full Size"
className="full-size-image"
/>
</div>
</div>
)}
<div className="mt-3">
<p>
Pictures have been taken by ©Nikhil Achary, ©IPSTC/Kenya, ©MSAG AUT,
and ©Hans Lampalzer (BLMV).{" "}
</p>
</div>
</Card_>
);
};
export default ImageGallery;

View File

@ -0,0 +1,10 @@
import React from 'react'
import Card_ from '../../UI/Card_/Card_'
const ImpactStories = (props) => {
const {className} = props;
return (
<Card_ className={className}>ImpactStories</Card_>
)
}
export default ImpactStories

View File

@ -0,0 +1,12 @@
// src/importImages.js
function importAll(r) {
let images = {};
r.keys().map((item, index) => {
images[item.replace('./', '')] = r(item);
});
return images;
}
const images = importAll(require.context('../../../img/pssm', false, /\.(png|jpe?g|svg)$/));
export default images;

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react"; import React, { useEffect, createRef } from "react";
import { MapContainer, GeoJSON, useMap } from "react-leaflet"; import { MapContainer, GeoJSON, useMap } from "react-leaflet";
import L from "leaflet"; import L from "leaflet";
@ -16,7 +16,7 @@ const CustomZoomControl = React.memo(() => {
useEffect(() => { useEffect(() => {
const zoomControl = L.control.zoom({ const zoomControl = L.control.zoom({
position: 'topright' // Change the position to bottom right position: "topright", // Change the position to bottom right
}); });
map.addControl(zoomControl); map.addControl(zoomControl);
@ -33,6 +33,8 @@ class PSSM extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.mapRef = createRef(); // Create a ref to store the MapContainer instance
this.state = { this.state = {
africaCountries: null, africaCountries: null,
countriesNames: [], countriesNames: [],
@ -93,6 +95,22 @@ class PSSM extends React.Component {
}); });
}; };
resetMap = () => {
if (this.mapRef.current) {
this.mapRef.current.setView(this.state.center, this.state.zoom); // Set the center and zoom to initial values
}
};
zoomIn = () => {
if (this.mapRef.current) {
this.mapRef.current.setZoom(this.mapRef.current.getZoom() + 1);
}
};
zoomOut = () => {
if (this.mapRef.current) {
this.mapRef.current.setZoom(this.mapRef.current.getZoom() - 1);
}
};
onMouseClick = (e) => { onMouseClick = (e) => {
this.setState({ this.setState({
selectedCountriesFilter: [], selectedCountriesFilter: [],
@ -135,8 +153,9 @@ class PSSM extends React.Component {
} }
return ( return (
<Card_ id="map" className="map-container mt-3"> <Card_ id="map" className="map-container">
<MapContainer <MapContainer
ref={this.mapRef}
center={this.state.center} center={this.state.center}
zoom={this.state.zoom} zoom={this.state.zoom}
style={{ width: "100%", height: "100%" }} style={{ width: "100%", height: "100%" }}
@ -182,14 +201,19 @@ class PSSM extends React.Component {
} }
})} })}
<CustomZoomControl /> {/* <CustomZoomControl /> */}
<SelectMenu <div className="custom-zoom-control">
ecowasCountries={ecowasCountries} <button onClick={this.zoomIn}>+</button>
recsaCountries={recsaCountries} <button onClick={this.zoomOut}>-</button>
selectedCountry={selectedCountry} <button onClick={this.resetMap}>*</button>
handleCountryChange={this.handleCountryChange} </div>
></SelectMenu>
<SelectMenu
ecowasCountries={ecowasCountries}
recsaCountries={recsaCountries}
selectedCountry={selectedCountry}
handleCountryChange={this.handleCountryChange}
></SelectMenu>
<Legend /> <Legend />
</MapContainer> </MapContainer>

View File

@ -0,0 +1,10 @@
import React from 'react'
import Card_ from '../../UI/Card_/Card_';
const PssmResources = (props) => {
const {className} = props;
return (
<Card_ className={className}>PSSM Resources</Card_>
)
}
export default PssmResources

View File

@ -1,12 +1,28 @@
import React from "react"; import React from "react";
import Container from "react-bootstrap/Container"; import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import Blurb from "../Layout/PSSM/Blurb"; import Blurb from "../Layout/PSSM/Blurb";
import PSSM from "../Layout/PSSM/PSSM"; import PSSM from "../Layout/PSSM/PSSM";
import ImageGallery from "../Layout/PSSM/ImageGallery";
import ImpactStories from "../Layout/PSSM/ImpactStories";
import PssmResources from "../Layout/PSSM/PssmResources";
const Treaties = () => { const Treaties = () => {
return ( return (
<Container className="p-5"> <Container fluid className="p-5">
<Blurb></Blurb> <Row>
<PSSM></PSSM> <Col sm={7}>
<Blurb></Blurb>
<ImpactStories className="mt-3 p-3"></ImpactStories>
<PssmResources className="mt-3 p-3"></PssmResources>
</Col>
<Col sm={5}>
<PSSM></PSSM>
</Col>
</Row>
<Row>
<ImageGallery className="mt-3"></ImageGallery>
</Row>
</Container> </Container>
); );
}; };

View File

@ -0,0 +1,8 @@
.blurb {
width: 100%; /* Adjust the width as needed */
height: 50%; /* Adjust the height as needed */
overflow-y: auto;
border: 1px solid #ccc; /* Optional: Add a border for better visibility */
padding: 10px; /* Optional: Add some padding */
box-sizing: border-box; /* Ensure padding is included in the element's total width and height */
}

View File

@ -0,0 +1,13 @@
.nav-bar{
background-color: $primary-accent-color !important;
}
.nav-bar-title{
font-size: 26px;
}
.nav-bar-item{
font-size: 26px;
color: $primary-text-color;
margin-right: 10px;
}

View File

@ -0,0 +1,49 @@
.image-gallery {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.thumbnail {
width: 200px;
height: 200px;
object-fit: cover;
cursor: pointer;
transition: transform 0.2s;
}
.thumbnail:hover {
transform: scale(1.1);
}
.modal {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
}
.modal-content {
position: relative;
max-width: 90%;
max-height: 90%;
}
.close {
position: absolute;
top: 10px;
right: 10px;
color: white;
font-size: 30px;
cursor: pointer;
}
.full-size-image {
width: 100%;
height: auto;
}

View File

@ -17,6 +17,9 @@
@import 'Layout/_map_info_box'; @import 'Layout/_map_info_box';
@import 'Layout/_map_info_box2'; @import 'Layout/_map_info_box2';
@import 'Layout/_legend'; @import 'Layout/_legend';
@import 'Layout/_blurb';
@import 'Layout/_pssm_image_gallery';
@import 'Layout/_nav_bar';
// Import other layout partials... // Import other layout partials...

BIN
src/img/pssm/1000013063.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 KiB

BIN
src/img/pssm/1000013066.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB

BIN
src/img/pssm/1000013069.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

BIN
src/img/pssm/1000013072.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

BIN
src/img/pssm/1000013075.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

BIN
src/img/pssm/1000013078.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB

BIN
src/img/pssm/Image 1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
src/img/pssm/Opening 2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

BIN
src/img/pssm/bild.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB