Skip to content

Commit a202bc5

Browse files
update about-me
1 parent 0a37c96 commit a202bc5

File tree

12 files changed

+598
-6
lines changed

12 files changed

+598
-6
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@iconify-json/logos": "^1.1.37",
2727
"@mdx-js/react": "^1.6.22",
2828
"asciinema-player": "^3.4.0",
29+
"axios": "^1.7.7",
2930
"clsx": "^1.2.1",
3031
"grapheme-splitter": "^1.0.4",
3132
"hast-util-is-element": "1.1.0",
@@ -37,6 +38,7 @@
3738
"raw-loader": "^4.0.2",
3839
"react": "^17.0.2",
3940
"react-dom": "^17.0.2",
41+
"react-simple-maps": "^3.0.0",
4042
"react-type-animation": "^3.2.0",
4143
"rehype-katex": "5",
4244
"remark-math": "3",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react';
2+
import './BentoLayout.css';
3+
4+
interface BentoItemProps {
5+
rows?: string;
6+
columns?: string;
7+
content: React.ReactNode; // 接受卡片内容
8+
}
9+
10+
interface BentoContainerProps {
11+
variant: 'variant-1' | 'variant-2' | 'variant-3';
12+
items: BentoItemProps[]; // 每个 item 包含样式和内容
13+
}
14+
15+
const BentoContainer: React.FC<BentoContainerProps> = ({ variant, items }) => {
16+
return (
17+
<div className={`bento__container ${variant}`}>
18+
{items.map((item, index) => (
19+
<div
20+
key={index}
21+
className="bento__item"
22+
style={{
23+
'--rows': item.rows || 'span 1',
24+
'--columns': item.columns || 'span 1',
25+
} as React.CSSProperties}
26+
>
27+
{item.content} {/* 渲染卡片的内容 */}
28+
</div>
29+
))}
30+
</div>
31+
);
32+
};
33+
34+
export default BentoContainer;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
* {
2+
margin: 0;
3+
padding: 0;
4+
box-sizing: border-box;
5+
}
6+
7+
.bento {
8+
min-block-size: 100vh;
9+
display: flex;
10+
flex-wrap: wrap;
11+
gap: 1ch;
12+
padding: 3rem;
13+
}
14+
15+
.bento__container {
16+
display: grid;
17+
grid-template-rows: 3fr 1fr 1fr 2fr 1fr;
18+
gap: 1ch;
19+
min-height: inherit;
20+
flex: 2 0 320px;
21+
}
22+
23+
.bento__container.variant-1 {
24+
--bg: #DDEEF8;
25+
grid-template-columns: 3fr 1fr 2fr;
26+
}
27+
28+
.bento__container.variant-2 {
29+
--bg: #DDEEF8;
30+
grid-template-columns: 2fr 3fr 1fr 2fr;
31+
}
32+
33+
.bento__container.variant-3 {
34+
--bg: #DDEEF8;
35+
grid-template-columns: 1fr 1fr;
36+
}
37+
38+
.bento__item {
39+
height: 100%;
40+
width: 100%;
41+
grid-column: var(--columns, span 1);
42+
grid-row: var(--rows, span 1);
43+
background-color: var(--bg);
44+
border-radius: 10px;
45+
/* padding: 1rem; */
46+
align-items: center;
47+
align-content: center;
48+
}
49+
50+
[data-theme='dark'] .bento__item {
51+
background-color: #53627f;
52+
}

src/components/BentoLayout/index.tsx

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import React from 'react';
2+
import BentoContainer from './BentoContainer';
3+
import wwj from '@site/static/img/wwj-scenery.jpeg'
4+
import MapChart from './map';
5+
import Timeline from './timeline'
6+
import coffeecup from '@site/static/img/coffee-cup.png'
7+
8+
const BentoLayout: React.FC = () => {
9+
return (
10+
<main className="bento">
11+
{/* Variant 1 */}
12+
<BentoContainer
13+
variant="variant-1"
14+
items={[
15+
{
16+
rows: 'span 2',
17+
columns: '1 / -1',
18+
content: <div style={{ position: 'relative', alignContent: 'center', padding: '1rem' }}><h1>Hi there!</h1><h1>I'm Wenjie Wei.</h1><h3>A PhD student in biology.</h3><img
19+
src={coffeecup}
20+
alt="Profile"
21+
style={{
22+
position: 'absolute',
23+
top: '-120px', /* Moves the image slightly above the div */
24+
right: '-40px', /* Moves the image to the right, slightly outside the div */
25+
width: '200px', /* Adjust the image size */
26+
height: 'auto'
27+
}}
28+
/></div>
29+
},
30+
// {
31+
// rows: 'span 1',
32+
// columns: '1 / -1',
33+
// content: <div style={{ alignContent: 'center', padding: '1rem' }}><h4>I was born in 1999 in Shaoxing, China</h4></div>
34+
// },
35+
{
36+
rows: 'span 3',
37+
columns: '1 / -1',
38+
content: <div style={{ alignContent: 'center', padding: '1rem' }}><h4>I am currently in Hangzhou. You can fly to me like this👇🏻</h4><MapChart /></div>
39+
},
40+
// {
41+
// columns: '1 / -1',
42+
// content: <div><h3>card</h3><h3>card</h3></div>
43+
// },
44+
// {
45+
// columns: '1 / -1',
46+
// rows: 'span 2',
47+
// content: <div><h3>Card 5</h3></div>
48+
// },
49+
// {
50+
// content: <div><h3>Card 6</h3></div>
51+
// },
52+
]}
53+
/>
54+
55+
{/* Variant 2 */}
56+
<BentoContainer
57+
variant="variant-2"
58+
items={[
59+
{
60+
rows: 'span 1',
61+
columns: '1 / -1',
62+
content: <div style={{ alignContent: 'center', padding: '1rem' }}><h3>I enjoy contributing to the bioinformatics community.</h3><img src="https://github-readme-stats.vercel.app/api?username=wjwei-handsome&include_all_commits=true&theme=swift&show_icons=true" alt="github_stats" style={{ borderRadius: '10px', height: '100%' }} /> </div>
63+
},
64+
// {
65+
// columns: 'span 2',
66+
// content: <div><h3>Card B</h3></div>
67+
// },
68+
{
69+
rows: 'span 4',
70+
columns: '1 / -1',
71+
content: <img src={wwj} alt="Card C" style={{ borderRadius: '10px', height: '100%' }} />
72+
},
73+
// {
74+
// rows: 'span 4',
75+
// columns: '1 / -1',
76+
// content: <div><h3>Card D</h3></div>
77+
// },
78+
// {
79+
// rows: 'span 1',
80+
// columns: '1 / -1',
81+
// content: <div><h3>Card E</h3></div>
82+
// },
83+
// {
84+
// columns: '1 / -1',
85+
// rows: 'span 2',
86+
// content: <div><h3>Card F</h3></div>
87+
// },
88+
]}
89+
/>
90+
91+
{/* Variant 3 */}
92+
<BentoContainer
93+
variant="variant-3"
94+
items={[
95+
{
96+
rows: 'span 1',
97+
columns: '1 / -1',
98+
content: <div style={{ alignContent: 'center', padding: '1rem' }}><h3>I'm still learning these languages</h3><img src="https://github-readme-stats.vercel.app/api/top-langs/?username=wjwei-handsome&layout=compact&theme=swift" alt="Card 2" style={{ borderRadius: '10px', height: '100%', alignContent: 'center' }} /></div>
99+
},
100+
// {
101+
// rows: 'span 3',
102+
// content: <div><h3>Card Y</h3></div>
103+
// },
104+
{
105+
rows: 'span 4',
106+
columns: '1 / -1',
107+
content: <div><Timeline /></div>
108+
},
109+
// {
110+
// columns: '1 / -1',
111+
// content: <div><h3>Card W</h3><button>Click Here</button></div>
112+
// },
113+
// {
114+
// columns: '1 / -1',
115+
// content: <div><h3>Card V</h3></div>
116+
// },
117+
]}
118+
/>
119+
</main >
120+
);
121+
};
122+
123+
export default BentoLayout;

src/components/BentoLayout/map.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React, { useEffect, useState } from 'react';
2+
import axios from 'axios';
3+
import { ComposableMap, Geographies, Geography, Graticule, Line } from "react-simple-maps"
4+
5+
const geoUrl =
6+
"https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json"
7+
8+
export default function MapChart() {
9+
const [ip, setIp] = useState('');
10+
const [location, setLocation] = useState({ latitude: 0, longitude: 0 });
11+
12+
useEffect(() => {
13+
// Fetch the IP address
14+
const fetchIp = async () => {
15+
try {
16+
const response = await axios.get('https://api.ipify.org?format=json');
17+
setIp(response.data.ip);
18+
console.log(response.data);
19+
} catch (error) {
20+
console.error('Error fetching the IP address:', error);
21+
}
22+
};
23+
24+
fetchIp();
25+
}, []);
26+
27+
useEffect(() => {
28+
// Fetch the location
29+
const fetchLocation = async () => {
30+
try {
31+
const response = await axios.get(`http://ip-api.com/json/${ip}?fields=lat,lon`);
32+
setLocation({ latitude: response.data.lat, longitude: response.data.lon });
33+
console.log(response.data);
34+
} catch (error) {
35+
console.error('Error fetching the location:', error);
36+
}
37+
};
38+
39+
if (ip) {
40+
fetchLocation();
41+
}
42+
}, [ip]);
43+
44+
return (
45+
<ComposableMap projection="geoAzimuthalEqualArea" projectionConfig={{
46+
scale: 200,
47+
rotate: [-90, -30, 0],
48+
center: [0, 0]
49+
}}>
50+
<Graticule stroke="#DDD" />
51+
<Geographies geography={geoUrl}>
52+
{({ geographies }) =>
53+
geographies.map((geo) => (
54+
<Geography key={geo.rsmKey} geography={geo} fill="#FFFFFF"
55+
stroke="#000000" />
56+
))
57+
}
58+
</Geographies>
59+
<Line
60+
to={[120.153576, 30.287459]}
61+
from={[location.latitude, location.longitude]}
62+
stroke="#FF5533"
63+
strokeWidth={4}
64+
strokeLinecap="round"
65+
/>
66+
</ComposableMap>
67+
)
68+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
.timeline-item {
2+
display: flex;
3+
align-items: center;
4+
/* Aligns the year and content along the vertical center */
5+
margin: 3cqb 0;
6+
position: relative;
7+
}
8+
9+
.timeline-year {
10+
font-size: 18px;
11+
font-weight: bold;
12+
margin-right: 40px;
13+
width: 80px;
14+
text-align: right;
15+
flex-shrink: 0;
16+
}
17+
18+
.timeline-content {
19+
width: 200px;
20+
/* Fixed width for content */
21+
height: 100%;
22+
/* Fixed height for content */
23+
padding: 10px 20px;
24+
background: #f4f4f9;
25+
border-radius: 8px;
26+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
27+
display: flex;
28+
flex-direction: column;
29+
justify-content: center;
30+
align-items: center;
31+
text-align: center;
32+
word-wrap: break-word;
33+
/* Break long words into new lines */
34+
white-space: normal;
35+
/* Allow text to wrap to the next line */
36+
overflow: hidden;
37+
/* Prevent overflow outside the box */
38+
}
39+
40+
.timeline {
41+
display: flex;
42+
flex-direction: column;
43+
align-items: flex-start;
44+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import './timeline.css'; // Importing CSS for styling
3+
4+
const Timeline = () => {
5+
const events = [
6+
{ year: '2017', title: 'HZAU', subtitle: 'Plant Science and Technology' },
7+
{ year: '2021', title: 'HAZU', subtitle: 'Crop Genetics and Breeding (Maize)' },
8+
{ year: '2024', title: 'Westlake University', subtitle: 'Human Genomics/Genetics' },
9+
];
10+
return (
11+
<div className="timeline">
12+
{events.map((event, index) => (
13+
<div className="timeline-item" key={index}>
14+
<div className="timeline-year">{event.year}</div>
15+
<div className="timeline-content">
16+
<h4>{event.title}</h4>
17+
<p>{event.subtitle}</p>
18+
</div>
19+
</div>
20+
))}
21+
</div>
22+
);
23+
};
24+
25+
export default Timeline;
File renamed without changes.

0 commit comments

Comments
 (0)