Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@

- [COMPLETED] PORT-000 Preserve production and create `feat/portfolio-v2` from verified `main`.
- [COMPLETED] PORT-001 Establish recruiter-first V2 structure and Andrew Thompson branding.
- [COMPLETED] PORT-008 Add a compact verified education and credentials section.
2 changes: 2 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Footer from "./components/Footer";
import Header from "./components/Header";
import Experience from "./components/Experience";
import WorkMethod from "./components/WorkMethod";
import Certificates from "./components/Certificates";

export default function App() {
return (
Expand All @@ -19,6 +20,7 @@ export default function App() {
<About />
<Experience />
<Skills />
<Certificates />
<Contact />
<Footer />
</Layout>
Expand Down
48 changes: 48 additions & 0 deletions src/components/Certificates.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { FiAward, FiExternalLink } from "react-icons/fi";
import Section from "../layout/Section";

const credentials = [
{
title: "Full Stack Web Development Certificate",
issuer: "University of North Carolina at Charlotte",
date: "May 2025",
credentialUrl: "https://www.credly.com/badges/3d764556-e5f4-49b1-b94e-8875edb19b03/linked_in_profile",
},
];

export default function Certificates() {
return (
<Section id="credentials" maxWidth="max-w-6xl" padding="py-14 px-6">
<div className="grid items-center gap-7 border-y border-white/10 py-8 lg:grid-cols-[0.7fr_1.3fr]">
<div>
<p className="eyebrow">Education &amp; credentials</p>
<h2 className="mt-3 font-display text-2xl font-semibold text-white sm:text-3xl">
Verified training, backed by working software
</h2>
</div>

<div className="space-y-4">
{credentials.map((credential) => (
<article key={credential.title} className="flex flex-col gap-5 rounded-xl border border-white/10 bg-white/[0.025] p-5 sm:flex-row sm:items-center sm:justify-between">
<div className="flex gap-4">
<span className="grid h-11 w-11 shrink-0 place-items-center rounded-lg border border-blueglow/30 bg-blueglow/10 text-xl text-blueglow">
<FiAward aria-hidden="true" />
</span>
<div>
<h3 className="font-display text-lg font-semibold text-white">{credential.title}</h3>
<p className="mt-1 text-sm leading-6 text-slate-400">
{credential.issuer} <span aria-hidden="true">·</span> {credential.date}
</p>
</div>
</div>

<a href={credential.credentialUrl} target="_blank" rel="noreferrer" className="inline-flex shrink-0 items-center gap-2 text-sm font-semibold text-blueglow transition-colors hover:text-blueglow-light focus:outline-none focus-visible:text-blueglow-light">
View verified credential <FiExternalLink aria-hidden="true" />
</a>
</article>
))}
</div>
</div>
</Section>
);
}
15 changes: 15 additions & 0 deletions src/components/__tests__/Certificates.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render, screen } from '@testing-library/react'
import Certificates from '../Certificates'

describe('Certificates', () => {
it('links the full-stack certificate to its verified credential', () => {
render(<Certificates />)

expect(screen.getByRole('heading', { name: 'Full Stack Web Development Certificate' })).toBeInTheDocument()
expect(screen.getByText(/University of North Carolina at Charlotte/)).toBeInTheDocument()
expect(screen.getByRole('link', { name: /view verified credential/i })).toHaveAttribute(
'href',
'https://www.credly.com/badges/3d764556-e5f4-49b1-b94e-8875edb19b03/linked_in_profile'
)
})
})
Loading