feat: implement hide app name feature with toggle in admin settings and update branding context
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled

This commit is contained in:
2026-03-04 10:11:35 +01:00
parent bac4e8ae7c
commit ce2cf499dc
11 changed files with 627 additions and 61 deletions

View File

@@ -16,7 +16,7 @@ import toast from 'react-hot-toast';
export default function Admin() {
const { user } = useAuth();
const { t, language } = useLanguage();
const { appName, hasLogo, logoUrl, defaultTheme, registrationMode, imprintUrl, privacyUrl, refreshBranding } = useBranding();
const { appName, hasLogo, logoUrl, defaultTheme, registrationMode, imprintUrl, privacyUrl, hideAppName, refreshBranding } = useBranding();
const navigate = useNavigate();
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
@@ -47,6 +47,7 @@ export default function Admin() {
const [savingImprintUrl, setSavingImprintUrl] = useState(false);
const [editPrivacyUrl, setEditPrivacyUrl] = useState('');
const [savingPrivacyUrl, setSavingPrivacyUrl] = useState(false);
const [savingHideAppName, setSavingHideAppName] = useState(false);
// OAuth state
const [oauthConfig, setOauthConfig] = useState(null);
@@ -168,6 +169,18 @@ export default function Admin() {
}
};
const handleHideAppNameToggle = async (value) => {
setSavingHideAppName(true);
try {
await api.put('/branding/hide-app-name', { hideAppName: value });
refreshBranding();
} catch {
toast.error(t('admin.hideAppNameFailed'));
} finally {
setSavingHideAppName(false);
}
};
const handleAppNameSave = async () => {
if (!editAppName.trim()) return;
setSavingName(true);
@@ -447,6 +460,28 @@ export default function Admin() {
{savingName ? <Loader2 size={14} className="animate-spin" /> : t('common.save')}
</button>
</div>
{hasLogo && (
<div className="flex items-center justify-between mt-3 p-3 rounded-lg bg-th-bg-s border border-th-border">
<div className="min-w-0">
<p className="text-sm font-medium text-th-text">{t('admin.hideAppNameLabel')}</p>
<p className="text-xs text-th-text-s mt-0.5">{t('admin.hideAppNameHint')}</p>
</div>
<button
type="button"
disabled={savingHideAppName}
onClick={() => handleHideAppNameToggle(!hideAppName)}
className={`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-th-ring focus:ring-offset-1 disabled:opacity-50 ml-4 ${
hideAppName ? 'bg-th-accent' : 'bg-th-border'
}`}
aria-checked={hideAppName}
role="switch"
>
<span className={`pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out ${
hideAppName ? 'translate-x-4' : 'translate-x-0'
}`} />
</button>
</div>
)}
</div>
</div>