Create new components to reduce code duplication
This commit is contained in:
parent
aa8c9ce317
commit
36db4c2c0c
1 changed files with 79 additions and 53 deletions
132
src/Body.tsx
132
src/Body.tsx
|
@ -1,5 +1,7 @@
|
|||
import "./style.css";
|
||||
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
import hero from "./assets/MichaelBradley.jpeg?format=avif;webp;jpeg&as=picture";
|
||||
|
||||
import CV from "./assets/cv.svg?react";
|
||||
|
@ -20,6 +22,64 @@ type ColouredLineProps = {
|
|||
light: boolean;
|
||||
};
|
||||
|
||||
const ProfilePicture = () => (
|
||||
<div id="michael-photo-container">
|
||||
<picture>
|
||||
{Object.entries(hero.sources).map(([format, src]) => (
|
||||
<source srcSet={src} type={`image/${format}`} key={format} />
|
||||
))}
|
||||
<img src={hero.img.src} alt="A picture of me in a suit smiling" id="michael-photo" />
|
||||
</picture>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Highlight = ({ children }: PropsWithChildren) => <span className="text-highlight">{children}</span>;
|
||||
|
||||
type FetchHeaderProps = {
|
||||
user: string;
|
||||
hostname: string;
|
||||
};
|
||||
|
||||
const FetchHeader = ({ user, hostname }: FetchHeaderProps) => (
|
||||
<>
|
||||
<p>
|
||||
<Highlight>{user}</Highlight>@<Highlight>{hostname}</Highlight>
|
||||
</p>
|
||||
<p>{"-".repeat(user.length + 1 + hostname.length)}</p>
|
||||
</>
|
||||
);
|
||||
|
||||
type InfoLineProps = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
const InfoLine = ({ label, value }: InfoLineProps) => (
|
||||
<p>
|
||||
<span className="text-highlight">{label}</span>: {value}
|
||||
</p>
|
||||
);
|
||||
|
||||
const BlankLine = () => (
|
||||
<p>
|
||||
<br />
|
||||
</p>
|
||||
);
|
||||
|
||||
const Description = () => (
|
||||
<div className="invisible-div">
|
||||
<FetchHeader user="website" hostname="MichaelBradley" />
|
||||
<InfoLine label="Degree" value="Bachelor of Computer Science" />
|
||||
<InfoLine label="University" value="Carleton" />
|
||||
<InfoLine label="Major CGPA" value="11.52/12 (A+)" />
|
||||
<InfoLine label="Languages" value="C/C++, Python, TypeScript" />
|
||||
<InfoLine label="Skills" value="Linux, Git, Testing" />
|
||||
<InfoLine label="Work Experience" value="2 years" />
|
||||
<InfoLine label="Applying for" value="Full-time job" />
|
||||
<InfoLine label="Location" value="Toronto or Remote" />
|
||||
</div>
|
||||
);
|
||||
|
||||
const ColouredLine = ({ light }: ColouredLineProps) => {
|
||||
const startIndex = light ? 8 : 0;
|
||||
return (
|
||||
|
@ -41,48 +101,10 @@ const Fetch = () => {
|
|||
return (
|
||||
<div id="fetch-container">
|
||||
<div id="fetch">
|
||||
<div id="michael-photo-container">
|
||||
<picture>
|
||||
{Object.entries(hero.sources).map(([format, src]) => (
|
||||
<source srcSet={src} type={`image/${format}`} key={format} />
|
||||
))}
|
||||
<img src={hero.img.src} alt="A picture of me in a suit smiling" id="michael-photo" />
|
||||
</picture>
|
||||
</div>
|
||||
<ProfilePicture />
|
||||
<div id="basic-info">
|
||||
<div className="invisible-div">
|
||||
<p>
|
||||
<span className="text-highlight">website</span>@<span className="text-highlight">MichaelBradley</span>
|
||||
</p>
|
||||
<p>----------------------</p>
|
||||
<p>
|
||||
<span className="text-highlight">Degree</span>: Bachelor of Computer Science
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">University</span>: Carleton
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Major CGPA</span>: 11.52/12 (A+)
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Languages</span>: C/C++, Python, TypeScript
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Skills</span>: Linux, Git, Testing
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Work Experience</span>: 2 years
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Applying for</span>: Full-time job
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Location</span>: Toronto or Remote
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<br />
|
||||
</p>
|
||||
<Description />
|
||||
<BlankLine />
|
||||
<ColouredLine light={false} />
|
||||
<ColouredLine light={true} />
|
||||
</div>
|
||||
|
@ -91,20 +113,24 @@ const Fetch = () => {
|
|||
);
|
||||
};
|
||||
|
||||
type ImageLinkProps = {
|
||||
href: string;
|
||||
title: string;
|
||||
Image: typeof Git; // Not ideal, but I can't figure out how to import the type directly from the declared wildcard module
|
||||
};
|
||||
|
||||
const ImageLink = ({ href, title, Image }: ImageLinkProps) => (
|
||||
<a rel="me" href={href} title={title}>
|
||||
<Image width="100%" />
|
||||
</a>
|
||||
);
|
||||
|
||||
const Links = () => (
|
||||
<div className="links">
|
||||
<a href="https://git.mmbradley.ca/MichaelBradley" title="Forgejo instance">
|
||||
<Git width="100%" />
|
||||
</a>
|
||||
<a href="https://www.linkedin.com/in/michaelmbradley/" title="LinkedIn account">
|
||||
<LinkedIn width="100%" />
|
||||
</a>
|
||||
<a href="https://mmbradley.ca/resume.pdf" title="My Résumé">
|
||||
<CV width="100%" />
|
||||
</a>
|
||||
<a rel="me" href="https://mstdn.ca/@michaelbradley" title="Mastodon account">
|
||||
<Mastodon width="100%" />
|
||||
</a>
|
||||
<ImageLink href="https://git.mmbradley.ca/MichaelBradley/" title="Forgejo instance" Image={Git} />
|
||||
<ImageLink href="https://www.linkedin.com/in/michaelmbradley/" title="LinkedIn account" Image={LinkedIn} />
|
||||
<ImageLink href="https://mmbradley.ca/resume.pdf" title="My Résumé" Image={CV} />
|
||||
<ImageLink href="https://mstdn.ca/@michaelbradley/" title="Mastodon account" Image={Mastodon} />
|
||||
<input id="dark-mode-toggle" type="checkbox" aria-label="Toggle dark mode" />
|
||||
<label htmlFor="dark-mode-toggle" id="dark-mode-toggle-label" title="Toggle dark mode">
|
||||
<DarkModeToggleIcon width="100%" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue