argobox/src/pages/projects.astro

620 lines
19 KiB
Plaintext

---
// src/pages/projects.astro
import BaseLayout from '../layouts/BaseLayout.astro';
import '../styles/card-animations.css';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
const title = "Projects | LaForceIT";
const description = "Explore Daniel LaForce's projects, including infrastructure solutions, automation tools, and home lab configurations.";
// Category icons
const categoryIcons = {
"Infrastructure": `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>`,
"DevOps": `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline><line x1="19" y1="12" x2="5" y2="12"></line></svg>`,
"Web Development": `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>`,
"Documentation": `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>`,
"Automation": `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 20V10"></path><path d="M12 20V4"></path><path d="M6 20v-6"></path><path d="M18 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"></path><path d="M12 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"></path><path d="M6 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"></path></svg>`
};
// Featured projects
const featuredProjects = [
{
title: "Home Lab Infrastructure",
description: "Enterprise-grade home lab environment with Kubernetes, virtualization, networking, and storage solutions.",
image: "/images/projects/homelab.jpg",
url: "https://argobox.com",
isExternal: true,
technologies: ["Proxmox", "Kubernetes", "pfSense", "TrueNAS"],
category: "Infrastructure"
},
{
title: "Tech Stack",
description: "A detailed overview of the technologies, tools, and platforms that power my projects and home lab environment.",
image: "/images/projects/tech-stack.jpg",
url: "/tech-stack",
isExternal: false,
technologies: ["Kubernetes", "Docker", "Terraform", "Ansible"],
category: "Documentation"
},
{
title: "Infrastructure as Code Templates",
description: "Collection of Terraform and Ansible templates for automating infrastructure deployment.",
image: "/images/projects/iac.jpg",
url: "/projects/infrastructure-templates",
isExternal: false,
technologies: ["Terraform", "Ansible", "AWS", "Azure"],
category: "DevOps"
},
{
title: "Kubernetes Management Dashboard",
description: "Custom web interface for monitoring and managing Kubernetes clusters with enhanced visualization.",
image: "/images/projects/k8s-dashboard.jpg",
url: "/projects/kubernetes-dashboard",
isExternal: false,
technologies: ["React", "Node.js", "Kubernetes API", "Prometheus"],
category: "Web Development"
}
];
// Project categories
const categories = [
"All",
"Infrastructure",
"DevOps",
"Web Development",
"Documentation",
"Automation"
];
---
<BaseLayout title={title} description={description}>
<Header slot="header" />
<div class="container">
<div class="page-header">
<h1 class="page-title">Projects</h1>
<p class="page-description">
Explore my projects focused on infrastructure automation, DevOps solutions, and home lab configurations. These projects demonstrate practical applications of modern technologies in real-world scenarios.
</p>
</div>
<!-- Search & Filters -->
<div class="resource-search">
<div class="search-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</div>
<input type="text" placeholder="Search projects..." class="search-input" id="project-search">
</div>
<div class="resource-filters">
{categories.map(category => (
<button class={`filter-button ${category === 'All' ? 'active' : ''}`} data-filter={category.toLowerCase().replace(' ', '-')}>
{category}
</button>
))}
</div>
<!-- Projects Grid -->
<div class="resources-grid">
{featuredProjects.map(project => (
<div class="resource-card" data-category={project.category.toLowerCase().replace(' ', '-')}>
<div class="resource-icon-wrapper">
<div class="resource-icon" set:html={categoryIcons[project.category]}></div>
<div class="resource-icon-particles">
<div class="resource-icon-particle"></div>
<div class="resource-icon-particle"></div>
<div class="resource-icon-particle"></div>
<div class="resource-icon-particle"></div>
<div class="resource-icon-particle"></div>
</div>
{/* Add animated dots in the background of each icon area */}
<div class="icon-bg-dot" style={{top: '20%', left: '80%'}}></div>
<div class="icon-bg-dot" style={{top: '70%', left: '15%'}}></div>
<div class="icon-bg-dot" style={{top: '30%', left: '30%'}}></div>
<div class="icon-bg-dot" style={{top: '60%', left: '70%'}}></div>
<div class="icon-bg-dot" style={{top: '10%', left: '50%'}}></div>
</div>
<div class="resource-content">
<h2 class="resource-title">{project.title}</h2>
<p class="resource-description">{project.description}</p>
<a href={project.url} class="resource-link" target={project.isExternal ? "_blank" : undefined} rel={project.isExternal ? "noopener noreferrer" : undefined}>
{project.isExternal ? 'Visit Project' : 'View Project'}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="5" y1="12" x2="19" y2="12"></line>
<polyline points="12 5 19 12 12 19"></polyline>
</svg>
</a>
<div class="resource-tags">
{project.technologies.map(tech => (
<span class="resource-tag">{tech}</span>
))}
</div>
</div>
<div class="shine-effect"></div>
</div>
))}
<!-- Empty State (hidden by default) -->
<div class="no-results" style="display: none;">
<div class="no-results-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
<line x1="11" y1="8" x2="11" y2="14"></line>
<line x1="8" y1="11" x2="14" y2="11"></line>
</svg>
</div>
<h3>No matching projects found</h3>
<p>Try adjusting your search terms or filters to find what you're looking for.</p>
</div>
</div>
<div class="github-section">
<div class="github-header">
<div class="github-icon-wrapper">
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
</svg>
<div class="github-icon-particles">
<div class="github-icon-particle"></div>
<div class="github-icon-particle"></div>
<div class="github-icon-particle"></div>
<div class="github-icon-particle"></div>
</div>
</div>
<h2 class="section-title">GitHub Repositories</h2>
<a href="/projects/github" class="view-all">
View All
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</a>
</div>
<div class="github-content">
<p class="github-message">
Explore my open-source projects and contributions on GitHub. These repositories include infrastructure configurations, automation scripts, and development tools.
</p>
<a href="/projects/github" class="github-cta">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
</svg>
Browse Repositories
</a>
</div>
</div>
</div>
<Footer slot="footer" />
</BaseLayout>
<style>
.container {
max-width: 1280px;
margin: 0 auto;
padding: 0 var(--container-padding, 1.5rem);
}
.page-header {
text-align: center;
margin-bottom: 3rem;
}
.page-title {
font-size: 3rem;
font-weight: 700;
margin-bottom: 1rem;
background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
position: relative;
display: inline-block;
}
.page-title::after {
content: '';
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 3px;
background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary));
border-radius: 3px;
}
.page-description {
max-width: 800px;
margin: 0 auto;
color: var(--text-secondary);
font-size: 1.1rem;
}
/* Resource Filtering */
.resource-filters {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.75rem;
margin: 2rem 0;
}
.filter-button {
padding: 0.5rem 1.25rem;
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
color: var(--text-secondary);
border-radius: 20px;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.3s ease;
}
.filter-button:hover {
background: linear-gradient(90deg, rgba(6, 182, 212, 0.1), rgba(59, 130, 246, 0.1));
color: var(--text-primary);
border-color: var(--accent-primary);
box-shadow: 0 0 10px var(--glow-primary);
}
.filter-button.active {
background: linear-gradient(90deg, rgba(6, 182, 212, 0.2), rgba(59, 130, 246, 0.2));
color: var(--accent-primary);
border-color: var(--accent-primary);
box-shadow: 0 0 15px var(--glow-primary);
}
/* Search Box */
.resource-search {
display: flex;
margin: 0 auto 2rem;
max-width: 500px;
position: relative;
}
.search-input {
width: 100%;
padding: 0.75rem 1rem 0.75rem 2.75rem;
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: 8px;
color: var(--text-primary);
font-size: 1rem;
transition: all 0.3s ease;
}
.search-input:focus {
outline: none;
border-color: var(--accent-primary);
box-shadow: 0 0 0 3px var(--glow-primary);
}
.search-icon {
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
color: var(--text-tertiary);
}
/* Resources Grid */
.resources-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 2rem;
margin-top: 1rem;
margin-bottom: 4rem;
}
/* Styles for .resource-card, .resource-icon-wrapper, etc. are now in card-animations.css */
.resource-content {
padding: 1.5rem;
flex: 1;
display: flex;
flex-direction: column;
}
.resource-title {
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--text-primary);
}
.resource-description {
color: var(--text-secondary);
margin-bottom: 1.5rem;
flex: 1;
}
.resource-link {
display: inline-flex;
align-items: center;
text-decoration: none;
color: var(--accent-primary);
font-weight: 500;
transition: all 0.3s ease;
position: relative;
align-self: flex-start;
}
.resource-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 100%;
height: 1px;
background: var(--accent-primary);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.3s ease;
}
.resource-link:hover {
color: var(--accent-secondary);
}
.resource-link:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.resource-link svg {
margin-left: 0.5rem;
transition: transform 0.3s ease;
}
.resource-link:hover svg {
transform: translateX(3px);
}
.resource-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 1rem;
}
/* .resource-tag styling is now in card-animations.css */
/* Background dots styling is now in card-animations.css */
/* Shine effect styling is now in card-animations.css */
/* Empty State */
.no-results {
text-align: center;
padding: 3rem;
color: var(--text-secondary);
background: var(--bg-tertiary);
border-radius: 12px;
border: 1px dashed var(--border-primary);
margin-top: 2rem;
display: none; /* Hidden by default */
grid-column: 1 / -1; /* Span all columns */
}
.no-results-icon {
color: var(--text-tertiary);
margin-bottom: 1rem;
}
.no-results-icon svg {
width: 64px;
height: 64px;
stroke-width: 1;
opacity: 0.5;
}
/* GitHub Section (kept from original) */
.github-section {
background: var(--card-bg);
border: 1px solid var(--border-primary);
border-radius: 16px;
padding: 3rem;
margin: 2rem 0 4rem;
position: relative;
overflow: hidden;
}
.github-section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at 30% 50%, rgba(6, 182, 212, 0.1), transparent 70%);
pointer-events: none;
}
.github-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 2rem;
position: relative;
}
.github-icon-wrapper {
position: relative;
width: 64px;
height: 64px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
justify-content: center;
color: var(--text-primary);
overflow: hidden;
}
.github-icon-particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.github-icon-particle {
position: absolute;
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--accent-primary);
opacity: 0.5;
animation: github-particle 3s infinite ease-in-out;
}
.github-icon-particle:nth-child(1) { animation-delay: 0s; }
.github-icon-particle:nth-child(2) { animation-delay: 0.5s; }
.github-icon-particle:nth-child(3) { animation-delay: 1s; }
.github-icon-particle:nth-child(4) { animation-delay: 1.5s; }
@keyframes github-particle {
0% { transform: translate(0, 0); opacity: 0; }
25% { opacity: 0.5; }
50% { transform: translate(20px, -20px); opacity: 0.8; }
75% { opacity: 0.5; }
100% { transform: translate(40px, -40px); opacity: 0; }
}
.section-title {
font-size: 2rem;
color: var(--text-primary);
margin: 0;
position: relative;
flex: 1;
}
.view-all {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--accent-primary);
font-size: var(--font-size-sm);
text-decoration: none;
transition: all 0.3s ease;
position: relative;
}
.view-all::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 100%;
height: 1px;
background: var(--accent-primary);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.3s ease;
}
.view-all:hover {
color: var(--accent-secondary);
transform: translateX(3px);
}
.view-all:hover::after {
transform: scaleX(1);
transform-origin: left;
}
.view-all svg {
transition: transform 0.3s ease;
}
.view-all:hover svg {
transform: translateX(3px);
}
.github-content {
display: flex;
justify-content: space-between;
align-items: center;
gap: 2rem;
}
.github-message {
color: var(--text-secondary);
font-size: var(--font-size-lg);
line-height: 1.7;
max-width: 70%;
margin: 0;
}
.github-cta {
display: flex;
align-items: center;
gap: 0.75rem;
background: #24292e;
color: white;
padding: 0.75rem 1.25rem;
border-radius: 8px;
text-decoration: none;
font-weight: 500;
transition: all 0.3s ease;
white-space: nowrap;
position: relative;
overflow: hidden;
}
.github-cta::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}
.github-cta:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
.github-cta:hover::before {
opacity: 1;
}
/* Keyframes are now in card-animations.css */
@media (max-width: 768px) {
.page-title {
font-size: 2.5rem;
}
.github-section {
padding: 2rem 1.5rem;
}
.github-content {
flex-direction: column;
text-align: center;
gap: 1.5rem;
}
.github-message {
max-width: 100%;
}
.github-header {
flex-direction: column;
gap: 1rem;
text-align: center;
}
}