Files
cloud-host/frontend/src/components/deleting-overlay.tsx
T
keyhan e99ab789ba Localize shared modal, overlay and deployment-progress components.
Localize the confirm modal, delete button, deleting overlays/modal, the
build-progress modal, deployment progress bar/manager and the resource
upgrade modal via a shared components dictionary. Build-phase labels now
resolve from the dictionary; deleting overlays take name/kind and build
their own localized message (callers updated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:23:44 +03:30

77 lines
2.5 KiB
TypeScript

'use client';
import { Clock } from 'lucide-react';
import { useT } from '@/i18n/I18nProvider';
type ResourceKind = 'application' | 'service';
/** Resolve the "Deleting …" message for a resource using the active dictionary. */
function useDeletingMessage(message: string | undefined, name: string | undefined, kind: ResourceKind) {
const t = useT();
if (message) return message;
if (name) return t.components.deletingNamed.replace('{name}', name);
return kind === 'service' ? t.components.deletingService : t.components.deletingApplication;
}
/** Applied to row cells under the glass overlay so content stays visible but blurred. */
export const deletingRowContentClass =
'opacity-45 blur-[2px] pointer-events-none select-none transition-[filter,opacity] duration-200';
const glassPanelClass =
'flex min-h-[52px] h-full w-full items-center justify-center gap-2 bg-white/45 backdrop-blur-md text-sm font-semibold text-gray-900 ring-1 ring-inset ring-white/50';
/**
* Glass overlay on a table row. Parent `<tr>` must be `relative`; render all `<td>` cells first,
* then this as the last child while deleting. Pass either an explicit `message`, or `name`/`kind`
* to have the localized message built for you.
*/
export function DeletingTableRowOverlay({
colSpan,
message,
name,
kind = 'application',
}: {
colSpan: number;
message?: string;
name?: string;
kind?: ResourceKind;
}) {
const text = useDeletingMessage(message, name, kind);
return (
<td
colSpan={colSpan}
className="!absolute inset-0 z-10 border-0 p-0 m-0 h-full w-full max-w-none bg-transparent"
aria-live="polite"
aria-busy="true"
>
<div className={glassPanelClass}>
<Clock className="w-4 h-4 shrink-0 animate-spin text-red-600" />
<span>{text}</span>
</div>
</td>
);
}
/** Full-card glass overlay while delete is in progress. Parent must be `relative`. */
export function DeletingCardOverlay({
message,
name,
kind = 'application',
}: {
message?: string;
name?: string;
kind?: ResourceKind;
}) {
const text = useDeletingMessage(message, name, kind);
return (
<div
className="absolute inset-0 z-20 flex items-center justify-center gap-2 rounded-xl bg-white/45 backdrop-blur-md text-sm font-semibold text-gray-900 ring-1 ring-inset ring-white/50"
aria-live="polite"
aria-busy="true"
>
<Clock className="w-4 h-4 shrink-0 animate-spin text-red-600" />
<span>{text}</span>
</div>
);
}