use export::http::{Path, Response, State}; use maud::html; use crate::handler::html::{HtmlRepoPath, archived_class, resolve, response_html}; use crate::service::GitService; use ::session::Session; #[utoipa::path( get, path = "/repos/{space_name}/{repo_name}/html/header", tag = "html", description = "渲染仓库标题、可见性和归档状态头部片段。", operation_id = "render_header", params(HtmlRepoPath), responses( (status = 200, description = "repo header html fragment", content_type = "text/html"), (status = 404, description = "repo not found") ) )] pub async fn render_header( State(service): State, Path(path): Path, session: Session, ) -> Response { let ctx = match resolve(service, path, session).await { Ok(c) => c, Err(resp) => return resp, }; let base = "git-header flex items-center gap-2 text-lg font-semibold"; let cls = archived_class(&ctx.dto, base); let markup = html! { div class=(cls) data-component="git-header" data-space=(ctx.space_name) data-repo=(ctx.repo_name) data-private=(if ctx.dto.is_private { "true" } else { "false" }) data-archived=(if ctx.dto.is_archived { "true" } else { "false" }) data-default-branch=(ctx.dto.default_branch) { a class="text-zinc-700 hover:text-zinc-900" href=(format!("/{}/{}", ctx.space_name, ctx.repo_name)) { span class="font-medium text-zinc-500" { (ctx.space_name) } span class="px-1 text-zinc-400" { "/" } span { (ctx.repo_name) } } @if ctx.dto.is_private { span class="rounded bg-amber-100 px-1.5 py-0.5 text-xs text-amber-700" { "private" } } @if ctx.dto.is_archived { span class="rounded bg-zinc-200 px-1.5 py-0.5 text-xs text-zinc-600" { "archived" } } @if let Some(desc) = ctx.dto.description.as_ref() { p class="ml-3 text-sm font-normal text-zinc-500" { (desc) } } } }; response_html(markup, 30) }