import React, { useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { githubApi } from "@/lib/api"; import type { GitHubConfig } from "@/types/config"; import { Input } from "../ui/input"; import { Checkbox } from "../ui/checkbox"; import { toast } from "sonner"; import { AlertTriangle } from "lucide-react"; import { Alert, AlertDescription } from "../ui/alert"; import { Info } from "lucide-react"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; interface GitHubConfigFormProps { config: GitHubConfig; setConfig: React.Dispatch>; } export function GitHubConfigForm({ config, setConfig }: GitHubConfigFormProps) { const [isLoading, setIsLoading] = useState(false); const handleChange = (e: React.ChangeEvent) => { const { name, value, type, checked } = e.target; // Special handling for preserveOrgStructure changes if ( name === "preserveOrgStructure" && config.preserveOrgStructure !== checked ) { toast.info( "Changing this setting may affect how repositories are accessed in Gitea. " + "Existing mirrored repositories will still be accessible during sync operations.", { duration: 6000, position: "top-center", } ); } setConfig({ ...config, [name]: type === "checkbox" ? checked : value, }); }; const testConnection = async () => { if (!config.token) { toast.error("GitHub token is required to test the connection"); return; } setIsLoading(true); try { const result = await githubApi.testConnection(config.token); if (result.success) { toast.success("Successfully connected to GitHub!"); } else { toast.error("Failed to connect to GitHub. Please check your token."); } } catch (error) { toast.error( error instanceof Error ? error.message : "An unknown error occurred" ); } finally { setIsLoading(false); } }; return ( GitHub Configuration

Required for private repositories, organizations, and starred repositories.

handleChange({ target: { name: "skipForks", type: "checkbox", checked: Boolean(checked), value: "", }, } as React.ChangeEvent) } />
handleChange({ target: { name: "privateRepositories", type: "checkbox", checked: Boolean(checked), value: "", }, } as React.ChangeEvent) } />
handleChange({ target: { name: "mirrorStarred", type: "checkbox", checked: Boolean(checked), value: "", }, } as React.ChangeEvent) } />
handleChange({ target: { name: "mirrorIssues", type: "checkbox", checked: Boolean(checked), value: "", }, } as React.ChangeEvent) } />
handleChange({ target: { name: "preserveOrgStructure", type: "checkbox", checked: Boolean(checked), value: "", }, } as React.ChangeEvent) } />
handleChange({ target: { name: "skipStarredIssues", type: "checkbox", checked: Boolean(checked), value: "", }, } as React.ChangeEvent) } />
Note:
You need to create a{" "} Classic GitHub PAT Token{" "} with following scopes:
  • repo
  • admin:org
The organization access is required for mirroring organization repositories.
You can generate tokens at{" "} github.com/settings/tokens .
); }