import React, { useState } from 'react'; import { Key, Loader2, Plus, Trash2, Copy } from 'lucide-react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; import { createDeveloperApiKey, listDeveloperApiKeys, revokeDeveloperApiKey } from '../../api/client'; export const DeveloperApiKeysPanel: React.FC = () => { const [label, setLabel] = useState(''); const [revealedKey, setRevealedKey] = useState(null); const queryClient = useQueryClient(); const { data, isLoading } = useQuery({ queryKey: ['developer-api-keys'], queryFn: listDeveloperApiKeys, }); const createMutation = useMutation({ mutationFn: () => createDeveloperApiKey(label.trim()), onSuccess: (res) => { setRevealedKey(res.api_key); setLabel(''); queryClient.invalidateQueries({ queryKey: ['developer-api-keys'] }); toast.success('Klucz API utworzony — skopiuj go teraz (nie będzie widoczny ponownie).'); }, onError: () => toast.error('Nie udało się utworzyć klucza.'), }); const revokeMutation = useMutation({ mutationFn: revokeDeveloperApiKey, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['developer-api-keys'] }); toast.success('Klucz unieważniony.'); }, onError: () => toast.error('Nie udało się unieważnić klucza.'), }); const keys = data?.keys || []; return (

Public API v2 — klucze deweloperskie

Klucze umożliwiają dostęp do /api/v2/public/* (katalog naborów, health). Specyfikacja: /api/v2/public/openapi.json

{revealedKey && (
Nowy klucz (skopiuj teraz):
{revealedKey}
)}
setLabel(e.target.value)} style={{ flex: 1, minWidth: '200px', padding: '0.5rem 0.75rem', borderRadius: '6px', border: '1px solid rgba(255,255,255,0.15)', background: 'rgba(0,0,0,0.2)', color: '#fff' }} />
{isLoading ? ( ) : keys.length === 0 ? (

Brak aktywnych kluczy.

) : (
{keys.map((k) => (
{k.label}
{k.key_prefix}… · {new Date(k.created_at).toLocaleDateString('pl-PL')}
))}
)}
); }; export default DeveloperApiKeysPanel;