Compare commits
2 Commits
863d841e47
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54b0dc856e | ||
|
|
9ec85f92cf |
19
.gitea/workflows/deploy.yml
Normal file
19
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
- run: npm ci
|
||||
- run: npx wrangler deploy
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
node_modules/
|
||||
.wrangler/
|
||||
dist/
|
||||
*.log
|
||||
.DS_Store
|
||||
31
README.md
31
README.md
@@ -1,3 +1,30 @@
|
||||
# portfolio
|
||||
# Portfolio
|
||||
|
||||
Personal portfolio
|
||||
Self-hosted portfolio built with Hono + HTMX + TailwindCSS on Cloudflare Workers.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Deploy to Cloudflare
|
||||
|
||||
1. Set `CLOUDFLARE_API_TOKEN` in Gitea secrets
|
||||
2. Push to `main` branch
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Access at `http://localhost:8787`
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Framework:** Hono.js
|
||||
- **UI:** HTMX + TailwindCSS
|
||||
- **Deployment:** Cloudflare Workers
|
||||
- **Theme:** Dracula
|
||||
|
||||
27
components/About.tsx
Normal file
27
components/About.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
export const About = () => (
|
||||
<section id="about" class="scroll-mt-24">
|
||||
<h2 class="text-3xl font-bold mb-4 text-dracula-purple">About</h2>
|
||||
<div class="prose prose-invert max-w-none">
|
||||
<p class="text-lg">
|
||||
Self-taught engineer with 20+ years of practical experience in systems administration,
|
||||
infrastructure management, and QA automation. Currently leading API testing automation
|
||||
initiatives for enterprise clients.
|
||||
</p>
|
||||
<p>
|
||||
Strong preference for self-hosted infrastructure and cost-effective solutions over major cloud providers.
|
||||
Proven track record in building automated testing frameworks, leading technical teams, and delivering
|
||||
reliable infrastructure solutions for small to medium businesses.
|
||||
</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
|
||||
<div class="bg-dracula-selection p-4 rounded">
|
||||
<h3 class="font-bold text-dracula-cyan mb-2">Location</h3>
|
||||
<p>Buenos Aires, Argentina</p>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-4 rounded">
|
||||
<h3 class="font-bold text-dracula-green mb-2">Languages</h3>
|
||||
<p>Spanish (Native), English (FCE certified)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
30
components/Contact.tsx
Normal file
30
components/Contact.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
export const Contact = () => (
|
||||
<section id="contact" class="scroll-mt-24">
|
||||
<h2 class="text-3xl font-bold mb-4 text-dracula-purple">Contact</h2>
|
||||
<div class="space-y-4">
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan mb-3">Get in Touch</h3>
|
||||
<p class="mb-4">
|
||||
Interested in working together? Reach out via email or connect on social platforms.
|
||||
</p>
|
||||
<div class="space-y-2">
|
||||
<a href="mailto:sudeste@example.com" class="flex items-center text-dracula-green hover:underline">
|
||||
<span class="mr-2">📧</span> sudeste@example.com
|
||||
</a>
|
||||
<a href="https://github.com/Sudeste" target="_blank" class="flex items-center text-dracula-green hover:underline">
|
||||
<span class="mr-2">🐙</span> GitHub
|
||||
</a>
|
||||
<a href="https://linkedin.com/in/sudeste" target="_blank" class="flex items-center text-dracula-green hover:underline">
|
||||
<span class="mr-2">💼</span> LinkedIn
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan mb-3">Download Resume</h3>
|
||||
<a href="/resume.pdf" class="text-dracula-green hover:underline" download>
|
||||
📄 Download PDF Resume
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
48
components/Experience.tsx
Normal file
48
components/Experience.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
export const Experience = () => (
|
||||
<section id="experience" class="scroll-mt-24">
|
||||
<h2 class="text-3xl font-bold mb-4 text-dracula-purple">Experience</h2>
|
||||
<div class="space-y-6">
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan">API Testing Automation Team Lead</h3>
|
||||
<span class="text-dracula-comment text-sm">2021 - Present</span>
|
||||
</div>
|
||||
<p class="text-dracula-purple mb-3">Intermex Wire Transfer, LLC</p>
|
||||
<ul class="list-disc list-inside space-y-2">
|
||||
<li>Lead team of 3 automation engineers in API testing initiatives</li>
|
||||
<li>Develop k6 performance testing framework with JavaScript abstraction</li>
|
||||
<li>Achieved 80% automation coverage across 50+ API endpoints</li>
|
||||
<li>Onboard development teams to Postman + Azure Pipelines automation methodology</li>
|
||||
<li>Team development: Training coworkers in Postman usage and basic JavaScript</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan">QA Performance Engineer</h3>
|
||||
<span class="text-dracula-comment text-sm">2021 - 2025</span>
|
||||
</div>
|
||||
<p class="text-dracula-purple mb-3">Freelance & Contract Roles</p>
|
||||
<ul class="list-disc list-inside space-y-2">
|
||||
<li>Developed k6 performance testing framework from scratch</li>
|
||||
<li>Created JavaScript abstraction layer for API synthetic testing</li>
|
||||
<li>Designed synthetic test methodology for production environments</li>
|
||||
<li>Consulting for small businesses on self-hosting infrastructure</li>
|
||||
<li>Office PC support: File servers, printer servers, LAN networks, VPN access</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan">Technical Services Provider</h3>
|
||||
<span class="text-dracula-comment text-sm">2006 - Present</span>
|
||||
</div>
|
||||
<p class="text-dracula-purple mb-3">Independent Contractor</p>
|
||||
<ul class="list-disc list-inside space-y-2">
|
||||
<li>Computer repair and maintenance services (18+ years)</li>
|
||||
<li>System optimization: Backup, format, Windows reinstallation, driver updates</li>
|
||||
<li>Hardware diagnostics and component replacement</li>
|
||||
<li>Self-taught knowledge accumulated through 20 years of practical experience</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
62
components/Layout.tsx
Normal file
62
components/Layout.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { html } from 'hono/html'
|
||||
|
||||
export const Layout = (props: { children: any }) => html`
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="scroll-smooth">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Sudeste - API Testing Automation Team Lead & Self-taught Engineer" />
|
||||
<title>Sudeste - Portfolio</title>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
dracula: {
|
||||
bg: '#282a36',
|
||||
fg: '#f8f8f2',
|
||||
selection: '#44475a',
|
||||
comment: '#6272a4',
|
||||
cyan: '#8be9fd',
|
||||
green: '#50fa7b',
|
||||
orange: '#ffb86c',
|
||||
pink: '#ff79c6',
|
||||
purple: '#bd93f9',
|
||||
red: '#ff5555',
|
||||
yellow: '#f1fa8c',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-dracula-bg text-dracula-fg min-h-screen">
|
||||
<nav class="fixed top-0 w-full bg-dracula-bg/90 backdrop-blur border-b border-dracula-selection z-50">
|
||||
<div class="max-w-4xl mx-auto px-4 py-3">
|
||||
<div class="flex justify-between items-center">
|
||||
<a href="/" class="text-xl font-bold text-dracula-purple">Sudeste</a>
|
||||
<div class="space-x-4">
|
||||
<a href="#about" class="hover:text-dracula-cyan transition">About</a>
|
||||
<a href="#projects" class="hover:text-dracula-cyan transition">Projects</a>
|
||||
<a href="#skills" class="hover:text-dracula-cyan transition">Skills</a>
|
||||
<a href="#experience" class="hover:text-dracula-cyan transition">Experience</a>
|
||||
<a href="#contact" class="hover:text-dracula-cyan transition">Contact</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<main class="max-w-4xl mx-auto px-4 pt-24 pb-12">
|
||||
${props.children}
|
||||
</main>
|
||||
<footer class="border-t border-dracula-selection mt-16 py-8">
|
||||
<div class="max-w-4xl mx-auto px-4 text-center text-dracula-comment">
|
||||
<p>© 2026 Sudeste. Built with Hono + HTMX + TailwindCSS on Cloudflare Workers.</p>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
38
components/Projects.tsx
Normal file
38
components/Projects.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
export const Projects = () => (
|
||||
<section id="projects" class="scroll-mt-24">
|
||||
<h2 class="text-3xl font-bold mb-4 text-dracula-purple">Projects</h2>
|
||||
<div class="space-y-6">
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan mb-2">k6 Performance Testing Framework</h3>
|
||||
<p class="text-dracula-comment mb-3">JavaScript-based k6 abstraction layer for API synthetic testing</p>
|
||||
<ul class="list-disc list-inside space-y-1">
|
||||
<li>Enabled Postman-like experience for endpoint-specific testing</li>
|
||||
<li>Developer-friendly workflow with JavaScript abstraction</li>
|
||||
<li>80% automation coverage across 50+ API endpoints</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan mb-2">Home Lab Infrastructure</h3>
|
||||
<p class="text-dracula-comment mb-3">Complete self-hosted stack demonstrating production-grade deployment skills</p>
|
||||
<ul class="list-disc list-inside space-y-1">
|
||||
<li>Gitea, Owncloud, SearXNG, PocketBase, WireGuard, nginx-proxy-manager</li>
|
||||
<li>Full CI/CD pipeline integration</li>
|
||||
<li>Monitoring with Grafana and Cockpit</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan mb-2">Media Processing Automation</h3>
|
||||
<p class="text-dracula-comment mb-3">FFmpeg-based video conversion utility with multi-subtitle track management</p>
|
||||
<ul class="list-disc list-inside space-y-1">
|
||||
<li>Television optimization workflows</li>
|
||||
<li>Automated subtitle track handling</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-cyan mb-2">Service Platform (Proof of Concept)</h3>
|
||||
<p class="text-dracula-comment mb-3">Cloudflare Worker + PocketBase + HTMX/TailwindCSS stack</p>
|
||||
<a href="https://sudestec.sudeste.workers.dev/" target="_blank" class="text-dracula-green hover:underline">View Demo →</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
61
components/Skills.tsx
Normal file
61
components/Skills.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
export const Skills = () => (
|
||||
<section id="skills" class="scroll-mt-24">
|
||||
<h2 class="text-3xl font-bold mb-4 text-dracula-purple">Skills</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-green mb-3">Operating Systems</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Arch Linux</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Debian</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Windows Server</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Windows Client</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-green mb-3">Languages</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">JavaScript</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Python</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Go</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Bash</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-green mb-3">Testing & QA</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Postman</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">k6</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">API Testing</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Performance Testing</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-green mb-3">DevOps & Cloud</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Azure Pipelines</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Docker</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Podman</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Cloudflare Workers</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-green mb-3">Infrastructure</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">KVM</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">WireGuard</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">RAID</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">OpenWrt</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-dracula-selection p-6 rounded-lg">
|
||||
<h3 class="text-xl font-bold text-dracula-green mb-3">Web Stack</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">Hono.js</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">HTMX</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">TailwindCSS</span>
|
||||
<span class="bg-dracula-bg px-3 py-1 rounded text-sm">PocketBase</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
16
package.json
Normal file
16
package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "portfolio",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "wrangler dev",
|
||||
"deploy": "wrangler deploy"
|
||||
},
|
||||
"dependencies": {
|
||||
"hono": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20240117.0",
|
||||
"wrangler": "^3.0.0"
|
||||
}
|
||||
}
|
||||
5
public/resume.pdf
Normal file
5
public/resume.pdf
Normal file
@@ -0,0 +1,5 @@
|
||||
# Resume placeholder - Replace with actual PDF
|
||||
|
||||
This file should be replaced with your actual PDF resume at `/home/sudeste/agent/portfolio/public/resume.pdf`
|
||||
|
||||
The CV_FINAL.md file contains your full resume content.
|
||||
24
src/index.ts
Normal file
24
src/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Hono } from 'hono'
|
||||
import { jsxRenderer } from 'hono/jsx-renderer'
|
||||
import { Layout } from '../components/Layout'
|
||||
import { About } from '../components/About'
|
||||
import { Projects } from '../components/Projects'
|
||||
import { Skills } from '../components/Skills'
|
||||
import { Experience } from '../components/Experience'
|
||||
import { Contact } from '../components/Contact'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use('*', jsxRenderer(({ children }) => <Layout>{children}</Layout>))
|
||||
|
||||
app.get('/', (c) => (
|
||||
<div class="space-y-16">
|
||||
<About />
|
||||
<Projects />
|
||||
<Skills />
|
||||
<Experience />
|
||||
<Contact />
|
||||
</div>
|
||||
))
|
||||
|
||||
export default app
|
||||
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2022"],
|
||||
"moduleResolution": "bundler",
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "hono/jsx",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["@cloudflare/workers-types"]
|
||||
}
|
||||
}
|
||||
7
wrangler.toml
Normal file
7
wrangler.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
name = "portfolio"
|
||||
main = "src/index.ts"
|
||||
compatibility_date = "2024-01-01"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
|
||||
[vars]
|
||||
CLOUDFLARE_ACCOUNT_ID = "your-account-id"
|
||||
Reference in New Issue
Block a user