<?php class CommitsPage extends BasePage { private $currentRepo; private $git; private $hash; public function __construct($allRepos, $currentRepo, $git, $hash) { parent::__construct($allRepos); $this->currentRepo = $currentRepo; $this->git = $git; $this->hash = $hash; $this->title = $currentRepo['name']; } public function render() { $this->renderLayout(function() { $main = $this->git->getMainBranch(); if (!$main) { echo '<div class="empty-state"><h3>No branches</h3><p>Empty repository.</p></div>'; return; } $this->renderBreadcrumbs(); echo '<h2>Commit History <span class="branch-badge">' . htmlspecialchars($main['name']) . '</span></h2>'; echo '<div class="commit-list">'; $start = $this->hash ?: $main['hash']; $repoParam = '&repo=' . urlencode($this->currentRepo['safe_name']); $this->git->history($start, 100, function($commit) use ($repoParam) { $msg = htmlspecialchars(explode("\n", $commit->message)[0]); echo '<div class="commit-row">'; echo '<a href="?action=commit&hash=' . $commit->sha . $repoParam . '" class="sha">' . substr($commit->sha, 0, 7) . '</a>'; echo '<span class="message">' . $msg . '</span>'; echo '<span class="meta">' . htmlspecialchars($commit->author) . ' • ' . date('Y-m-d', $commit->date) . '</span>'; echo '</div>'; }); echo '</div>'; }, $this->currentRepo); } private function renderBreadcrumbs() { $repoUrl = '?repo=' . urlencode( $this->currentRepo['safe_name'] ); $crumbs = [ '<a href="?">Repositories</a>', '<a href="' . $repoUrl . '">' . htmlspecialchars($this->currentRepo['name']) . '</a>', 'Commits' ]; echo '<div class="breadcrumb">' . implode(' / ', $crumbs) . '</div>'; } }