Adjust watermark permissions and transparency
This commit is contained in:
@@ -12,7 +12,7 @@ import { MobileColorInput, MobileField, MobileFileInput, MobileInput, MobileSele
|
||||
import { TenantEvent, getEvent, updateEvent, getTenantFonts, getTenantSettings, TenantFont, WatermarkSettings, trackOnboarding } from '../api';
|
||||
import { isAuthError } from '../auth/tokens';
|
||||
import { ApiError, getApiErrorMessage } from '../lib/apiError';
|
||||
import { isBrandingAllowed, isWatermarkAllowed } from '../lib/events';
|
||||
import { isBrandingAllowed, isWatermarkAllowed, isWatermarkRemovalAllowed } from '../lib/events';
|
||||
import { MobileSheet } from './components/Sheet';
|
||||
import toast from 'react-hot-toast';
|
||||
import { adminPath } from '../constants';
|
||||
@@ -188,10 +188,24 @@ export default function MobileBrandingPage() {
|
||||
const previewLogoValue = previewForm.logoMode === 'emoticon' ? previewForm.logoValue : '';
|
||||
const previewInitials = getInitials(previewTitle);
|
||||
const watermarkAllowed = isWatermarkAllowed(event ?? null);
|
||||
const watermarkRemovalAllowed = isWatermarkRemovalAllowed(event ?? null);
|
||||
const brandingAllowed = isBrandingAllowed(event ?? null);
|
||||
const customWatermarkAllowed = watermarkAllowed && brandingAllowed;
|
||||
const watermarkLocked = watermarkAllowed && !brandingAllowed;
|
||||
const brandingDisabled = !brandingAllowed || form.useDefaultBranding;
|
||||
|
||||
React.useEffect(() => {
|
||||
setWatermarkForm((prev) => {
|
||||
if (prev.mode === 'custom' && !customWatermarkAllowed) {
|
||||
return { ...prev, mode: 'base' };
|
||||
}
|
||||
if (prev.mode === 'off' && !watermarkRemovalAllowed) {
|
||||
return { ...prev, mode: 'base' };
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
}, [customWatermarkAllowed, watermarkRemovalAllowed]);
|
||||
|
||||
async function handleSave() {
|
||||
if (!event?.slug) return;
|
||||
setSaving(true);
|
||||
@@ -271,7 +285,12 @@ export default function MobileBrandingPage() {
|
||||
size: form.logoSize,
|
||||
},
|
||||
};
|
||||
const watermarkPayload = buildWatermarkPayload(watermarkForm, watermarkAllowed, brandingAllowed);
|
||||
const watermarkPayload = buildWatermarkPayload(
|
||||
watermarkForm,
|
||||
watermarkAllowed,
|
||||
brandingAllowed,
|
||||
watermarkRemovalAllowed
|
||||
);
|
||||
if (watermarkPayload) {
|
||||
settings.watermark = watermarkPayload;
|
||||
}
|
||||
@@ -307,10 +326,14 @@ export default function MobileBrandingPage() {
|
||||
}
|
||||
|
||||
function renderWatermarkTab() {
|
||||
const policyLabel = watermarkAllowed ? 'basic' : 'none';
|
||||
const disabled = !watermarkAllowed;
|
||||
const controlsLocked = watermarkLocked || disabled;
|
||||
const controlsLocked = watermarkLocked;
|
||||
const mode = controlsLocked ? 'base' : watermarkForm.mode;
|
||||
const resolvedMode = mode === 'custom' && !customWatermarkAllowed
|
||||
? 'base'
|
||||
: mode === 'off' && !watermarkRemovalAllowed
|
||||
? 'base'
|
||||
: mode;
|
||||
const customizationDisabled = controlsLocked || resolvedMode !== 'custom';
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -325,12 +348,12 @@ export default function MobileBrandingPage() {
|
||||
padding={watermarkForm.padding}
|
||||
offsetX={watermarkForm.offsetX}
|
||||
offsetY={watermarkForm.offsetY}
|
||||
previewUrl={mode === 'off' ? '' : watermarkForm.assetDataUrl || watermarkForm.assetPreviewUrl}
|
||||
previewUrl={resolvedMode === 'off' ? '' : watermarkForm.assetDataUrl || watermarkForm.assetPreviewUrl}
|
||||
previewAlt={t('events.watermark.previewAlt', 'Watermark preview')}
|
||||
/>
|
||||
</MobileCard>
|
||||
|
||||
{disabled ? (
|
||||
{!watermarkAllowed ? (
|
||||
<UpgradeCard
|
||||
title={t('events.watermark.lockedTitle', 'Unlock watermarks')}
|
||||
body={t('events.watermark.lockedBody', 'Custom watermarks are available with the Premium package.')}
|
||||
@@ -353,7 +376,7 @@ export default function MobileBrandingPage() {
|
||||
|
||||
<MobileField label={t('events.watermark.mode', 'Modus')}>
|
||||
<MobileSelect
|
||||
value={mode}
|
||||
value={resolvedMode}
|
||||
disabled={controlsLocked}
|
||||
onChange={(event) => {
|
||||
const value = event.target.value;
|
||||
@@ -364,16 +387,16 @@ export default function MobileBrandingPage() {
|
||||
}}
|
||||
>
|
||||
<option value="base">{t('events.watermark.modeBase', 'Basis')}</option>
|
||||
<option value="custom" disabled={watermarkLocked}>
|
||||
<option value="custom" disabled={!customWatermarkAllowed}>
|
||||
{t('events.watermark.modeCustom', 'Eigenes Wasserzeichen')}
|
||||
</option>
|
||||
<option value="off" disabled={policyLabel === 'basic'}>
|
||||
<option value="off" disabled={!watermarkRemovalAllowed}>
|
||||
{t('events.watermark.modeOff', 'Deaktiviert')}
|
||||
</option>
|
||||
</MobileSelect>
|
||||
</MobileField>
|
||||
|
||||
{mode === 'custom' && !controlsLocked ? (
|
||||
{resolvedMode === 'custom' && !controlsLocked ? (
|
||||
<YStack space="$2">
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
||||
{t('events.watermark.upload', 'Wasserzeichen hochladen')}
|
||||
@@ -452,7 +475,7 @@ export default function MobileBrandingPage() {
|
||||
<PositionGrid
|
||||
value={watermarkForm.position}
|
||||
onChange={(next) => setWatermarkForm((prev) => ({ ...prev, position: next }))}
|
||||
disabled={controlsLocked}
|
||||
disabled={customizationDisabled}
|
||||
/>
|
||||
<LabeledSlider
|
||||
label={t('events.watermark.size', 'Größe')}
|
||||
@@ -461,7 +484,7 @@ export default function MobileBrandingPage() {
|
||||
max={60}
|
||||
step={1}
|
||||
onChange={(value) => setWatermarkForm((prev) => ({ ...prev, scale: value / 100 }))}
|
||||
disabled={controlsLocked}
|
||||
disabled={customizationDisabled}
|
||||
/>
|
||||
<LabeledSlider
|
||||
label={t('events.watermark.opacity', 'Transparenz')}
|
||||
@@ -470,7 +493,7 @@ export default function MobileBrandingPage() {
|
||||
max={80}
|
||||
step={5}
|
||||
onChange={(value) => setWatermarkForm((prev) => ({ ...prev, opacity: value / 100 }))}
|
||||
disabled={controlsLocked}
|
||||
disabled={customizationDisabled}
|
||||
/>
|
||||
<LabeledSlider
|
||||
label={t('events.watermark.padding', 'Abstand zum Rand')}
|
||||
@@ -479,7 +502,7 @@ export default function MobileBrandingPage() {
|
||||
max={80}
|
||||
step={2}
|
||||
onChange={(value) => setWatermarkForm((prev) => ({ ...prev, padding: value }))}
|
||||
disabled={controlsLocked}
|
||||
disabled={customizationDisabled}
|
||||
/>
|
||||
<LabeledSlider
|
||||
label={t('events.watermark.offset', 'Feinjustierung')}
|
||||
@@ -488,7 +511,7 @@ export default function MobileBrandingPage() {
|
||||
max={30}
|
||||
step={1}
|
||||
onChange={(value) => setWatermarkForm((prev) => ({ ...prev, offsetX: value }))}
|
||||
disabled={controlsLocked}
|
||||
disabled={customizationDisabled}
|
||||
suffix={t('events.watermark.offsetX', 'X-Achse')}
|
||||
/>
|
||||
<LabeledSlider
|
||||
@@ -498,7 +521,7 @@ export default function MobileBrandingPage() {
|
||||
max={30}
|
||||
step={1}
|
||||
onChange={(value) => setWatermarkForm((prev) => ({ ...prev, offsetY: value }))}
|
||||
disabled={controlsLocked}
|
||||
disabled={customizationDisabled}
|
||||
/>
|
||||
</MobileCard>
|
||||
</>
|
||||
@@ -1095,15 +1118,19 @@ function extractWatermark(event: TenantEvent): WatermarkForm {
|
||||
function buildWatermarkPayload(
|
||||
form: WatermarkForm,
|
||||
watermarkAllowed: boolean,
|
||||
brandingAllowed: boolean
|
||||
brandingAllowed: boolean,
|
||||
removalAllowed: boolean
|
||||
): WatermarkSettings | null {
|
||||
if (!watermarkAllowed) {
|
||||
return { mode: 'off' };
|
||||
const customAllowed = watermarkAllowed && brandingAllowed;
|
||||
let mode = form.mode;
|
||||
|
||||
if (mode === 'custom' && !customAllowed) {
|
||||
mode = 'base';
|
||||
}
|
||||
|
||||
const policy = watermarkAllowed ? 'basic' : 'none';
|
||||
const desiredMode = brandingAllowed ? form.mode : 'base';
|
||||
const mode = desiredMode === 'off' && policy === 'basic' ? 'base' : desiredMode;
|
||||
if (mode === 'off' && !removalAllowed) {
|
||||
mode = 'base';
|
||||
}
|
||||
|
||||
const payload: WatermarkSettings = {
|
||||
mode,
|
||||
@@ -1115,7 +1142,7 @@ function buildWatermarkPayload(
|
||||
offset_y: Math.max(-500, Math.min(500, Math.round(form.offsetY))),
|
||||
};
|
||||
|
||||
if (mode === 'custom' && brandingAllowed) {
|
||||
if (mode === 'custom' && customAllowed) {
|
||||
if (form.assetDataUrl) {
|
||||
payload.asset_data_url = form.assetDataUrl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user