import { useState } from 'react'; import { Loader2 } from 'lucide-react'; import { useClient } from 'hooks/useClient'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; // Where the instance and the token are set. // // Two halves, and which one you get depends on who you are. The URL is the OWNER'S — one instance per // server — and everyone else supplies only a token, inheriting the owner's URL. That is not a UI choice: // `service_connections` stores a member's row with a null URL for exactly this reason, so that "members // never see the instance URL" is a property of the schema rather than a filter somebody has to remember. // // A blank token on save means "keep the stored one", so the URL can be corrected without re-pasting a // token. There is no way to read one back out. export type ConnectionState = { configured: boolean; url?: string | null; user?: string | null; isOwner?: boolean; }; type Props = { state: ConnectionState; onSaved: () => void }; export const GiteaConnection = ({ state, onSaved }: Props) => { const { put } = useClient(); // Loopback is the right default and worth putting in front of someone: the sidecar fetches // SERVER-SIDE, so `localhost` means the machine Officer runs on. It needs no TLS and never leaves the // box — where the public URL would take the same traffic out and back. const [url, setUrl] = useState(state.url ?? 'http://localhost:3000'); const [token, setToken] = useState(''); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const save = async () => { setBusy(true); setError(null); try { await put('/gitea/_config', state.isOwner === false ? { token } : { url, token }); onSaved(); } catch (err) { setError(err instanceof Error ? err.message : 'could not save'); } finally { setBusy(false); } }; return (

Connect Gitea

{state.isOwner === false ? 'Your own access token. The instance is already set.' : 'Where Gitea runs, and a token for it.'}

{state.isOwner !== false && ( )} {error &&

{error}

}
); };