📄 Projects.js
/home/palash/git/site/node_modules/new_site/src/components/Projects.js
Language: js • Lines: 120
import 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>
    </>
}