Documentation Index
Fetch the complete documentation index at: https://mintlify.com/santiagonieto09/portafolio/llms.txt
Use this file to discover all available pages before exploring further.
The repository explorer renders all non-fork public repositories with real-time client-side filtering and sorting. Because the full repository list is embedded in the server-rendered page payload, no server round-trips are needed after the initial data load — every search keystroke and filter change is instant.
RepositoryExplorer component
Source: src/components/portfolio/repository-explorer.tsx
RepositoryExplorer accepts the complete list of repositories and owns all filter state:
function RepositoryExplorer({ repositories }: { repositories: Repository[] })
State is a single RepositoryQuery object managed with useState, initialised to defaultQuery. A patch helper merges partial updates so individual controls only need to send the fields they change.
Three useMemo calls derive everything from the full repositories array:
| Derived value | How it is computed |
|---|
languages | collectLanguages(repositories) — union of all language keys across repos, alphabetically sorted |
technologies | collectTechnologies(repositories) — union of all technology names that are not raw language names, alphabetically sorted |
visible | applyQuery(repositories, query) — the filtered and sorted subset shown in the grid |
The grid uses a responsive three-column layout (md:grid-cols-2 xl:grid-cols-3). When no repository matches the current query a polite empty-state message is shown instead.
Filter & sort controls
Source: src/components/portfolio/repository-filters.tsx
RepositoryFilters receives the current query, an onChange callback, the available languages and technologies lists, and the live resultCount. It renders a self-contained panel containing all controls:
Text search — A search input that matches against repo.name, repo.description, repo.technologies, Object.keys(repo.languages), and repo.topics (case-insensitive substring match via matchesSearch()).
Language dropdown — A <Select> populated with the unique, sorted language list from collectLanguages(repositories). Selecting a language keeps only repos that have at least one byte of that language. Selecting the “Lenguaje” placeholder resets the filter to null.
Technology (framework) dropdown — A <Select> populated with collectTechnologies(repositories), which excludes raw language names so it only lists frameworks and tools. Selecting a technology keeps only repos where repo.technologies includes that value.
Feature toggles — A dropdown menu (DropdownMenu) containing five CheckboxItem toggles. The number of active toggles is shown as a badge on the trigger button:
| Toggle key | Label | Effect |
|---|
onlyWithRelease | Tiene release | Keeps repos where repo.release !== null |
onlyWithDocs | Tiene documentación | Keeps repos where docsUrlFor(repo.htmlUrl) is non-null |
onlyWithSite | Tiene sitio web | Keeps repos where repo.homepage is non-null |
onlyActive | Proyecto activo | Keeps repos where repo.archived === false |
onlyArchived | Proyecto archivado | Keeps repos where repo.archived === true |
Sort key — Selects which field drives the sort order:
| Value | Label | Comparator |
|---|
updated | Actualización | pushedAt descending |
created | Creación | createdAt descending |
stars | Estrellas | stars descending |
name | Nombre | name locale-compare descending |
Sort direction — Ascending or descending. The direction multiplier flips all comparators, so name ascending becomes A → Z.
Result count badge — A live-region (aria-live="polite") paragraph showing the number of matching projects.
RepositoryCard
Source: src/components/portfolio/repository-card.tsx
Each repository is rendered as an <article> with a full-height flex column layout. The card contains:
Header — Repository name as an <h3> (truncated with CSS), a description paragraph (line-clamp-2 by default), and a “Ver más…” / “Ver menos” toggle button for descriptions longer than 110 characters. An archived/active status chip is positioned in the top-right corner.
Technology badges — A <ul> of up to 8 technology name chips drawn from repo.technologies. If a technology name also appears in Object.keys(repo.languages), a colored dot using languageColor(tech) is shown beside it.
Metadata grid — Four data items in a <dl> grid:
| Item | Icon | Content |
|---|
| Created | CalendarPlus | formatDate(repo.createdAt) |
| Last pushed | History | useRelativeTime(repo.pushedAt) |
| Stars | Star | repo.stars |
| Forks & visibility | GitFork | {repo.forks} · {repo.visibility} |
Release panel — Shown only when repo.release !== null. Displays the release name, tag in a monospace () wrapper, and the formatted publish date.
Footer links — A row of action buttons:
| Button | Condition | Destination |
|---|
| Repositorio | Always | repo.htmlUrl (GitHub) |
| Docs | docsUrlFor(repo.htmlUrl) !== null | DeepWiki URL for the repo |
| Ver release | repo.release !== null | repo.release.url |
| Sitio web | repo.homepage !== null | repo.homepage |
docsUrlFor() converts a GitHub repository URL (https://github.com/owner/repo) to its DeepWiki documentation URL (https://deepwiki.com/owner/repo). It returns null for any URL that is not a valid GitHub repository path.
Repository domain type
The Repository interface is defined in src/domain/github/types.ts:
interface Repository {
id: number;
name: string;
description: string | null;
htmlUrl: string;
homepage: string | null;
language: string | null;
languages: Record<string, number>;
technologies: string[];
stars: number;
forks: number;
watchers: number;
openIssues: number;
archived: boolean;
visibility: string;
createdAt: string;
updatedAt: string;
pushedAt: string;
topics: string[];
hasPages: boolean;
license: string | null;
release: ReleaseInfo | null;
}
languages is a Record<string, number> where each key is a language name and the value is the byte count for that language in the repository — the same data returned by GitHub’s per-repo /languages endpoint.
technologies is the result of running detectTechnologies() at data-fetch time and is stored alongside the rest of the repository data in the portfolio snapshot.
Forked repositories are always excluded from the portfolio. The GitHub API call uses per_page=100&sort=updated, so the portfolio shows up to 100 public non-fork repos. If an account has more than 100 public non-fork repositories, the oldest ones (by push date) will not appear.