feat: add Gitea support with new widgets and API integration

This commit is contained in:
Kayela Claybon
2026-01-15 17:29:27 -06:00
parent 7725cd75a4
commit 22666529d7
14 changed files with 738 additions and 78 deletions

View File

@@ -0,0 +1,200 @@
import React, { useState } from "react";
import useGiteaCommits from "../../hooks/useGiteaCommits";
import GiteaCommitItem from "./GiteaCommitItem";
import "../../styles/GiteaWidget.css";
import {
FaCodeBranch,
FaSync,
FaExclamationTriangle,
FaServer,
} from "react-icons/fa";
export const GiteaWidget = ({
defaultGiteaUrl = "https://git.konceptkit.com/",
defaultRepo = "owner/repo",
token = null,
limit = 5,
branch = "main",
title = "Recent Commits",
}) => {
const [giteaUrl, setGiteaUrl] = useState(defaultGiteaUrl);
const [repo, setRepo] = useState(defaultRepo);
const [inputGiteaUrl, setInputGiteaUrl] = useState(defaultGiteaUrl);
const [inputRepo, setInputRepo] = useState(defaultRepo);
const [showAdvanced, setShowAdvanced] = useState(false);
const { commits, loading, error } = useGiteaCommits(
giteaUrl,
repo,
token,
limit,
branch
);
const handleSubmit = (e) => {
e.preventDefault();
// Validate URL
let url = inputGiteaUrl;
if (!url.startsWith("http")) {
url = `https://${url}`;
}
// Remove trailing slash if present
url = url.replace(/\/$/, "");
setGiteaUrl(url);
// Validate repo format
if (inputRepo.includes("/")) {
setRepo(inputRepo);
} else {
alert('Repository must be in format "owner/repo"');
}
};
// Example preset repositories
const presetRepos = [
{ label: "Documentation", value: "owner/docs" },
{ label: "API Server", value: "owner/api-server" },
{ label: "Web App", value: "owner/web-app" },
];
return (
<div className="gitea-widget border-[#e1e4e8] rounded-2xl shadow-sm border-l-8 border-l-lime-600">
<div className="github-widget-header rounded-t-2xl">
<FaServer className="gitea-icon" />
<h3>{title}</h3>
<button
className="advanced-toggle"
onClick={() => setShowAdvanced(!showAdvanced)}
>
{showAdvanced ? "Simple" : "Advanced"}
</button>
</div>
{showAdvanced ? (
<form onSubmit={handleSubmit} className="config-form">
<div className="form-group">
<label>
<FaServer /> Gitea Instance URL
</label>
<input
type="text"
value={inputGiteaUrl}
onChange={(e) => setInputGiteaUrl(e.target.value)}
placeholder="https://gitea.example.com"
className="url-input"
/>
</div>
<div className="form-group">
<label>
<FaCodeBranch /> Repository
</label>
<input
type="text"
value={inputRepo}
onChange={(e) => setInputRepo(e.target.value)}
placeholder="owner/repository"
className="repo-input"
/>
<div className="preset-repos">
{presetRepos.map((preset) => (
<button
key={preset.value}
type="button"
className="preset-btn"
onClick={() => setInputRepo(preset.value)}
>
{preset.label}
</button>
))}
</div>
</div>
<button type="submit" className="refresh-btn">
<FaSync /> Load Commits
</button>
</form>
) : (
<form onSubmit={handleSubmit} className="simple-form">
<div className="input-group">
<input
type="text"
value={inputRepo}
onChange={(e) => setInputRepo(e.target.value)}
placeholder="owner/repo"
className="simple-input"
/>
<button type="submit" className="simple-btn">
<FaSync />
</button>
</div>
</form>
)}
<div className="current-config">
<small>
Instance: <code>{giteaUrl}</code> | Repo: <code>{repo}</code> |
Branch: <code>{branch}</code>
</small>
</div>
<div className="widget-body">
{loading ? (
<div className="loading">
<div className="spinner"></div>
Loading commits from {repo}...
</div>
) : error ? (
<div className="error">
<FaExclamationTriangle />
<div className="error-details">
<p>Failed to load commits</p>
<small>{error}</small>
<p className="help-text">
Ensure:
<ul>
<li>Gitea instance is accessible</li>
<li>Repository exists and is accessible</li>
<li>API token has correct permissions (if private repo)</li>
</ul>
</p>
</div>
</div>
) : (
<div className="commits-list">
{commits.length > 0 ? (
commits.map((commit) => (
<GiteaCommitItem
key={commit.sha}
commit={commit}
giteaUrl={giteaUrl}
repo={repo}
/>
))
) : (
<div className="no-commits">
No commits found in the {branch} branch
</div>
)}
</div>
)}
</div>
<div className="widget-footer">
<a
href={`${giteaUrl}/${repo}`}
target="_blank"
rel="noopener noreferrer"
className="view-all"
>
View on Gitea
</a>
<span className="commit-count">{commits.length} commits shown</span>
</div>
</div>
);
};