chore: build
ci-web / test (push) Successful in 15m6s

This commit is contained in:
Xor290
2026-08-18 20:28:18 +02:00
parent dfc62c305d
commit 47a11b6601
+57 -1
View File
@@ -28,6 +28,7 @@ import { useNavigate } from 'react-router-dom'
import { api, ApiError, type Demo, type DemoDetails } from '../../lib/api' import { api, ApiError, type Demo, type DemoDetails } from '../../lib/api'
import { statusColor, statusLabel } from '../../lib/format' import { statusColor, statusLabel } from '../../lib/format'
import { ChevronIcon, PodStatusPanel } from '../../components/PodStatusPanel' import { ChevronIcon, PodStatusPanel } from '../../components/PodStatusPanel'
import { ConfirmDialog } from '../../components/ConfirmDialog'
import { CreateDemoModal } from '../../components/CreateDemoModal' import { CreateDemoModal } from '../../components/CreateDemoModal'
import { EditDomainModal } from '../../components/EditDomainModal' import { EditDomainModal } from '../../components/EditDomainModal'
import { DemoCard } from '../../components/DemoCard' import { DemoCard } from '../../components/DemoCard'
@@ -42,6 +43,8 @@ export function PremiumDemos() {
const navigate = useNavigate() const navigate = useNavigate()
const [demos, setDemos] = useState<Demo[]>([]) const [demos, setDemos] = useState<Demo[]>([])
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [busy, setBusy] = useState<string | null>(null)
const [toDelete, setToDelete] = useState<Demo | null>(null)
const [createModalOpen, setCreateModalOpen] = useState(false) const [createModalOpen, setCreateModalOpen] = useState(false)
const [editingDomain, setEditingDomain] = useState<Demo | null>(null) const [editingDomain, setEditingDomain] = useState<Demo | null>(null)
@@ -68,6 +71,23 @@ export function PremiumDemos() {
return () => clearInterval(id) return () => clearInterval(id)
}, [load]) }, [load])
const confirmDestroy = async () => {
if (!toDelete) return
const d = toDelete
setBusy(d.id)
try {
await api.deleteDemo(d.id)
toast({ status: 'success', title: 'Plateforme détruite' })
setToDelete(null)
await load()
} catch (err) {
const msg = err instanceof ApiError ? err.message : 'Erreur'
toast({ status: 'error', title: 'Destruction impossible', description: msg })
} finally {
setBusy(null)
}
}
const toggleRow = async (d: Demo) => { const toggleRow = async (d: Demo) => {
if (expandedId === d.id) { if (expandedId === d.id) {
setExpandedId(null) setExpandedId(null)
@@ -107,6 +127,21 @@ export function PremiumDemos() {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [expandedId]) }, [expandedId])
const renderActions = (d: Demo) => (
<Button
size="sm"
colorScheme="red"
variant="outline"
isDisabled={busy === d.id}
onClick={(e) => {
e.stopPropagation()
setToDelete(d)
}}
>
Détruire
</Button>
)
return ( return (
<> <>
<Flex mb={2} align="center" gap={4} wrap="wrap"> <Flex mb={2} align="center" gap={4} wrap="wrap">
@@ -143,6 +178,7 @@ export function PremiumDemos() {
<Th>Client</Th> <Th>Client</Th>
<Th>Statut</Th> <Th>Statut</Th>
<Th>URL</Th> <Th>URL</Th>
<Th></Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
@@ -198,9 +234,12 @@ export function PremiumDemos() {
/> />
</HStack> </HStack>
</Td> </Td>
<Td textAlign="right">
<HStack justify="flex-end">{renderActions(d)}</HStack>
</Td>
</Tr> </Tr>
<Tr> <Tr>
<Td p={0} border={isOpen ? undefined : 'none'} colSpan={4}> <Td p={0} border={isOpen ? undefined : 'none'} colSpan={5}>
<Collapse in={isOpen} unmountOnExit animateOpacity> <Collapse in={isOpen} unmountOnExit animateOpacity>
<Box p={4} bg="chakra-subtle-bg" borderTopWidth="1px"> <Box p={4} bg="chakra-subtle-bg" borderTopWidth="1px">
{detailsLoading && !details ? ( {detailsLoading && !details ? (
@@ -234,12 +273,29 @@ export function PremiumDemos() {
detailsLoading={detailsLoading} detailsLoading={detailsLoading}
details={expandedId === d.id ? details : null} details={expandedId === d.id ? details : null}
onEditDomain={() => setEditingDomain(d)} onEditDomain={() => setEditingDomain(d)}
actions={renderActions(d)}
/> />
))} ))}
</Stack> </Stack>
</> </>
)} )}
<ConfirmDialog
isOpen={!!toDelete}
title="Détruire la plateforme premium ?"
confirmLabel="Détruire"
isLoading={!!toDelete && busy === toDelete.id}
onConfirm={confirmDestroy}
onClose={() => setToDelete(null)}
>
La plateforme{' '}
<Text as="span" fontFamily="mono" fontWeight="semibold">
{toDelete?.namespace}
</Text>{' '}
et toutes ses données (client payant) seront supprimées définitivement. Cette action est
irréversible.
</ConfirmDialog>
<EditDomainModal <EditDomainModal
demo={editingDomain} demo={editingDomain}
onClose={() => setEditingDomain(null)} onClose={() => setEditingDomain(null)}