Skip to content

Commit 69d271e

Browse files
committed
refactor: move about into new module, separate AboutSection
1 parent 2ce92d6 commit 69d271e

File tree

3 files changed

+152
-490
lines changed

3 files changed

+152
-490
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { useSelector } from 'react-redux';
4+
import { Helmet } from 'react-helmet';
5+
import { useTranslation } from 'react-i18next';
6+
import { Link } from 'react-router-dom';
7+
8+
import {
9+
AboutContent,
10+
IntroSection,
11+
IntroSectionContent,
12+
IntroSectionDescription,
13+
Section,
14+
SectionContainer,
15+
SectionItem,
16+
ContactSection,
17+
ContactSectionTitle,
18+
ContactSectionDetails,
19+
Footer
20+
} from '../About.styles';
21+
22+
import { ContactSectionLinks, AboutSectionInfo } from '../statics/aboutData';
23+
import Nav from '../../IDE/components/Header/Nav';
24+
import RootPage from '../../../components/RootPage';
25+
import packageData from '../../../../package.json';
26+
import HeartIcon from '../../../images/heart.svg';
27+
import AsteriskIcon from '../../../images/p5-asterisk.svg';
28+
import LogoIcon from '../../../images/p5js-square-logo.svg';
29+
30+
const AboutSection = ({ section, t }) => (
31+
<Section>
32+
<h2>{t(section.header)}</h2>
33+
<SectionContainer>
34+
{section.items.map((item) => (
35+
<SectionItem key={item.url}>
36+
<AsteriskIcon aria-hidden="true" focusable="false" />
37+
<div>
38+
<a href={item.url} target="_blank" rel="noopener noreferrer">
39+
{t(item.title)}
40+
</a>
41+
<p>{t(item.description)}</p>
42+
</div>
43+
</SectionItem>
44+
))}
45+
</SectionContainer>
46+
</Section>
47+
);
48+
49+
const About = () => {
50+
const { t } = useTranslation();
51+
52+
const p5version = useSelector((state) => {
53+
const index = state.files.find((file) => file.name === 'index.html');
54+
return index?.content.match(/\/p5\.js\/([\d.]+)\//)?.[1];
55+
});
56+
57+
return (
58+
<RootPage>
59+
<Helmet>
60+
<title> {t('About.TitleHelmet')} </title>
61+
</Helmet>
62+
63+
<Nav layout="dashboard" />
64+
65+
<AboutContent>
66+
<IntroSection>
67+
<h1>{t('About.Title')}</h1>
68+
<IntroSectionContent>
69+
<LogoIcon
70+
role="img"
71+
aria-label={t('Common.p5logoARIA')}
72+
focusable="false"
73+
/>
74+
<div>
75+
<p>{t('About.OneLine')}</p>
76+
</div>
77+
</IntroSectionContent>
78+
<IntroSectionDescription>
79+
<p>{t('About.Description1')}</p>
80+
<p>{t('About.Description2')}</p>
81+
</IntroSectionDescription>
82+
<a
83+
href="https://p5js.org/donate/"
84+
target="_blank"
85+
rel="noopener noreferrer"
86+
>
87+
<HeartIcon aria-hidden="true" focusable="false" />
88+
{t('About.Donate')}
89+
</a>
90+
</IntroSection>
91+
92+
{AboutSectionInfo.map((section) => (
93+
<AboutSection key={t(section.header)} section={section} t={t} />
94+
))}
95+
96+
<ContactSection>
97+
<h2>{t('Contact')}</h2>
98+
<div>
99+
<ContactSectionTitle>{t('About.Email')}</ContactSectionTitle>
100+
<ContactSectionDetails>
101+
{t('About.EmailAddress')}
102+
</ContactSectionDetails>
103+
</div>
104+
<div>
105+
<ContactSectionTitle>{t('About.Socials')}</ContactSectionTitle>
106+
<ContactSectionDetails>
107+
{ContactSectionLinks.map((item, index, array) => (
108+
<React.Fragment key={item.href}>
109+
<a href={item.href} target="_blank" rel="noopener noreferrer">
110+
{t(item.label)}
111+
</a>
112+
{index < array.length - 1 && ', '}
113+
</React.Fragment>
114+
))}
115+
</ContactSectionDetails>
116+
</div>
117+
</ContactSection>
118+
119+
<Footer>
120+
<div>
121+
<Link to="/privacy-policy">{t('About.PrivacyPolicy')}</Link>
122+
<Link to="/terms-of-use">{t('About.TermsOfUse')}</Link>
123+
<Link to="/code-of-conduct">{t('About.CodeOfConduct')}</Link>
124+
</div>
125+
<p>
126+
{t('About.WebEditor')}: <span>v{packageData?.version}</span>
127+
</p>
128+
<p>
129+
p5.js: <span>v{p5version}</span>
130+
</p>
131+
</Footer>
132+
</AboutContent>
133+
</RootPage>
134+
);
135+
};
136+
137+
AboutSection.propTypes = {
138+
section: PropTypes.shape({
139+
header: PropTypes.string.isRequired,
140+
items: PropTypes.arrayOf(
141+
PropTypes.shape({
142+
url: PropTypes.string.isRequired,
143+
title: PropTypes.string.isRequired,
144+
description: PropTypes.string.isRequired
145+
})
146+
).isRequired
147+
}).isRequired,
148+
t: PropTypes.func.isRequired
149+
};
150+
151+
export default About;

0 commit comments

Comments
 (0)