feat(studio): localize catalog studio UI and polish responsive layout
Route all Catalog Studio strings through the admin.studio namespace (workspace, filters, review, inspector, quality, sync, scale32, organize imports and page titles/subtitles) with English fallback, and add shared StudioPage chrome plus a loading skeleton. Tighten mobile padding on the header and sub-bars.
This commit is contained in:
1 parent
d7d6382b60
commit
56676effc3
28 files changed
+1293
-634
No files matched your search
@@ -15,11 +15,7 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { previewAutoCatalog } from "@/lib/furni/auto-catalog";
|
||||
import { FurnitureInspector } from "./furniture-inspector";
|
||||
import {
|
||||
getFurniImageUrl,
|
||||
handleImgError,
|
||||
TYPE_LABELS,
|
||||
} from "./studio-furni-icons";
|
||||
import { getFurniImageUrl, handleImgError } from "./studio-furni-icons";
|
||||
import type { FurniItem } from "./studio-types";
|
||||
|
||||
interface FurnitureDetailDrawerProps {
|
||||
@@ -49,6 +45,10 @@ export function FurnitureDetailDrawer({
|
||||
onRepair,
|
||||
}: FurnitureDetailDrawerProps) {
|
||||
const t = useTranslations("admin.studio.completeness");
|
||||
const studioT = useTranslations("admin.studio");
|
||||
const drawerT = useTranslations("admin.studio.drawer");
|
||||
const typeLabel =
|
||||
detail.type === "wallitem" ? studioT("types.wall") : studioT("types.floor");
|
||||
const detailPreview = previewAutoCatalog(
|
||||
detail.classname,
|
||||
detail.type === "wallitem" ? "i" : "s",
|
||||
@@ -57,11 +57,11 @@ export function FurnitureDetailDrawer({
|
||||
<aside className="absolute inset-y-0 right-0 z-20 flex h-full w-[min(28rem,100%)] shrink-0 flex-col border-l border-[var(--admin-border)] bg-[var(--admin-surface)] shadow-xl lg:static lg:h-full lg:shadow-none">
|
||||
<div className="flex shrink-0 items-center justify-between border-b border-[var(--admin-border)] px-3 py-2.5">
|
||||
<span className="text-xs font-bold uppercase tracking-wider text-[var(--admin-text-muted)]">
|
||||
Furni detail
|
||||
{drawerT("title")}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Close furniture details"
|
||||
aria-label={studioT("aria.closeDetails")}
|
||||
onClick={onClose}
|
||||
className="rounded-md p-1 text-[var(--admin-text-muted)] hover:bg-[var(--admin-accent)]/10 hover:text-[var(--admin-text)]"
|
||||
>
|
||||
@@ -101,17 +101,17 @@ export function FurnitureDetailDrawer({
|
||||
) : null}
|
||||
|
||||
<div className="mb-4 flex flex-wrap gap-1.5">
|
||||
<Badge variant="secondary">{typeLabel}</Badge>
|
||||
<Badge variant="secondary">
|
||||
{TYPE_LABELS[detail.type] ?? detail.type}
|
||||
{drawerT("revision", { revision: detail.revision })}
|
||||
</Badge>
|
||||
<Badge variant="secondary">rev {detail.revision}</Badge>
|
||||
{detail.alreadyImported ? (
|
||||
<Badge className="text-[var(--admin-success)] border-[var(--admin-success)]/40">
|
||||
<Check size={10} /> {t("parts.sql")}: {t("statuses.present")}
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge className="text-[var(--admin-accent-foreground)]">
|
||||
<Sparkles size={10} /> Auto-import ready
|
||||
<Sparkles size={10} /> {drawerT("autoImportReady")}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
@@ -127,22 +127,30 @@ export function FurnitureDetailDrawer({
|
||||
<div className="mb-4 rounded-lg border border-[var(--admin-border)] bg-[var(--admin-canvas)] p-3">
|
||||
<div className="mb-2 flex items-center gap-1.5 text-[0.65rem] font-bold uppercase tracking-wider text-[var(--admin-text-muted)]">
|
||||
<WandSparkles size={12} className="text-[var(--admin-accent)]" />
|
||||
Automatic placement
|
||||
{drawerT("automaticPlacement")}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-[var(--admin-text-muted)]">Category</span>
|
||||
<span className="text-[var(--admin-text-muted)]">
|
||||
{drawerT("category")}
|
||||
</span>
|
||||
<span className="font-semibold text-[var(--admin-text)]">
|
||||
{detailPreview.categoryLabel}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-[var(--admin-text-muted)]">Price</span>
|
||||
<span className="text-[var(--admin-text-muted)]">
|
||||
{drawerT("price")}
|
||||
</span>
|
||||
<span className="font-semibold text-[var(--admin-text)]">
|
||||
{detailPreview.credits} credits
|
||||
{detailPreview.points > 0
|
||||
? ` + ${detailPreview.points} points`
|
||||
: ""}
|
||||
? drawerT("priceCreditsPoints", {
|
||||
credits: detailPreview.credits,
|
||||
points: detailPreview.points,
|
||||
})
|
||||
: drawerT("priceCredits", {
|
||||
count: detailPreview.credits,
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -163,14 +171,14 @@ export function FurnitureDetailDrawer({
|
||||
) : (
|
||||
<CloudDownload size={14} />
|
||||
)}
|
||||
Import & add to catalog
|
||||
{drawerT("importAdd")}
|
||||
</Button>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{!detail.nitroExists && (
|
||||
<>
|
||||
<p className="rounded-md border border-[var(--admin-warning)]/30 bg-[var(--admin-warning)]/10 p-2 text-[0.65rem] text-[var(--admin-warning)]">
|
||||
This furni is in the DB but its bundle file is missing.
|
||||
{drawerT("bundleMissing")}
|
||||
</p>
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -183,7 +191,7 @@ export function FurnitureDetailDrawer({
|
||||
) : (
|
||||
<RefreshCw size={14} />
|
||||
)}
|
||||
Regenerate .nitro
|
||||
{drawerT("regenerate")}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
@@ -194,7 +202,7 @@ export function FurnitureDetailDrawer({
|
||||
disabled={!detail.nitroExists}
|
||||
>
|
||||
<Pencil size={14} />
|
||||
Edit nitro
|
||||
{drawerT("editNitro")}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
@@ -206,7 +214,7 @@ export function FurnitureDetailDrawer({
|
||||
onClick={onDelete}
|
||||
>
|
||||
<Trash2 size={14} />
|
||||
Delete imported furni
|
||||
{drawerT("deleteImported")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user