Files
fristydev/components/projects-section.tsx
T
fristy ad943fff8c
Build & Push / Lint & Build (push) Successful in 1m15s
Build & Push / Build & Push Image (push) Successful in 52s
Initial commit: fristy.net personal site
2026-09-10 04:59:12 +03:00

106 lines
4.8 KiB
TypeScript

import type { Dictionary } from "@/lib/i18n/get-dictionary";
import type { Locale } from "@/lib/i18n/locales";
import type { GiteaRepo } from "@/lib/gitea";
import { SectionHeading } from "./section-heading";
const LANGUAGE_COLORS: Record<string, string> = {
"C#": "#178600",
TypeScript: "#3178c6",
JavaScript: "#f1e05a",
Python: "#3572a5",
Rust: "#dea584",
Go: "#00add8",
};
export function ProjectsSection({
repos,
dict,
locale,
}: {
repos: GiteaRepo[];
dict: Dictionary["projects"];
locale: Locale;
}) {
const dateFormat = new Intl.DateTimeFormat(locale, { dateStyle: "medium" });
return (
<section id="projects" className="scroll-mt-24">
<SectionHeading kicker="git.fristy.net" title={dict.title} subtitle={dict.subtitle} />
{repos.length === 0 ? (
<p className="rounded-2xl border border-white/10 bg-panel p-6 text-zinc-400">
{dict.empty}
</p>
) : (
<div className="grid gap-4 sm:grid-cols-2">
{repos.map((repo) => (
<div
key={repo.id}
className="group rounded-2xl border border-white/10 bg-panel p-5 transition-colors hover:border-blurple/60"
>
<p className="font-mono text-sm text-blurple-soft">{repo.fullName}</p>
<h3 className="mt-1 text-lg font-bold">
<a
href={repo.website ?? repo.htmlUrl}
target="_blank"
rel="noopener noreferrer"
className="transition-colors group-hover:text-white"
>
{repo.name}
</a>
</h3>
<p className="mt-2 line-clamp-3 text-sm text-zinc-400">
{repo.description ?? dict.noDescription}
</p>
<div className="mt-4 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-zinc-500">
{repo.language ? (
<span className="inline-flex items-center gap-1.5">
<span
className="h-2.5 w-2.5 rounded-full"
style={{
backgroundColor:
LANGUAGE_COLORS[repo.language] ?? "#5865f2",
}}
/>
{repo.language}
</span>
) : null}
<span>
★ {repo.stars} {dict.stars}
</span>
<span>
⑂ {repo.forks} {dict.forks}
</span>
<span>
{dict.updated}: {dateFormat.format(new Date(repo.updatedAt))}
</span>
</div>
<div className="mt-3 flex items-center justify-between gap-4 text-xs font-medium">
<span>
{repo.website ? (
<a
href={repo.website}
target="_blank"
rel="noopener noreferrer"
className="text-blurple-soft transition-colors hover:text-white"
>
{dict.viewWebsite} ↗
</a>
) : null}
</span>
<a
href={repo.htmlUrl}
target="_blank"
rel="noopener noreferrer"
className="text-zinc-500 transition-colors hover:text-white"
>
{dict.viewOnGitea} →
</a>
</div>
</div>
))}
</div>
)}
</section>
);
}