feat: refactor GiteaWidget to use environment variables and improve configuration options
This commit is contained in:
17
.env
17
.env
@@ -1,5 +1,12 @@
|
|||||||
REACT_APP_GITHUB_TOKEN=your_github_token_here
|
|
||||||
REACT_APP_GITEA_TOKEN=your_gitea_token_here
|
|
||||||
GITEA_API_URL='https://git.konceptkit.com/'
|
# Vite requires VITE_ prefix
|
||||||
GITHUB_API_URL='https://api.github.com/'
|
VITE_GITEA_API_URL=https://git.konceptkit.com
|
||||||
GITEA_ACCESS_TOKEN='de037d3d8b7268acd0dc734a83799e4f3761bad3'
|
VITE_DEFAULT_REPO=kayela/membership-fe
|
||||||
|
VITE_DEFAULT_BRANCH=main
|
||||||
|
VITE_COMMIT_LIMIT=10
|
||||||
|
VITE_SHOW_CONFIG=true
|
||||||
|
VITE_GITEA_TOKEN='de037d3d8b7268acd0dc734a83799e4f3761bad3'
|
||||||
|
|
||||||
|
# Public variables (exposed to client)
|
||||||
|
VITE_PUBLIC_SITE_NAME=My App
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.9",
|
||||||
"@types/react": "^19.2.5",
|
"@types/react": "^19.2.5",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
"@vitejs/plugin-react": "^5.1.1",
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.9",
|
||||||
"@types/react": "^19.2.5",
|
"@types/react": "^19.2.5",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
"@vitejs/plugin-react": "^5.1.1",
|
||||||
|
|||||||
14
src/App.tsx
14
src/App.tsx
@@ -3,18 +3,8 @@ import { GitHubWidget, GiteaWidget } from "./components/GitWidget";
|
|||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<div className="bg-slate-800 py-20">
|
<div className="bg-slate-800 py-20 ">
|
||||||
<GitHubWidget
|
<GiteaWidget limit={8} title="Recent Activity" />
|
||||||
defaultRepo="kayela-c/puck"
|
|
||||||
limit={8}
|
|
||||||
title="Recent Activity"
|
|
||||||
// token={process.env.REACT_APP_GITHUB_TOKEN} // Optional for private repos
|
|
||||||
/>
|
|
||||||
<GiteaWidget
|
|
||||||
defaultRepo="andika/membership-fe"
|
|
||||||
limit={8}
|
|
||||||
title="Recent Activity"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import React, { useState } from "react";
|
|||||||
import useGitHubCommits from "../../hooks/useGitHubCommits";
|
import useGitHubCommits from "../../hooks/useGitHubCommits";
|
||||||
import GitHubCommitItem from "./GitHubCommitItem";
|
import GitHubCommitItem from "./GitHubCommitItem";
|
||||||
import { FaGithub, FaSync, FaExclamationTriangle } from "react-icons/fa";
|
import { FaGithub, FaSync, FaExclamationTriangle } from "react-icons/fa";
|
||||||
|
|
||||||
import "../../styles/GitHubWidget.css";
|
import "../../styles/GitHubWidget.css";
|
||||||
|
|
||||||
export const GitHubWidget = ({
|
export const GitHubWidget = ({
|
||||||
@@ -74,10 +73,9 @@ export const GitHubWidget = ({
|
|||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="github-view-all"
|
className="github-view-all"
|
||||||
>
|
>
|
||||||
View Git →
|
View on GitHub →
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,147 +1,197 @@
|
|||||||
import React, { useState } from "react";
|
// components/GiteaWidget/GiteaWidget.jsx
|
||||||
import useGiteaCommits from "../../hooks/useGiteaCommits";
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import useGiteaCommits from '../../hooks/useGiteaCommits';
|
||||||
import GiteaCommitItem from "./GiteaCommitItem";
|
import GiteaCommitItem from "./GiteaCommitItem";
|
||||||
import "../../styles/GiteaWidget.css";
|
import { FaCodeBranch, FaSync, FaExclamationTriangle, FaServer, FaCog } from 'react-icons/fa';
|
||||||
import {
|
import '../../styles/GiteaWidget.css';
|
||||||
FaCodeBranch,
|
|
||||||
FaSync,
|
|
||||||
FaExclamationTriangle,
|
|
||||||
FaServer,
|
|
||||||
} from "react-icons/fa";
|
|
||||||
|
|
||||||
export const GiteaWidget = ({
|
// Get environment variables from import.meta.env
|
||||||
defaultGiteaUrl = "https://git.konceptkit.com/",
|
const ENV = {
|
||||||
defaultRepo = "owner/repo",
|
GITEA_API_URL: import.meta.env.VITE_GITEA_API_URL,
|
||||||
token = null,
|
DEFAULT_REPO: import.meta.env.VITE_DEFAULT_REPO,
|
||||||
limit = 5,
|
GITEA_TOKEN: import.meta.env.VITE_GITEA_TOKEN,
|
||||||
branch = "main",
|
COMMIT_LIMIT: parseInt(import.meta.env.VITE_COMMIT_LIMIT) || 5,
|
||||||
title = "Recent Commits",
|
DEFAULT_BRANCH: import.meta.env.VITE_DEFAULT_BRANCH,
|
||||||
|
SHOW_CONFIG: import.meta.env.VITE_SHOW_CONFIG !== 'false',
|
||||||
|
MODE: import.meta.env.MODE, // 'development', 'production', etc.
|
||||||
|
DEV: import.meta.env.DEV,
|
||||||
|
PROD: import.meta.env.PROD
|
||||||
|
};
|
||||||
|
|
||||||
|
const GiteaWidget = ({
|
||||||
|
// Use environment variables as defaults
|
||||||
|
defaultGiteaUrl = ENV.GITEA_API_URL || 'https://gitea.example.com',
|
||||||
|
defaultRepo = ENV.DEFAULT_REPO || 'owner/repo',
|
||||||
|
token = ENV.GITEA_TOKEN || null,
|
||||||
|
limit = ENV.COMMIT_LIMIT || 5,
|
||||||
|
branch = ENV.DEFAULT_BRANCH || 'main',
|
||||||
|
title = 'Recent Commits',
|
||||||
|
showConfig = ENV.SHOW_CONFIG
|
||||||
}) => {
|
}) => {
|
||||||
const [giteaUrl, setGiteaUrl] = useState(defaultGiteaUrl);
|
const [giteaUrl, setGiteaUrl] = useState(defaultGiteaUrl);
|
||||||
const [repo, setRepo] = useState(defaultRepo);
|
const [repo, setRepo] = useState(defaultRepo);
|
||||||
const [inputGiteaUrl, setInputGiteaUrl] = useState(defaultGiteaUrl);
|
const [inputGiteaUrl, setInputGiteaUrl] = useState(defaultGiteaUrl);
|
||||||
const [inputRepo, setInputRepo] = useState(defaultRepo);
|
const [inputRepo, setInputRepo] = useState(defaultRepo);
|
||||||
const [showAdvanced, setShowAdvanced] = useState(false);
|
const [showAdvanced, setShowAdvanced] = useState(false);
|
||||||
|
|
||||||
|
// Log environment variables in development
|
||||||
|
useEffect(() => {
|
||||||
|
if (ENV.DEV) {
|
||||||
|
console.log('Vite Environment Variables:', {
|
||||||
|
GITEA_API_URL: ENV.GITEA_API_URL,
|
||||||
|
DEFAULT_REPO: ENV.DEFAULT_REPO,
|
||||||
|
hasToken: !!ENV.GITEA_TOKEN,
|
||||||
|
MODE: ENV.MODE,
|
||||||
|
allEnv: import.meta.env
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const { commits, loading, error } = useGiteaCommits(
|
const { commits, loading, error } = useGiteaCommits(
|
||||||
giteaUrl,
|
giteaUrl,
|
||||||
repo,
|
repo,
|
||||||
token,
|
token,
|
||||||
limit,
|
limit,
|
||||||
branch
|
branch
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Validate URL
|
// Validate URL
|
||||||
let url = inputGiteaUrl;
|
let url = inputGiteaUrl?.trim();
|
||||||
if (!url.startsWith("http")) {
|
if (url && !url.startsWith('http')) {
|
||||||
url = `https://${url}`;
|
url = `https://${url}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove trailing slash if present
|
// Remove trailing slash if present
|
||||||
url = url.replace(/\/$/, "");
|
url = url?.replace(/\/$/, '') || defaultGiteaUrl;
|
||||||
|
|
||||||
setGiteaUrl(url);
|
setGiteaUrl(url);
|
||||||
|
|
||||||
// Validate repo format
|
// Validate repo format
|
||||||
if (inputRepo.includes("/")) {
|
if (inputRepo.includes('/')) {
|
||||||
setRepo(inputRepo);
|
setRepo(inputRepo);
|
||||||
} else {
|
} else {
|
||||||
alert('Repository must be in format "owner/repo"');
|
alert('Repository must be in format "owner/repo"');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example preset repositories
|
// Reset to environment defaults
|
||||||
const presetRepos = [
|
const resetToDefaults = () => {
|
||||||
{ label: "Documentation", value: "owner/docs" },
|
setGiteaUrl(defaultGiteaUrl);
|
||||||
{ label: "API Server", value: "owner/api-server" },
|
setRepo(defaultRepo);
|
||||||
{ label: "Web App", value: "owner/web-app" },
|
setInputGiteaUrl(defaultGiteaUrl);
|
||||||
];
|
setInputRepo(defaultRepo);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gitea-widget border-[#e1e4e8] rounded-2xl shadow-sm border-l-8 border-l-lime-600">
|
<div className="gitea-widget">
|
||||||
<div className="github-widget-header rounded-t-2xl">
|
<div className="widget-header">
|
||||||
<FaServer className="gitea-icon" />
|
<FaServer className="gitea-icon" />
|
||||||
<h3>{title}</h3>
|
<h3>{title}</h3>
|
||||||
|
<span className="env-badge">
|
||||||
<button
|
{ENV.MODE === 'development' ? 'DEV' : ENV.MODE}
|
||||||
className="advanced-toggle"
|
</span>
|
||||||
onClick={() => setShowAdvanced(!showAdvanced)}
|
|
||||||
>
|
{showConfig && (
|
||||||
{showAdvanced ? "Simple" : "Advanced"}
|
<div className="header-controls">
|
||||||
</button>
|
<button
|
||||||
|
className="advanced-toggle"
|
||||||
|
onClick={() => setShowAdvanced(!showAdvanced)}
|
||||||
|
title={showAdvanced ? 'Hide configuration' : 'Show configuration'}
|
||||||
|
>
|
||||||
|
{showAdvanced ? 'Simple' : 'Configure'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="reset-btn"
|
||||||
|
onClick={resetToDefaults}
|
||||||
|
title="Reset to default configuration"
|
||||||
|
>
|
||||||
|
<FaCog />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showAdvanced ? (
|
{/* Configuration form */}
|
||||||
|
{showConfig && showAdvanced && (
|
||||||
<form onSubmit={handleSubmit} className="config-form">
|
<form onSubmit={handleSubmit} className="config-form">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>
|
<label>
|
||||||
<FaServer /> Gitea Instance URL
|
<FaServer /> Gitea Instance URL
|
||||||
|
<span className="env-indicator">
|
||||||
|
{inputGiteaUrl === defaultGiteaUrl ? '(from .env)' : '(custom)'}
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={inputGiteaUrl}
|
value={inputGiteaUrl}
|
||||||
onChange={(e) => setInputGiteaUrl(e.target.value)}
|
onChange={(e) => setInputGiteaUrl(e.target.value)}
|
||||||
placeholder="https://gitea.example.com"
|
placeholder={defaultGiteaUrl}
|
||||||
className="url-input"
|
className="url-input"
|
||||||
/>
|
/>
|
||||||
|
<small className="help-text">
|
||||||
|
Default from .env: <code>{defaultGiteaUrl}</code>
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>
|
<label>
|
||||||
<FaCodeBranch /> Repository
|
<FaCodeBranch /> Repository
|
||||||
|
<span className="env-indicator">
|
||||||
|
{inputRepo === defaultRepo ? '(from .env)' : '(custom)'}
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={inputRepo}
|
value={inputRepo}
|
||||||
onChange={(e) => setInputRepo(e.target.value)}
|
onChange={(e) => setInputRepo(e.target.value)}
|
||||||
placeholder="owner/repository"
|
placeholder={defaultRepo}
|
||||||
className="repo-input"
|
className="repo-input"
|
||||||
/>
|
/>
|
||||||
<div className="preset-repos">
|
<small className="help-text">
|
||||||
{presetRepos.map((preset) => (
|
Format: owner/repo | Default from .env: <code>{defaultRepo}</code>
|
||||||
<button
|
</small>
|
||||||
key={preset.value}
|
|
||||||
type="button"
|
|
||||||
className="preset-btn"
|
|
||||||
onClick={() => setInputRepo(preset.value)}
|
|
||||||
>
|
|
||||||
{preset.label}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" className="refresh-btn">
|
<div className="form-actions">
|
||||||
<FaSync /> Load Commits
|
<button type="submit" className="refresh-btn">
|
||||||
</button>
|
<FaSync /> Load Commits
|
||||||
</form>
|
</button>
|
||||||
) : (
|
<button type="button" className="cancel-btn" onClick={() => setShowAdvanced(false)}>
|
||||||
<form onSubmit={handleSubmit} className="simple-form">
|
Cancel
|
||||||
<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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Current configuration display */}
|
||||||
<div className="current-config">
|
<div className="current-config">
|
||||||
<small>
|
<div className="config-info">
|
||||||
Instance: <code>{giteaUrl}</code> | Repo: <code>{repo}</code> |
|
<span className="config-item">
|
||||||
Branch: <code>{branch}</code>
|
<FaServer /> <strong>Instance:</strong>
|
||||||
</small>
|
<code>{giteaUrl === defaultGiteaUrl ? 'Default' : 'Custom'}</code>
|
||||||
|
</span>
|
||||||
|
<span className="config-item">
|
||||||
|
<FaCodeBranch /> <strong>Repo:</strong>
|
||||||
|
<code>{repo}</code>
|
||||||
|
</span>
|
||||||
|
<span className="config-item">
|
||||||
|
<strong>Branch:</strong> <code>{branch}</code>
|
||||||
|
</span>
|
||||||
|
<span className="config-item">
|
||||||
|
<strong>Showing:</strong> <code>{limit} commits</code>
|
||||||
|
</span>
|
||||||
|
{ENV.DEV && (
|
||||||
|
<span className="config-item">
|
||||||
|
<strong>Mode:</strong> <code className="mode-dev">{ENV.MODE}</code>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Widget body */}
|
||||||
<div className="widget-body">
|
<div className="widget-body">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="loading">
|
<div className="loading">
|
||||||
@@ -154,22 +204,25 @@ export const GiteaWidget = ({
|
|||||||
<div className="error-details">
|
<div className="error-details">
|
||||||
<p>Failed to load commits</p>
|
<p>Failed to load commits</p>
|
||||||
<small>{error}</small>
|
<small>{error}</small>
|
||||||
<p className="help-text">
|
{ENV.DEV && (
|
||||||
Ensure:
|
<div className="debug-info">
|
||||||
<ul>
|
<p>Debug info:</p>
|
||||||
<li>Gitea instance is accessible</li>
|
<ul>
|
||||||
<li>Repository exists and is accessible</li>
|
<li>URL: {giteaUrl}</li>
|
||||||
<li>API token has correct permissions (if private repo)</li>
|
<li>Repo: {repo}</li>
|
||||||
</ul>
|
<li>Has Token: {token ? 'Yes' : 'No'}</li>
|
||||||
</p>
|
<li>Mode: {ENV.MODE}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="commits-list">
|
<div className="commits-list">
|
||||||
{commits.length > 0 ? (
|
{commits.length > 0 ? (
|
||||||
commits.map((commit) => (
|
commits.map((commit) => (
|
||||||
<GiteaCommitItem
|
<GiteaCommitItem
|
||||||
key={commit.sha}
|
key={commit.sha}
|
||||||
commit={commit}
|
commit={commit}
|
||||||
giteaUrl={giteaUrl}
|
giteaUrl={giteaUrl}
|
||||||
repo={repo}
|
repo={repo}
|
||||||
@@ -183,9 +236,9 @@ export const GiteaWidget = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="widget-footer">
|
<div className="widget-footer">
|
||||||
<a
|
<a
|
||||||
href={`${giteaUrl}/${repo}`}
|
href={`${giteaUrl}/${repo}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
@@ -193,8 +246,24 @@ export const GiteaWidget = ({
|
|||||||
>
|
>
|
||||||
View on Gitea →
|
View on Gitea →
|
||||||
</a>
|
</a>
|
||||||
<span className="commit-count">{commits.length} commits shown</span>
|
<span className="commit-count">
|
||||||
|
{commits.length} commits shown
|
||||||
|
{ENV.DEV && ` (${ENV.MODE})`}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add default props using environment variables
|
||||||
|
GiteaWidget.defaultProps = {
|
||||||
|
defaultGiteaUrl: ENV.GITEA_API_URL || 'https://gitea.example.com',
|
||||||
|
defaultRepo: ENV.DEFAULT_REPO || 'owner/repo',
|
||||||
|
token: ENV.GITEA_TOKEN || null,
|
||||||
|
limit: ENV.COMMIT_LIMIT || 5,
|
||||||
|
branch: ENV.DEFAULT_BRANCH || 'main',
|
||||||
|
title: 'Recent Commits',
|
||||||
|
showConfig: ENV.SHOW_CONFIG
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GiteaWidget;
|
||||||
Reference in New Issue
Block a user