fix(catalog): make access controls visible and compact
This commit is contained in:
1 parent
93a7e9a7c2
commit
35d0f3ee01
5 files changed
+139
-15
No files matched your search
@@ -0,0 +1,73 @@
|
|||||||
|
.options {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.option {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 14px;
|
||||||
|
border: 1px solid var(--admin-border);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--admin-surface);
|
||||||
|
color: var(--admin-text);
|
||||||
|
}
|
||||||
|
.optionHeader,
|
||||||
|
.control {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.optionHeader {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.control {
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-height: 32px;
|
||||||
|
}
|
||||||
|
.state {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--admin-text-muted);
|
||||||
|
}
|
||||||
|
.description {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--admin-text-muted);
|
||||||
|
}
|
||||||
|
.toggle[data-slot="switch"] {
|
||||||
|
width: 44px;
|
||||||
|
height: 24px;
|
||||||
|
border: 1px solid var(--admin-text-muted);
|
||||||
|
background: var(--admin-border);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.toggle[data-checked] {
|
||||||
|
background: var(--admin-accent);
|
||||||
|
border-color: var(--admin-accent);
|
||||||
|
}
|
||||||
|
.toggle [data-slot="switch-thumb"] {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
left: 2px;
|
||||||
|
background: var(--admin-text);
|
||||||
|
color: var(--admin-canvas);
|
||||||
|
}
|
||||||
|
.toggle[data-checked] [data-slot="switch-thumb"] {
|
||||||
|
left: 22px;
|
||||||
|
}
|
||||||
|
.toggle:focus-visible {
|
||||||
|
outline: 2px solid var(--admin-accent);
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
.option[data-disabled] .toggle,
|
||||||
|
.option[data-disabled] .label {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.option[data-disabled] .control {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
@@ -49,6 +49,7 @@ import {
|
|||||||
LAYOUT_DESCRIPTIONS,
|
LAYOUT_DESCRIPTIONS,
|
||||||
} from "@/lib/catalog-layouts";
|
} from "@/lib/catalog-layouts";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import styles from "./catalog-access.module.css";
|
||||||
import { ImagePreview } from "./image-preview";
|
import { ImagePreview } from "./image-preview";
|
||||||
import { catalogTreeQs, useCatalogManager } from "./use-catalog-store";
|
import { catalogTreeQs, useCatalogManager } from "./use-catalog-store";
|
||||||
|
|
||||||
@@ -572,26 +573,29 @@ function InlineEditorSession({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Toggles */}
|
{/* Toggles */}
|
||||||
<div className="rounded-md border p-3 space-y-3">
|
<div className={styles.options}>
|
||||||
<ToggleRow
|
<ToggleRow
|
||||||
id="ie-enabled"
|
id="ie-enabled"
|
||||||
label="Enabled"
|
disabled={!canEdit || saving}
|
||||||
description="Active in the catalog"
|
label={t("access.enabled")}
|
||||||
|
description={t("access.enabledHint")}
|
||||||
checked={form.enabled === "1"}
|
checked={form.enabled === "1"}
|
||||||
onChange={(v) => update("enabled", v ? "1" : "0")}
|
onChange={(v) => update("enabled", v ? "1" : "0")}
|
||||||
/>
|
/>
|
||||||
<ToggleRow
|
<ToggleRow
|
||||||
id="ie-visible"
|
id="ie-visible"
|
||||||
label="Visible"
|
disabled={!canEdit || saving}
|
||||||
description="Shown in navigation"
|
label={t("access.visible")}
|
||||||
|
description={t("access.visibleHint")}
|
||||||
checked={form.visible === "1"}
|
checked={form.visible === "1"}
|
||||||
onChange={(v) => update("visible", v ? "1" : "0")}
|
onChange={(v) => update("visible", v ? "1" : "0")}
|
||||||
/>
|
/>
|
||||||
{catalogType === "normal" && (
|
{catalogType === "normal" && (
|
||||||
<ToggleRow
|
<ToggleRow
|
||||||
id="ie-club"
|
id="ie-club"
|
||||||
label="Club Only"
|
disabled={!canEdit || saving}
|
||||||
description="Requires HC subscription"
|
label={t("access.club")}
|
||||||
|
description={t("access.clubHint")}
|
||||||
checked={form.clubOnly === "1"}
|
checked={form.clubOnly === "1"}
|
||||||
onChange={(v) => update("clubOnly", v ? "1" : "0")}
|
onChange={(v) => update("clubOnly", v ? "1" : "0")}
|
||||||
/>
|
/>
|
||||||
@@ -832,24 +836,41 @@ function ToggleRow({
|
|||||||
id,
|
id,
|
||||||
label,
|
label,
|
||||||
description,
|
description,
|
||||||
|
disabled,
|
||||||
checked,
|
checked,
|
||||||
onChange,
|
onChange,
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
disabled: boolean;
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
onChange: (v: boolean) => void;
|
onChange: (v: boolean) => void;
|
||||||
}) {
|
}) {
|
||||||
|
const t = useTranslations("pages.admin.catalog.workspace.access");
|
||||||
return (
|
return (
|
||||||
<div className="flex items-start justify-between gap-3">
|
<div className={styles.option} data-disabled={disabled || undefined}>
|
||||||
<div className="min-w-0 flex-1">
|
<div className={styles.optionHeader}>
|
||||||
<Label htmlFor={id} className="text-xs font-medium cursor-pointer">
|
<Label htmlFor={id} className={styles.label}>
|
||||||
{label}
|
{label}
|
||||||
</Label>
|
</Label>
|
||||||
<p className="text-[10px] text-muted-foreground">{description}</p>
|
<div className={styles.control}>
|
||||||
|
<span className={styles.state} aria-hidden="true">
|
||||||
|
{t(checked ? "yes" : "no")}
|
||||||
|
</span>
|
||||||
|
<Switch
|
||||||
|
id={id}
|
||||||
|
checked={checked}
|
||||||
|
onCheckedChange={onChange}
|
||||||
|
disabled={disabled}
|
||||||
|
aria-describedby={`${id}-description`}
|
||||||
|
className={styles.toggle}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Switch id={id} checked={checked} onCheckedChange={onChange} size="sm" />
|
<p id={`${id}-description`} className={styles.description}>
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
+11
-1
@@ -1969,7 +1969,17 @@
|
|||||||
},
|
},
|
||||||
"unsaved": "Unsaved changes",
|
"unsaved": "Unsaved changes",
|
||||||
"fullEditor": "Full editor",
|
"fullEditor": "Full editor",
|
||||||
"saveHint": "Category changes are not saved. Use Save or Ctrl+S."
|
"saveHint": "Category changes are not saved. Use Save or Ctrl+S.",
|
||||||
|
"access": {
|
||||||
|
"enabled": "Enabled",
|
||||||
|
"enabledHint": "Makes this category available in the catalog.",
|
||||||
|
"visible": "Visible in navigation",
|
||||||
|
"visibleHint": "Shows this category in the catalog menu.",
|
||||||
|
"club": "HC only",
|
||||||
|
"clubHint": "Restricts access to users with an HC subscription.",
|
||||||
|
"yes": "Yes",
|
||||||
|
"no": "No"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"bulk": {
|
"bulk": {
|
||||||
"previewCount": "{count} of {total} offers will change.",
|
"previewCount": "{count} of {total} offers will change.",
|
||||||
|
|||||||
+11
-1
@@ -1888,7 +1888,17 @@
|
|||||||
},
|
},
|
||||||
"unsaved": "Modifiche non salvate",
|
"unsaved": "Modifiche non salvate",
|
||||||
"fullEditor": "Editor completo",
|
"fullEditor": "Editor completo",
|
||||||
"saveHint": "Le modifiche alla categoria non sono salvate. Usa Salva o Ctrl+S."
|
"saveHint": "Le modifiche alla categoria non sono salvate. Usa Salva o Ctrl+S.",
|
||||||
|
"access": {
|
||||||
|
"enabled": "Categoria attiva",
|
||||||
|
"enabledHint": "Rende questa categoria disponibile nel catalogo.",
|
||||||
|
"visible": "Visibile nel menu",
|
||||||
|
"visibleHint": "Mostra questa categoria nel menu del catalogo.",
|
||||||
|
"club": "Solo utenti HC",
|
||||||
|
"clubHint": "Limita l’accesso agli utenti con abbonamento HC.",
|
||||||
|
"yes": "Sì",
|
||||||
|
"no": "No"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"bulk": {
|
"bulk": {
|
||||||
"previewCount": "Verranno modificate {count} offerte su {total}.",
|
"previewCount": "Verranno modificate {count} offerte su {total}.",
|
||||||
|
|||||||
+11
-1
@@ -1718,7 +1718,17 @@
|
|||||||
},
|
},
|
||||||
"unsaved": "Niet-opgeslagen wijzigingen",
|
"unsaved": "Niet-opgeslagen wijzigingen",
|
||||||
"fullEditor": "Volledige editor",
|
"fullEditor": "Volledige editor",
|
||||||
"saveHint": "Categoriewijzigingen zijn niet opgeslagen. Gebruik Opslaan of Ctrl+S."
|
"saveHint": "Categoriewijzigingen zijn niet opgeslagen. Gebruik Opslaan of Ctrl+S.",
|
||||||
|
"access": {
|
||||||
|
"enabled": "Categorie actief",
|
||||||
|
"enabledHint": "Maakt deze categorie beschikbaar in de catalogus.",
|
||||||
|
"visible": "Zichtbaar in het menu",
|
||||||
|
"visibleHint": "Toont deze categorie in het catalogusmenu.",
|
||||||
|
"club": "Alleen HC",
|
||||||
|
"clubHint": "Beperkt toegang tot gebruikers met een HC-abonnement.",
|
||||||
|
"yes": "Ja",
|
||||||
|
"no": "Nee"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"bulk": {
|
"bulk": {
|
||||||
"previewCount": "{count} van {total} aanbiedingen worden gewijzigd.",
|
"previewCount": "{count} van {total} aanbiedingen worden gewijzigd.",
|
||||||
|
|||||||
Reference in new issue
Block a user