chore: build
ci-api / test (push) Successful in 26m55s
ci-web / test (push) Successful in 14m57s

This commit is contained in:
Xor290
2026-08-18 14:46:05 +02:00
parent 02a5edd1b7
commit 955f2325fb
5 changed files with 87 additions and 0 deletions
+1
View File
@@ -210,6 +210,7 @@ export const api = {
deleteDemo: (id: string) => request<Demo>('DELETE', `/demos/${id}`),
setDemoDomain: (id: string, domain: string) =>
request<Demo>('POST', `/demos/${id}/domain`, { domain }),
transferDemoToPremium: (id: string) => request<Demo>('POST', `/demos/${id}/premium`),
listCodes: () => request<{ items: CodeBuySub[] }>('GET', '/codes'),
createCode: (username: string) =>
+51
View File
@@ -45,6 +45,7 @@ export function Demos() {
const [loading, setLoading] = useState(true)
const [busy, setBusy] = useState<string | null>(null)
const [toDelete, setToDelete] = useState<Demo | null>(null)
const [toPremium, setToPremium] = useState<Demo | null>(null)
const [createModalOpen, setCreateModalOpen] = useState(false)
const [editingDomain, setEditingDomain] = useState<Demo | null>(null)
@@ -105,6 +106,27 @@ export function Demos() {
}
}
const confirmTransferToPremium = async () => {
if (!toPremium) return
const d = toPremium
setBusy(d.id)
try {
await api.transferDemoToPremium(d.id)
toast({
status: 'success',
title: 'Démo passée en premium',
description: 'La migration des données tourne en tâche de fond.',
})
setToPremium(null)
await load()
} catch (err) {
const msg = err instanceof ApiError ? err.message : 'Erreur'
toast({ status: 'error', title: 'Passage en premium impossible', description: msg })
} finally {
setBusy(null)
}
}
const toggleRow = async (d: Demo) => {
if (expandedId === d.id) {
setExpandedId(null)
@@ -159,6 +181,18 @@ export function Demos() {
>
+30 j
</Button>
<Button
size="sm"
colorScheme="purple"
variant="outline"
isDisabled={!isAlive(d.status) || busy === d.id}
onClick={(e) => {
e.stopPropagation()
setToPremium(d)
}}
>
Passer en premium
</Button>
<Button
size="sm"
colorScheme="red"
@@ -336,6 +370,23 @@ export function Demos() {
libérées. Cette action est irréversible.
</ConfirmDialog>
<ConfirmDialog
isOpen={!!toPremium}
title="Passer cette démo en premium ?"
confirmLabel="Passer en premium"
confirmColorScheme="purple"
isLoading={!!toPremium && busy === toPremium.id}
onConfirm={confirmTransferToPremium}
onClose={() => setToPremium(null)}
>
La démo{' '}
<Text as="span" fontFamily="mono" fontWeight="semibold">
{toPremium?.namespace}
</Text>{' '}
n'expirera plus et sera migrée vers un namespace dédié (données conservées). Cette
opération tourne en tâche de fond et n'est pas instantanée.
</ConfirmDialog>
<EditDomainModal
demo={editingDomain}
onClose={() => setEditingDomain(null)}