feat: update global styles and layout with new font and theme support; enhance dashboard header with theme toggle
This commit is contained in:
+96
-89
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
ArrowRight,
|
||||
BookOpen,
|
||||
Container,
|
||||
Cpu,
|
||||
Database,
|
||||
@@ -8,6 +7,7 @@ import {
|
||||
GitBranch,
|
||||
GitFork,
|
||||
HardDrive,
|
||||
Layers,
|
||||
} from "lucide-react";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -15,13 +15,14 @@ import { buttonVariants } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
// ponytail: static data, fine for a personal portfolio. Move to CMS/content layer if > 50 items.
|
||||
const skills = [
|
||||
{ icon: HardDrive, label: "Backend (Bun, Elysia, Axum)" },
|
||||
{ icon: Container, label: "Docker & Traefik" },
|
||||
{ icon: Database, label: "PostgreSQL, Redis, NATS" },
|
||||
{ icon: Cpu, label: "Rust, TypeScript, Python" },
|
||||
{ icon: GitBranch, label: "CI/CD, GitHub Actions" },
|
||||
{ icon: BookOpen, label: "Dapr, Prometheus, Jaeger" },
|
||||
{ icon: Layers, label: "Dapr, Prometheus, Jaeger" },
|
||||
];
|
||||
|
||||
const techTags = [
|
||||
@@ -50,19 +51,25 @@ const techTags = [
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="flex flex-1 flex-col">
|
||||
{/* Hero */}
|
||||
<section className="flex flex-col items-center justify-center px-6 py-24 text-center sm:py-32">
|
||||
<div className="mb-6 flex size-14 items-center justify-center rounded-2xl bg-foreground text-xl font-bold text-background">
|
||||
AH
|
||||
{/* Hero — terminal-inspired */}
|
||||
<section className="relative flex flex-col items-center justify-center overflow-hidden px-6 py-28 text-center sm:py-36">
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_at_center,oklch(0.45_0.13_265_/_0.06)_0%,transparent_70%)] dark:bg-[radial-gradient(ellipse_at_center,oklch(0.7_0.15_75_/_0.06)_0%,transparent_70%)]" />
|
||||
<div className="relative">
|
||||
<p className="mb-2 font-mono text-xs text-muted-foreground">
|
||||
<span className="text-primary dark:text-primary">~</span> whoami
|
||||
</p>
|
||||
<h1 className="font-mono text-3xl font-bold tracking-tight sm:text-5xl">
|
||||
<span className="text-muted-foreground">$ </span>
|
||||
Asep Haryana Saputra
|
||||
<span className="inline-block size-2.5 animate-pulse bg-foreground ml-1 rounded-none" />
|
||||
</h1>
|
||||
<p className="mx-auto mt-3 max-w-lg font-mono text-xs text-muted-foreground sm:text-sm">
|
||||
<span className="text-muted-foreground/50"># </span>
|
||||
Teknik Informatika student exploring backend systems, distributed
|
||||
infrastructure, and DevOps — still learning, still building.
|
||||
</p>
|
||||
</div>
|
||||
<h1 className="max-w-2xl text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Asep Haryana Saputra
|
||||
</h1>
|
||||
<p className="mt-3 max-w-lg text-lg text-muted-foreground">
|
||||
Backend & infrastructure engineer who builds distributed systems,
|
||||
RESTful APIs, and production-grade observability stacks.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||||
<div className="relative mt-10 flex flex-wrap items-center justify-center gap-3">
|
||||
<a href="#projects" className={cn(buttonVariants({ size: "lg" }))}>
|
||||
View Projects
|
||||
<ArrowRight className="size-4" />
|
||||
@@ -79,75 +86,75 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* About */}
|
||||
<section className="mx-auto flex w-full max-w-3xl flex-col gap-8 px-6 pb-24">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>About</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="text-muted-foreground">
|
||||
{/* Content — staggered sections with alternating visual weight */}
|
||||
<section className="mx-auto flex w-full max-w-3xl flex-col gap-12 px-6 pb-28">
|
||||
{/* About — minimal, just text */}
|
||||
<div>
|
||||
<p className="mb-2 font-mono text-xs text-muted-foreground">
|
||||
<span className="text-primary dark:text-primary">~</span> about
|
||||
</p>
|
||||
<div className="space-y-3 leading-relaxed text-muted-foreground">
|
||||
<p>
|
||||
I build backend systems and infrastructure for personal projects,
|
||||
research collaborations, and production deployments. My work spans
|
||||
RESTful API design, container orchestration with Docker &
|
||||
Traefik, distributed tracing with OpenTelemetry & Jaeger, and
|
||||
event-driven architectures on Dapr & NATS.
|
||||
I’m a Teknik Informatika student passionate about backend
|
||||
engineering, distributed systems, and infrastructure. I spend my
|
||||
time building RESTful APIs, learning container orchestration with
|
||||
Docker & Traefik, and exploring observability with OpenTelemetry
|
||||
& Jaeger.
|
||||
</p>
|
||||
<p className="mt-3">
|
||||
I was the Back-End lead on the ZeaVis Edu capstone team ("AI
|
||||
for Smart Education" by Pijak × IBM SkillsBuild), where
|
||||
I designed the system architecture, API contracts, and deployment
|
||||
pipeline for a computer vision-based corn leaf disease detection
|
||||
platform.
|
||||
<p>
|
||||
I was the Back-End lead on the ZeaVis Edu capstone team (“AI
|
||||
for Smart Education” by Pijak × IBM SkillsBuild),
|
||||
a 5-person team with task division across Back-End, Front-End,
|
||||
and Machine Learning. I handled the system architecture, API
|
||||
design, RESTful API development, and Docker deployment on VPS.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Skills */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Skills & Tools</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="mb-4 grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
{skills.map((s) => {
|
||||
const Icon = s.icon;
|
||||
return (
|
||||
<div
|
||||
key={s.label}
|
||||
className="flex items-center gap-2 rounded-lg border border-border px-3 py-2 text-sm"
|
||||
>
|
||||
<Icon className="size-4 shrink-0 text-muted-foreground" />
|
||||
<span>{s.label}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{techTags.map((t) => (
|
||||
<Badge
|
||||
key={t}
|
||||
variant="secondary"
|
||||
className="text-[11px] font-normal"
|
||||
{/* Skills & Tools — grid */}
|
||||
<div>
|
||||
<p className="mb-2 font-mono text-xs text-muted-foreground">
|
||||
<span className="text-primary dark:text-primary">~</span> skills
|
||||
</p>
|
||||
<div className="mb-4 grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
{skills.map((s) => {
|
||||
const Icon = s.icon;
|
||||
return (
|
||||
<div
|
||||
key={s.label}
|
||||
className="flex items-center gap-3 rounded-lg border border-border bg-card px-3.5 py-2.5 text-sm"
|
||||
>
|
||||
{t}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Icon className="size-4 shrink-0 text-primary dark:text-primary" />
|
||||
<span>{s.label}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{techTags.map((t) => (
|
||||
<Badge
|
||||
key={t}
|
||||
variant="outline"
|
||||
className="text-[11px] font-normal"
|
||||
>
|
||||
{t}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Projects */}
|
||||
<div id="projects" className="scroll-mt-20">
|
||||
<h2 className="mb-4 text-xl font-semibold tracking-tight">
|
||||
Featured Project
|
||||
</h2>
|
||||
<Card>
|
||||
{/* Featured Project — elevated */}
|
||||
<div id="projects" className="scroll-mt-24">
|
||||
<p className="mb-2 font-mono text-xs text-muted-foreground">
|
||||
<span className="text-primary dark:text-primary">~</span> featured
|
||||
project
|
||||
</p>
|
||||
<Card className="relative overflow-hidden">
|
||||
<CardHeader>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<CardTitle>ZeaVis Edu</CardTitle>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<CardTitle className="text-lg">ZeaVis Edu</CardTitle>
|
||||
<p className="mt-0.5 text-sm text-muted-foreground">
|
||||
Asisten Edukasi Interaktif untuk Deteksi Penyakit Daun
|
||||
Jagung
|
||||
</p>
|
||||
@@ -179,19 +186,19 @@ export default function Home() {
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="text-sm text-muted-foreground">
|
||||
<p>
|
||||
<p className="mb-4">
|
||||
A Computer Vision-powered educational platform that helps
|
||||
farmers, agricultural students, and field extension officers
|
||||
identify corn leaf diseases by uploading a photo. Built as a
|
||||
capstone project for the Pijak × IBM SkillsBuild program.
|
||||
</p>
|
||||
|
||||
<div className="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<p className="mb-1.5 text-xs font-semibold uppercase tracking-wider">
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div className="rounded-lg border border-border bg-muted/30 p-3">
|
||||
<p className="mb-2 text-xs font-semibold uppercase tracking-wider text-foreground">
|
||||
What it does
|
||||
</p>
|
||||
<ul className="list-inside list-disc space-y-1 text-muted-foreground">
|
||||
<ul className="list-inside list-disc space-y-1 text-xs">
|
||||
<li>Upload a photo of a corn leaf</li>
|
||||
<li>
|
||||
AI classifies the disease — Blight, Rust, Leaf Spot,
|
||||
@@ -200,14 +207,14 @@ export default function Home() {
|
||||
<li>Get treatment & prevention recommendations</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p className="mb-1.5 text-xs font-semibold uppercase tracking-wider">
|
||||
<div className="rounded-lg border border-border bg-muted/30 p-3">
|
||||
<p className="mb-2 text-xs font-semibold uppercase tracking-wider text-foreground">
|
||||
My role
|
||||
</p>
|
||||
<ul className="list-inside list-disc space-y-1 text-muted-foreground">
|
||||
<ul className="list-inside list-disc space-y-1 text-xs">
|
||||
<li>System architecture & API design</li>
|
||||
<li>RESTful API (Bun + Elysia + Drizzle + PostgreSQL)</li>
|
||||
<li>Rust inference engine (Axum + ONNX Runtime)</li>
|
||||
<li>Secure upload handling</li>
|
||||
<li>
|
||||
Docker deployment on VPS with Traefik & Tailscale
|
||||
</li>
|
||||
@@ -234,7 +241,7 @@ export default function Home() {
|
||||
].map((t) => (
|
||||
<Badge
|
||||
key={t}
|
||||
variant="outline"
|
||||
variant="secondary"
|
||||
className="text-[10px] font-normal"
|
||||
>
|
||||
{t}
|
||||
@@ -245,16 +252,16 @@ export default function Home() {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Infrastructure CTA */}
|
||||
<Card>
|
||||
<CardContent className="flex flex-col items-center gap-4 py-8 text-center">
|
||||
{/* Infrastructure CTA — clean card */}
|
||||
<Card className="text-center">
|
||||
<CardContent className="flex flex-col items-center gap-4 py-10">
|
||||
<p className="text-base font-medium">
|
||||
This site doubles as a live infrastructure monitor.
|
||||
</p>
|
||||
<p className="max-w-md text-sm text-muted-foreground">
|
||||
The dashboard tracks Docker services, Traefik request metrics,
|
||||
Prometheus system resources, and Jaeger traces across the
|
||||
deployment.
|
||||
Prometheus system resources, and Jaeger traces — all running on
|
||||
my VPS deployment.
|
||||
</p>
|
||||
<a href="/dashboard" className={cn(buttonVariants())}>
|
||||
Live Dashboard
|
||||
|
||||
Reference in New Issue
Block a user