js • Lines: 120import Card from 'react-bootstrap/Card';
import { Button, Col, Container, Modal, Row } from 'react-bootstrap';
import { IoGameControllerOutline } from 'react-icons/io5';
import { FaExternalLinkAlt, FaGithub, FaInfoCircle, FaJava, FaMarkdown, FaPython, FaReact, FaRust } from 'react-icons/fa';
import { useState } from 'react';
import Blog from './Blog';
import PageIntro from './PageIntro';
import { TbBrandJavascript } from 'react-icons/tb';
function ProjectModal(props) {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Card.Link variant="primary" onClick={handleShow}>
<FaInfoCircle />
</Card.Link>
<Modal show={show}
onHide={handleClose}
size="xl"
aria-labelledby="contained-modal-title-vcenter"
centered>
<Modal.Header closeButton>
<Modal.Title>{props.title}</Modal.Title>
</Modal.Header>
<Modal.Body style={{
maxHeight: 'calc(100vh - 210px)',
overflowY: 'auto'
}}>
<Blog contentType="swe" mdUrl={props.mdUrl} />
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
);
}
function ProjectCard(props) {
const { name, desc, playUrl, githubUrl, mdUrl, type } = props;
const getTechStackIcon = () => {
const title = window.findProp("techStack.title." + type);
const color = window.findProp("techStack.iconColor." + type);
switch (type) {
case "react":
return <FaReact color={color} title={title} />
case "java":
return <FaJava color={color} title={title} />
case "rust":
return <FaRust color={color} title={title} />
case "markdown":
return <FaMarkdown color={color} title={title} />
case "python":
return <FaPython color={color} title={title} />
case "javascript":
return <TbBrandJavascript color={color} title={title} />
default:
return <></>
}
}
return (
<Card className="h-100" style={{ width: '100%' }}>
<Card.Body>
<Card.Title className={window.findProp("pages.home.mainStyle")} style={{ color: window.findProp("pages.projects.titleColor") }}>{name}</Card.Title>
<Card.Text style={{ color: window.findProp("pages.projects.bodyColor") }}>{desc}</Card.Text>
<Card.Text>{window.findProp("pages.projects.techStack")}{getTechStackIcon()}</Card.Text>
</Card.Body>
<Card.Footer className="mt-auto">
<div className="d-flex flex-wrap gap-3 align-items-center">
{
playUrl ? <Card.Link href={playUrl} target={type === "react" ? '' : '_blank'}>
{type === "react" ? <IoGameControllerOutline /> : <FaExternalLinkAlt />}
</Card.Link> : <></>
}
{
githubUrl ? <Card.Link href={githubUrl} target={type === "react" ? '' : '_blank'}>
<FaGithub />
</Card.Link> : <></>
}
{
mdUrl ? <ProjectModal title={name} mdUrl={mdUrl} /> : <></>
}
</div>
</Card.Footer>
</Card>
);
}
export default function Projects() {
return <>
<Container fluid>
<PageIntro
h1={window.findProp("labels.projects")}
p={window.findProp("pages.projects.intro")}
h1Color={window.findProp("pages.projects.h1Color")}
pColor={window.findProp("pages.projects.pColor")}
/>
<Row xs={1} md={2} xl={3} className="g-4">
{(window.findProp("projects") || []).map(p => <Col key={p.id} className="d-flex">
<ProjectCard
name={p.name}
desc={p.desc}
playUrl={p.playUrl}
githubUrl={p.githubUrl}
mdUrl={p.mdUrl}
type={p.type}
iconColor={p.iconColor} />
</Col>)}
</Row>
</Container>
</>
}