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>
This commit is contained in:
keyhan
2026-06-11 13:23:44 +03:30
parent f8ee1ca168
commit e99ab789ba
14 changed files with 205 additions and 86 deletions
+29 -24
View File
@@ -1,15 +1,16 @@
'use client';
import { Clock } from 'lucide-react';
import { useT } from '@/i18n/I18nProvider';
export function deletingResourceMessage(
kind: 'application' | 'service',
name?: string,
): string {
if (kind === 'service') {
return name ? `Deleting “${name}”…` : 'Deleting service…';
}
return name ? `Deleting “${name}”…` : 'Deleting application…';
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. */
@@ -21,15 +22,21 @@ const glassPanelClass =
/**
* Glass overlay on a table row. Parent `<tr>` must be `relative`; render all `<td>` cells first,
* then this as the last child while deleting.
* 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 = 'Deleting…',
message,
name,
kind = 'application',
}: {
colSpan: number;
message?: string;
name?: string;
kind?: ResourceKind;
}) {
const text = useDeletingMessage(message, name, kind);
return (
<td
colSpan={colSpan}
@@ -39,25 +46,23 @@ export function DeletingTableRowOverlay({
>
<div className={glassPanelClass}>
<Clock className="w-4 h-4 shrink-0 animate-spin text-red-600" />
<span>{message}</span>
<span>{text}</span>
</div>
</td>
);
}
/** @deprecated Use DeletingTableRowOverlay on top of visible row cells */
export function DeletingTableRowCell({
colSpan,
message = 'Deleting…',
}: {
colSpan: number;
message?: string;
}) {
return <DeletingTableRowOverlay colSpan={colSpan} message={message} />;
}
/** Full-card glass overlay while delete is in progress. Parent must be `relative`. */
export function DeletingCardOverlay({ message = 'Deleting…' }: { message?: string }) {
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"
@@ -65,7 +70,7 @@ export function DeletingCardOverlay({ message = 'Deleting…' }: { message?: str
aria-busy="true"
>
<Clock className="w-4 h-4 shrink-0 animate-spin text-red-600" />
<span>{message}</span>
<span>{text}</span>
</div>
);
}