Tier model: registered=basic (recipes, 12 photos, QR), PRO=verified or admin-activated (HSL, tools/gradient mask, RAW, export > source longest edge); admin users table gets Activated Pro column
This commit is contained in:
@@ -24,9 +24,14 @@ export function ExportModal({
|
||||
const { t } = useI18n();
|
||||
const [custom, setCustom] = useState(String(Math.min(CUSTOM_MAX, Math.max(1024, longest * 2))));
|
||||
|
||||
// `maxDim` is whatever the account's tier allows: none for PRO, the photo's
|
||||
// own long edge for a basic account, 2048 for a guest. The field's own `max`
|
||||
// says so, so a number past it is refused where it is typed rather than
|
||||
// silently clamped on the way out.
|
||||
const customMax = Math.min(CUSTOM_MAX, maxDim ?? CUSTOM_MAX);
|
||||
const pick = (n: number | null) => onPick(n !== null && maxDim !== null ? Math.min(n, maxDim) : n);
|
||||
const customValue = Number(custom);
|
||||
const customOk = Number.isFinite(customValue) && customValue >= 1 && customValue <= CUSTOM_MAX;
|
||||
const customOk = Number.isFinite(customValue) && customValue >= 1 && customValue <= customMax;
|
||||
|
||||
return (
|
||||
<div className="modal-backdrop" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
|
||||
@@ -38,12 +43,14 @@ export function ExportModal({
|
||||
<button type="button" className="btn" data-key="export-same" onClick={() => pick(null)}>
|
||||
{t('export.same')}
|
||||
</button>
|
||||
<button type="button" className="btn" data-key="export-2k" onClick={() => pick(2048)}>
|
||||
{t('export.2k')}
|
||||
</button>
|
||||
{/* A capped account cannot be handed a size its tier refuses, so the two
|
||||
sizes over the ceiling are not offered at all. */}
|
||||
{maxDim === null || maxDim > 2048 ? (
|
||||
{(maxDim === null || maxDim >= 2048) && (
|
||||
<button type="button" className="btn" data-key="export-2k" onClick={() => pick(2048)}>
|
||||
{t('export.2k')}
|
||||
</button>
|
||||
)}
|
||||
{/* A size the ceiling refuses is not offered at all — picking it would
|
||||
only hand back the cap. The note below names that cap. */}
|
||||
{(maxDim === null || maxDim >= 4096) && (
|
||||
<>
|
||||
<button type="button" className="btn" data-key="export-4k" onClick={() => pick(4096)}>
|
||||
{t('export.4k')}
|
||||
@@ -57,7 +64,7 @@ export function ExportModal({
|
||||
className="field"
|
||||
type="number"
|
||||
min={1}
|
||||
max={CUSTOM_MAX}
|
||||
max={customMax}
|
||||
value={custom}
|
||||
onChange={(e) => setCustom(e.target.value)}
|
||||
/>
|
||||
@@ -72,7 +79,8 @@ export function ExportModal({
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
)}
|
||||
{maxDim !== null && (
|
||||
<p className="hint" data-key="export-cap">
|
||||
{t('export.cap', { px: maxDim })}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user