feat: refine launcher admin and showcase UI

This commit is contained in:
DCCONSTRUCTIONS
2026-05-01 21:00:51 +03:00
parent e8c6e76885
commit db0eabe7d7
13 changed files with 897 additions and 189 deletions
+47 -1
View File
@@ -92,6 +92,23 @@ export function LauncherApp() {
setSelectedServiceId((current) => (current === serviceId ? undefined : serviceId));
}
function handleStageStep(direction: "previous" | "next") {
if (!launcherServices.length) return;
setSelectedServiceId((current) => {
const currentIndex = current ? launcherServices.findIndex((service) => service.id === current) : -1;
const fallbackIndex = direction === "next" ? 0 : launcherServices.length - 1;
const nextIndex =
currentIndex === -1
? fallbackIndex
: direction === "next"
? (currentIndex + 1) % launcherServices.length
: (currentIndex - 1 + launcherServices.length) % launcherServices.length;
return launcherServices[nextIndex]?.id;
});
}
function handleCreateGrant(grant: Omit<ServiceGrant, "id" | "status" | "createdAt" | "updatedAt">) {
setData((current) => ({
...current,
@@ -183,6 +200,28 @@ export function LauncherApp() {
}));
}
function handleReorderServices(orderedServiceIds: string[]) {
setData((current) => {
const orderById = new Map(orderedServiceIds.map((serviceId, index) => [serviceId, (index + 1) * 10]));
const now = new Date().toISOString();
return {
...current,
services: current.services.map((service) => {
const nextOrder = orderById.get(service.id);
return nextOrder
? {
...service,
order: nextOrder,
updatedAt: now,
}
: service;
}),
};
});
}
function handleCreateService() {
const createdAt = new Date().toISOString();
@@ -248,7 +287,13 @@ export function LauncherApp() {
/>
<main className="launcher-main">
<ServiceStage service={selectedService} hasServices={launcherServices.length > 0} onLaunch={handleLaunch} />
<ServiceStage
service={selectedService}
hasServices={launcherServices.length > 0}
onLaunch={handleLaunch}
onSelectPrevious={() => handleStageStep("previous")}
onSelectNext={() => handleStageStep("next")}
/>
{adminOpen && me.permissions.canOpenAdmin ? (
<AdminOverlay
data={data}
@@ -261,6 +306,7 @@ export function LauncherApp() {
onCreateInvite={handleCreateInvite}
onRetrySync={handleRetrySync}
onUpdateService={handleUpdateService}
onReorderServices={handleReorderServices}
onCreateService={handleCreateService}
onDeleteService={handleDeleteService}
/>