import { useQuery } from '@tanstack/react-query'; import { KeySquareIcon } from 'lucide-react'; import { useState } from 'react'; import { Badge } from '#/components/atoms/badge.jsx'; import { Button } from '#/components/atoms/button.jsx'; import { Panel } from '#/components/atoms/panel.jsx'; import { RowIcon } from '#/components/atoms/row-icon.jsx'; import { CheckboxField } from '#/components/molecules/checkbox-field.jsx'; import { ErrorNotice } from '#/components/molecules/error-notice.jsx'; import { FormShell } from '#/components/molecules/form-shell.jsx'; import { ListRow } from '#/components/molecules/list-row.jsx'; import { Section } from '#/components/molecules/section.jsx'; import { TextField } from '#/components/molecules/text-field.jsx'; import { get, post } from '#/lib/api.js'; import { day } from '#/lib/format.js'; import { queryKeys, useApiMutation, useInvalidate } from '#/lib/query.js'; export function AppPasswordsCard() { const { data, error } = useQuery({ queryKey: queryKeys.appPasswords, queryFn: () => get('/app-passwords'), }); const action = useApiMutation([queryKeys.appPasswords]); const invalidate = useInvalidate(); const [created, setCreated] = useState(null); const revoke = (name) => action.run(async () => { await post('/app-passwords/revoke', { name }); setCreated(null); }); return (
{created && (
New app password {created.name}
{created.password}
Copy it now. Only its hash is stored, so it cannot be shown again.
)} {data && data.passwords.length > 0 && (
{data.passwords.map((entry) => ( } title={ <> {entry.name} {entry.privileged && privileged} } description={`Created ${day(entry.createdAt)}`} actions={ } /> ))}
)} { const result = await post('/app-passwords/create', { name: values.name, privileged: values.privileged != null, }); setCreated(result); invalidate([queryKeys.appPasswords]); }} >
); }