chore: modularize ui components
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="footer">
|
||||
<div className="footer-content">
|
||||
<p>
|
||||
Built with <span className="heart">❤️</span> and Amara Chukwu
|
||||
</p>
|
||||
<p className="footer-year">© {new Date().getFullYear()}</p>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function Header({ showNavLinks = true }) {
|
||||
return (
|
||||
<header className="header">
|
||||
<nav className="navbar">
|
||||
<div className="logo">
|
||||
<Link href="/">
|
||||
<span className="logo-text">JE</span>
|
||||
</Link>
|
||||
</div>
|
||||
{showNavLinks && (
|
||||
<div className="nav-links">
|
||||
<Link href="/" className="nav-link">
|
||||
Home
|
||||
</Link>
|
||||
<Link href="/rates" className="nav-link cta">
|
||||
Rates
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
{!showNavLinks && (
|
||||
<div className="nav-links">
|
||||
<a href="mailto:me@jesseinit.dev" className="nav-link cta">
|
||||
Get in touch
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import Head from 'next/head';
|
||||
import Header from './Header';
|
||||
import Footer from './Footer';
|
||||
|
||||
export default function Layout({ children, title, description, showNavLinks = true }) {
|
||||
return (
|
||||
<div className="container">
|
||||
<Head>
|
||||
<title>{title || 'Jesse Egbosionu - Software Engineer'}</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta
|
||||
name="description"
|
||||
content={description || 'Software engineer based in Amsterdam, focused on building scalable backend systems.'}
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<Header showNavLinks={showNavLinks} />
|
||||
|
||||
<main className="main-content">{children}</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
export default function RateCard({ provider, rate, href, isBest, index, formatCurrency }) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={`rate-card ${isBest ? 'best' : ''}`}
|
||||
style={{ animationDelay: `${index * 0.1}s` }}
|
||||
>
|
||||
<div className="rate-card-header">
|
||||
<h3 className="provider-name">{provider}</h3>
|
||||
{isBest && <span className="best-badge">Best Rate</span>}
|
||||
</div>
|
||||
|
||||
<div className="rate-value">{formatCurrency(rate)}</div>
|
||||
|
||||
<div className="rate-card-footer">
|
||||
<span className="visit-link">Visit provider →</span>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
const socialData = [
|
||||
{
|
||||
name: 'GitHub',
|
||||
url: 'https://github.com/jesseinit',
|
||||
icon: (
|
||||
<svg className="social-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'LinkedIn',
|
||||
url: 'https://linkedin.com/in/jesse-egbosionu/',
|
||||
icon: (
|
||||
<svg className="social-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'Twitter',
|
||||
url: 'https://twitter.com/jesseinit/',
|
||||
icon: (
|
||||
<svg className="social-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function SocialLinks() {
|
||||
return (
|
||||
<div className="social-links">
|
||||
{socialData.map((social) => (
|
||||
<a
|
||||
key={social.name}
|
||||
href={social.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="social-link"
|
||||
>
|
||||
{social.icon}
|
||||
{social.name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user