Skip to content

Commit 1031bf4

Browse files
Merge pull request #169 from HaudinFlorence/use_a_dialog_for_the_large_portrait_card
Use a dialog to display the LargePortraitCard.
2 parents 4b4d0d8 + fcf6cf7 commit 1031bf4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+9269
-1026
lines changed

package-lock.json

Lines changed: 572 additions & 340 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
"@fortawesome/free-brands-svg-icons": "^6.5.1",
3131
"@fortawesome/free-regular-svg-icons": "^6.5.1",
3232
"@mdx-js/react": "^3.0.0",
33+
"@mui/material": "^6.1.5",
34+
"@mui/styles": "^6.1.5",
3335
"autoprefixer": "^10.4.19",
3436
"canvas": "^2.11.2",
3537
"clsx": "^2.0.0",
@@ -47,8 +49,9 @@
4749
"react-bootstrap": "^2.10.4",
4850
"react-dom": "^18.0.0",
4951
"react-markdown": "^9.0.1",
52+
"react-router": "^5.3.4",
53+
"react-router-dom": "^5.3.4",
5054
"react-slick": "^0.30.2",
51-
"reactjs-popup": "^2.0.6",
5255
"request": "^2.88.2",
5356
"rss": "^1.2.2",
5457
"sharp": "^0.34.2",

src/components/about/LargePortraitCard.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,28 @@ import React from "react";
66
import Avatar from "./Avatar";
77

88
export function Distinction({ person }) {
9-
if (person.distinctionTitle.length !== 0) {
10-
return person.distinctionTitle.map((distinction, index) => (
11-
<div key={index}>
12-
<Link href={person.distinctionLink[index]}>
13-
<DistinctionIcon className={styles.distinction_icon} />
14-
{distinction}
15-
</Link>
16-
</div>
17-
));
18-
} else return <div></div>;
9+
const HasPersonDistinction = person.distinctionTitle.length !== 0;
10+
11+
return (
12+
<div>
13+
{HasPersonDistinction ? (
14+
<ul style={{paddingLeft: "0px"}}>
15+
{person.distinctionTitle.map((distinction, index) => (
16+
<li className="items-list" key={person.pageName}>
17+
<div>
18+
<Link href={person.distinctionLink[index]}>
19+
<DistinctionIcon className={styles.distinction_icon} />
20+
{distinction}
21+
</Link>
22+
</div>
23+
</li>
24+
))}
25+
</ul>
26+
) : null}
27+
</div>
28+
);
1929
}
30+
2031
export default function LargePortraitCard({ person }) {
2132
return (
2233
<div className={styles.large_portrait_card}>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import React from 'react';
2+
import Layout from '@theme/Layout';
3+
import { useHistory, useLocation } from '@docusaurus/router';
4+
import { useEffect } from 'react';
5+
import { Route } from 'react-router-dom';
6+
import { About } from '@site/src/components/about'
7+
import LargePortraitCard from '@site/src/components/about/LargePortraitCard';
8+
import { getTeamByPageName } from '@site/src/components/about';
9+
import styles from "@site/src/components/about/styles.module.css";
10+
11+
export default function LargePortraitCardPage() {
12+
const location = useLocation();
13+
const history = useHistory();
14+
15+
useEffect(() => {
16+
if (location.state?.fromAbout) {
17+
window.scrollTo({ top: location.state.scrollY ?? 0, behavior: 'auto' });
18+
}
19+
}, []);
20+
21+
const handleOverlayClick = () => {
22+
const scrollY = location.state?.scrollY;
23+
setTimeout(() => {
24+
if (scrollY !== undefined) {
25+
window.scrollTo({ top: scrollY, behavior: 'auto' });
26+
}
27+
}, 0);
28+
history.replace('/about');
29+
};
30+
31+
const handleClose = () => {
32+
const scrollY = location.state?.scrollY;
33+
if (location.state?.fromAbout) {
34+
history.replace('/about');
35+
36+
setTimeout(() => {
37+
if (scrollY !== undefined) {
38+
window.scrollTo({ top: scrollY, behavior: 'auto' });
39+
}
40+
}, 0);
41+
} else {
42+
history.goBack();
43+
}
44+
}
45+
return (
46+
<Layout>
47+
<About />
48+
<Route
49+
path="/about/:pageName"
50+
render={({ match }) => {
51+
const { pageName } = match.params; /* extract the dynamic part from the url i.e. the pageName*/
52+
const teamMembers = getTeamByPageName(pageName);
53+
const person = teamMembers.find((person) => person.pageName== pageName);
54+
if (!person) return null;
55+
56+
return (
57+
<div className={styles.modal_overlay} onClick={handleOverlayClick}>
58+
<div
59+
className={styles.modal_content}
60+
onClick={(e) => e.stopPropagation()}
61+
>
62+
<button
63+
className="close-button"
64+
style={{
65+
position: "absolute",
66+
top: "10px",
67+
right: "10px",
68+
}}
69+
onClick={handleClose}
70+
/>
71+
<LargePortraitCard person={person} />
72+
</div>
73+
</div>
74+
);
75+
}}
76+
/>
77+
</Layout>
78+
)
79+
}
80+
Lines changed: 30 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,42 @@
11
import styles from "./styles.module.css";
2-
import Popup from "reactjs-popup";
3-
import SocialMediaContacts from "./SocialMediaContacts";
4-
import { useRef, useState } from "react";
5-
import LargePortraitCard from "./LargePortraitCard";
2+
import { useHistory } from "@docusaurus/router";
63
import Avatar from "./Avatar";
74

8-
const contentStyle = {
9-
background: "white",
10-
borderRadius: "10px",
11-
};
5+
export function SmallPortraitCard({ person }) {
6+
const history = useHistory();
127

13-
const overlayStyle = {
14-
backgroundColor: "var(--ifm-background-color-popup-overlay)",
15-
opacity: "0.4",
16-
width: "100%",
17-
height: "100%",
18-
};
19-
20-
function getCenterOfViewport() {
21-
let horizontalCenter = Math.floor(window.innerWidth / 2);
22-
let verticalCenter = Math.floor(window.innerHeight / 2);
23-
return [horizontalCenter, verticalCenter];
24-
}
25-
26-
function calculateOffsets(elementRef) {
27-
const rect = elementRef.current.getBoundingClientRect();
28-
const [xViewportCenter, yViewportCenter] = getCenterOfViewport();
29-
const [xCardCenter, yCardCenter] = [
30-
rect.left + rect.width / 2,
31-
rect.top + rect.height / 2,
32-
];
33-
const offsets = [
34-
xViewportCenter - xCardCenter,
35-
yViewportCenter - yCardCenter,
36-
];
37-
return offsets;
38-
}
39-
40-
export function SmallPortraitCard({ person, setOffsets }) {
41-
const elementRef = useRef(null);
8+
function openDialog() {
9+
const completeName = person.completeName.replace(/\s+/g, '');
10+
const completeNameWithoutAccents = completeName
11+
.normalize("NFD")
12+
.replace(/[\u0300-\u036f]/g, '');
13+
history.push({
14+
pathname: `/about/${completeNameWithoutAccents}`,
15+
state: { fromAbout: true, scrollY: window.scrollY, },
16+
});
17+
}
4218

4319
return (
44-
<div
45-
ref={elementRef}
46-
className={"card" + " " + styles.small_portrait_card}
47-
id={person.firstName}
48-
onClick={() => {
49-
setOffsets(calculateOffsets(elementRef));
50-
}}
51-
>
52-
<div className="card__header">
53-
<Avatar person={person} />
54-
<div
55-
className={
56-
"flex-full-centered" + " " + styles.small_card_complete_name
57-
}
58-
>
59-
{person.completeName}
60-
</div>
61-
</div>
62-
<div className="card__body">
63-
<div
64-
className={"flex-full-centered" + " " + styles.small_card_position}
65-
>
66-
{person.position}
67-
</div>
68-
<div style={{ marginTop: "var(--ifm-spacing-xl)" }}>
69-
<SocialMediaContacts person={person}></SocialMediaContacts>
20+
<div onClick={openDialog}>
21+
<div className={"card" + " " + styles.small_portrait_card}>
22+
<div className="card__header">
23+
<Avatar person={person} />
24+
<div
25+
className={
26+
"flex-full-centered" + " " + styles.small_card_complete_name
27+
}
28+
>
29+
{person.completeName}
30+
</div>
7031
</div>
71-
</div>
72-
</div>
73-
);
74-
}
75-
export default function PopupPortrait({ person }) {
76-
const [offsets, setOffsets] = useState([0, 0]);
77-
let [isPopupOpen, setIsPopupOpen] = useState(false);
78-
79-
return (
80-
<div>
81-
<Popup
82-
open={isPopupOpen}
83-
closeOnEscape={true}
84-
closeOnDocumentClick={true}
85-
onClose={() => setIsPopupOpen(false)}
86-
trigger={
87-
<div>
88-
<SmallPortraitCard person={person} setOffsets={setOffsets} />
32+
<div className="card__body">
33+
<div
34+
className={"flex-full-centered" + " " + styles.small_card_position}
35+
>
36+
{person.position}
8937
</div>
90-
}
91-
onOpen={() => {
92-
setIsPopupOpen(true);
93-
}}
94-
contentStyle={contentStyle}
95-
overlayStyle={overlayStyle}
96-
position={"center center"}
97-
offsetX={offsets[0]}
98-
offsetY={offsets[1]}
99-
>
100-
<div>
101-
<button
102-
className="close-button"
103-
style={{ position: "absolute", right: "0px" }}
104-
onClick={() => {
105-
setIsPopupOpen(false);
106-
}}
107-
></button>
108-
<LargePortraitCard person={person}></LargePortraitCard>
10938
</div>
110-
</Popup>
39+
</div>
11140
</div>
11241
);
11342
}

src/components/about/SubTeam.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
import styles from "./styles.module.css";
2-
import PopupPortrait from "./SmallPortraitCard";
2+
import { SmallPortraitCard } from "./SmallPortraitCard";
33

4-
export default function SubTeam({
5-
subTeamName,
6-
subTeam
7-
}) {
4+
export default function SubTeam({ subTeamName, subTeam }) {
85
return (
96
<div className={styles.subteam_container}>
107
<h2 className={"text--center"}> {subTeamName}</h2>
118
<div className={"container"}>
129
<ul className="row padding-none flex-full-centered row-with-margin-top">
1310
{subTeam.map((person, index) => (
14-
<li className="cards-list" key={index}>
11+
<li className="cards-list" key={person.pageName}>
1512
<div className="col">
16-
<PopupPortrait
17-
person={person}
18-
/>
13+
<SmallPortraitCard person={person} />
1914
</div>
2015
</li>
2116
))}

0 commit comments

Comments
 (0)