Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.
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
26 changes: 24 additions & 2 deletions src/components/Layout/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useState, useEffect } from 'react';

function Header() {
const [isScrolled, setIsScrolled] = useState(false);
// Get the base URL from the router's basename
const baseUrl = import.meta.env.BASE_URL;

useEffect(() => {
Expand Down Expand Up @@ -32,7 +31,6 @@ function Header() {
className="profile-pic-link"
>
<img
// Use the baseUrl for the image path
src={`${baseUrl}profile-picture.jpg`}
alt="David Salathé"
className="header-profile-pic"
Expand All @@ -50,6 +48,30 @@ function Header() {
>
About
</a>
<div className="social-links">
<a
href="https://github.com/dsalathe"
target="_blank"
rel="noopener noreferrer"
className="social-link"
aria-label="GitHub"
>
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
</svg>
</a>
<a
href="https://www.linkedin.com/in/david-salathe/"
target="_blank"
rel="noopener noreferrer"
className="social-link"
aria-label="LinkedIn"
>
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</a>
</div>
</nav>
</div>
</header>
Expand Down
1 change: 1 addition & 0 deletions src/data/posts/001-first-post.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ id: 1
title: First Blog Post
description: This is my first blog post
publishedDate: 2025-02-15
image: Octocat.png
keywords:
- first
- blog
Expand Down
1 change: 1 addition & 0 deletions src/data/posts/002-react-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ id: 2
title: Getting Started with React
description: Learn the basics of React and its core concepts
publishedDate: 2025-02-16
image: logo512.png
keywords:
- react
- javascript
Expand Down
152 changes: 120 additions & 32 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ p {
.blog-card-link:nth-child(n+6) { animation-delay: 0.5s; }

.blog-card {
display: flex;
flex-direction: column;
background: #ffffff;
border-radius: 16px;
overflow: hidden;
Expand All @@ -109,6 +111,7 @@ p {
}

.blog-card-content {
flex: 1;
padding: 24px;
}

Expand Down Expand Up @@ -225,6 +228,7 @@ p {
border-bottom: 1px solid #eaeaea;
transition: all 0.3s ease;
width: 100%; /* Make header span full width */
padding-bottom: 24px; /* Add padding to account for the overflowing profile pic */
}

.header-scrolled {
Expand Down Expand Up @@ -283,6 +287,8 @@ p {
opacity: 1;
transform: translateY(0);
transition: all 0.3s ease;
position: relative; /* Add this */
height: 0; /* Add this */
}

.header-center-hidden {
Expand All @@ -292,55 +298,40 @@ p {
}

.header-profile-pic {
width: 48px;
height: 48px;
width: 90px;
height: 90px;
border-radius: 50%;
object-fit: cover;
border: 2px solid #fff;
border: 3px solid #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
position: absolute;
bottom: -80px;
left: 50%;
transform: translateX(-50%); /* Center horizontally */
}

.header-scrolled .header-title h1 {
font-size: 1.25rem;
}

.header-scrolled .header-profile-pic {
width: 60px; /* Smaller size when scrolled */
height: 50px;
bottom: -30px; /* Adjust position when scrolled */
}

/* Update hover effect to avoid horizontal shift */
.header-profile-pic:hover {
transform: scale(1.1);
transform: translateX(-50%) scale(1.1);
}

.header-nav {
flex: 1;
display: flex;
justify-content: flex-end;
gap: 1.5rem;
}

.nav-link {
text-decoration: none;
color: #4a5568;
font-weight: 500;
transition: color 0.3s ease;
position: relative;
}

.nav-link::after {
content: '';
position: absolute;
width: 0;
height: 2px;
bottom: -4px;
left: 0;
background-color: #4299e1;
transition: width 0.3s ease;
}

.nav-link:hover {
color: #4299e1;
}

.nav-link:hover::after {
width: 100%;
align-items: center;
gap: 1rem;
}

/* Blog Post Page Styles */
Expand Down Expand Up @@ -462,3 +453,100 @@ p {
rgba(224, 231, 255, 1) /* Match this color with your body background */
);
}

/* Add these new styles */

.blog-card-image {
width: 100%;
height: 200px;
overflow: hidden;
border-radius: 16px 16px 0 0;
}

.blog-card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}

.blog-card:hover .blog-card-image img {
transform: scale(1.05);
}

.blog-post-image {
width: 100%;
max-height: 400px;
overflow: hidden;
border-radius: 16px;
margin-bottom: 2rem;
}

.blog-post-image img {
width: 100%;
height: 100%;
object-fit: cover;
}

/* Add these new styles for social links */
.social-links {
display: flex;
align-items: center;
gap: 0.75rem;
margin-left: 1rem;
padding-left: 1rem;
border-left: 1px solid #eaeaea;
}

.social-link {
color: #4a5568;
transition: color 0.3s ease, transform 0.2s ease;
display: flex;
align-items: center;
}

.social-link:hover {
color: #4299e1;
transform: translateY(-2px);
}

/* Update existing header-nav styles to accommodate social links */
.header-nav {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 1rem;
}

/* Add new nav link styles */
.nav-link {
color: #4a5568;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 0.75rem;
border-radius: 6px;
transition: all 0.3s ease;
}

.nav-link:hover {
color: #4299e1;
background-color: rgba(66, 153, 225, 0.1);
}

/* Responsive adjustments */
@media (max-width: 768px) {
.nav-link {
padding: 0.25rem 0.5rem;
font-size: 0.9rem;
}

.header-nav {
gap: 0.5rem;
}

.social-links {
margin-left: 0.5rem;
padding-left: 0.5rem;
}
}
14 changes: 14 additions & 0 deletions src/pages/BlogPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ function BlogPage() {
});
};

const getImageUrl = (imagePath) => {
const baseUrl = import.meta.env.BASE_URL;
return imagePath ? `${baseUrl}${imagePath}` : null;
};

useEffect(() => {
const loadBlog = async () => {
try {
Expand Down Expand Up @@ -48,6 +53,15 @@ function BlogPage() {
return (
<div className="blog-post-container">
<article className="blog-post">
{blog.image && (
<div className="blog-post-image">
<img
src={getImageUrl(blog.image)}
alt={blog.title}
loading="lazy"
/>
</div>
)}
<Markdown>{blog.content}</Markdown>
<div className="blog-post-meta">
<p className="blog-post-date">Published: {formatDate(blog.publishedDate)}</p>
Expand Down
14 changes: 14 additions & 0 deletions src/pages/HomePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ function HomePage() {
});
};

const getImageUrl = (imagePath) => {
const baseUrl = import.meta.env.BASE_URL;
return imagePath ? `${baseUrl}${imagePath}` : null;
};

const filteredBlogs = blogs.filter(blog =>
!searchQuery || blog.keywords.some(keyword =>
keyword.toLowerCase().includes(searchQuery.toLowerCase())
Expand Down Expand Up @@ -80,6 +85,15 @@ function HomePage() {
className="blog-card-link"
>
<article className="blog-card">
{blog.image && (
<div className="blog-card-image">
<img
src={getImageUrl(blog.image)}
alt={blog.title}
loading="lazy"
/>
</div>
)}
<div className="blog-card-content">
<h2>{blog.title}</h2>
<p className="blog-description">{blog.description}</p>
Expand Down
3 changes: 2 additions & 1 deletion src/utils/blogLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export const loadBlogPosts = async () => {
title: data.title,
description: data.description,
publishedDate: data.publishedDate,
keywords: data.keywords
keywords: data.keywords,
image: data.image // Add this line
});
}

Expand Down