fix: keep site banner off login page
This commit is contained in:
@@ -36,8 +36,6 @@ button.account-secondary { min-height: 44px; padding: 11px 16px; border: 1px sol
|
|||||||
.account-notice { margin: 8px 0 0; padding: 12px 14px; border: 1px solid var(--ops-line); border-radius: 8px; font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
|
.account-notice { margin: 8px 0 0; padding: 12px 14px; border: 1px solid var(--ops-line); border-radius: 8px; font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
|
||||||
.account-notice.is-error { color: #ffb6b6; border-color: #763d44; background: #311e23; }
|
.account-notice.is-error { color: #ffb6b6; border-color: #763d44; background: #311e23; }
|
||||||
.account-notice.is-status { color: #aae0cb; border-color: #365c50; background: #1b2924; }
|
.account-notice.is-status { color: #aae0cb; border-color: #365c50; background: #1b2924; }
|
||||||
.account-notice.site-banner-login.is-error { border-color: var(--site-banner-border-color, #763d44); background: var(--site-banner-background-color, #311e23); }
|
|
||||||
.account-notice.site-banner-login.is-status { border-color: var(--site-banner-border-color, #365c50); background: var(--site-banner-background-color, #1b2924); }
|
|
||||||
.account-login-message { color: #ded8ed; border-color: #514a60; background: #26222d; white-space: pre-line; }
|
.account-login-message { color: #ded8ed; border-color: #514a60; background: #26222d; white-space: pre-line; }
|
||||||
.account-connected { display: flex; align-items: center; gap: 9px; border-top: 1px solid var(--ops-line-soft); margin-top: 32px; padding-top: 20px; color: var(--ops-faint); font-size: 12px; }
|
.account-connected { display: flex; align-items: center; gap: 9px; border-top: 1px solid var(--ops-line-soft); margin-top: 32px; padding-top: 20px; color: var(--ops-faint); font-size: 12px; }
|
||||||
.account-connection-dot { width: 6px; height: 6px; background: #83bda7; border-radius: 50%; flex-shrink: 0; }
|
.account-connection-dot { width: 6px; height: 6px; background: #83bda7; border-radius: 50%; flex-shrink: 0; }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState, type CSSProperties, type FormEvent } from 'react'
|
import { useEffect, useState, type FormEvent } from 'react'
|
||||||
import { getApiBase, setToken } from '../lib/auth'
|
import { getApiBase, setToken } from '../lib/auth'
|
||||||
import AuthLayout from '../ui/AuthLayout'
|
import AuthLayout from '../ui/AuthLayout'
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ export default function LoginPage() {
|
|||||||
const [mode, setMode] = useState<LoginMode>('jellyfin')
|
const [mode, setMode] = useState<LoginMode>('jellyfin')
|
||||||
const [options, setOptions] = useState<LoginOptions>(DEFAULT_OPTIONS)
|
const [options, setOptions] = useState<LoginOptions>(DEFAULT_OPTIONS)
|
||||||
const [optionsReady, setOptionsReady] = useState(false)
|
const [optionsReady, setOptionsReady] = useState(false)
|
||||||
const [banner, setBanner] = useState<{ message: string; tone: string; backgroundColor?: string | null; borderColor?: string | null } | null>(null)
|
|
||||||
const [loginMessage, setLoginMessage] = useState('')
|
const [loginMessage, setLoginMessage] = useState('')
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
@@ -37,14 +36,6 @@ export default function LoginPage() {
|
|||||||
showSignupLink: data?.login?.showSignupLink !== false,
|
showSignupLink: data?.login?.showSignupLink !== false,
|
||||||
})
|
})
|
||||||
setLoginMessage(typeof data?.login?.message === 'string' ? data.login.message.trim() : '')
|
setLoginMessage(typeof data?.login?.message === 'string' ? data.login.message.trim() : '')
|
||||||
if (data?.banner?.enabled && typeof data.banner.message === 'string' && data.banner.message.trim().toLowerCase() !== 'beta environment') {
|
|
||||||
setBanner({
|
|
||||||
message: data.banner.message,
|
|
||||||
tone: data.banner.tone || 'info',
|
|
||||||
backgroundColor: data.banner.backgroundColor,
|
|
||||||
borderColor: data.banner.borderColor,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
// Keep the normal sign-in methods available during a settings outage.
|
// Keep the normal sign-in methods available during a settings outage.
|
||||||
} finally {
|
} finally {
|
||||||
@@ -87,16 +78,10 @@ export default function LoginPage() {
|
|||||||
} finally { setLoading(false) }
|
} finally { setLoading(false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
const bannerStyle = {
|
|
||||||
'--site-banner-background-color': banner?.backgroundColor || undefined,
|
|
||||||
'--site-banner-border-color': banner?.borderColor || undefined,
|
|
||||||
} as CSSProperties
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthLayout title="Welcome back." description="Sign in to your media workspace." footer={
|
<AuthLayout title="Welcome back." description="Sign in to your media workspace." footer={
|
||||||
optionsReady && options.showSignupLink && <>Have an invite? <a href="/signup">Create an account <span aria-hidden="true">↗</span></a></>
|
optionsReady && options.showSignupLink && <>Have an invite? <a href="/signup">Create an account <span aria-hidden="true">↗</span></a></>
|
||||||
}>
|
}>
|
||||||
{banner && <p className={`account-notice site-banner-login ${['error', 'maintenance'].includes(banner.tone) ? 'is-error' : 'is-status'}`} style={bannerStyle} role="status">{banner.message}</p>}
|
|
||||||
{loginMessage && <p className="account-notice account-login-message" role="status">{loginMessage}</p>}
|
{loginMessage && <p className="account-notice account-login-message" role="status">{loginMessage}</p>}
|
||||||
{optionsReady && options.showJellyfinLogin && options.showLocalLogin && <fieldset className="login-methods" aria-label="Sign-in account">
|
{optionsReady && options.showJellyfinLogin && options.showLocalLogin && <fieldset className="login-methods" aria-label="Sign-in account">
|
||||||
<button type="button" aria-pressed={selectedMode === 'jellyfin'} disabled={loading} onClick={() => { setMode('jellyfin'); setError('') }}>Grizzlyflix</button>
|
<button type="button" aria-pressed={selectedMode === 'jellyfin'} disabled={loading} onClick={() => { setMode('jellyfin'); setError('') }}>Grizzlyflix</button>
|
||||||
|
|||||||
@@ -117,13 +117,8 @@ const site = { login: { message: '', showJellyfinLogin: true, showLocalLogin: tr
|
|||||||
assert.equal(await page.getByRole('button', { name: 'Sign in', exact: true }).count(), 0)
|
assert.equal(await page.getByRole('button', { name: 'Sign in', exact: true }).count(), 0)
|
||||||
assert.equal(await page.getByRole('link', { name: 'Forgot password?' }).count(), 0)
|
assert.equal(await page.getByRole('link', { name: 'Forgot password?' }).count(), 0)
|
||||||
assert.equal(await page.getByRole('link', { name: /Create an account/ }).count(), 0)
|
assert.equal(await page.getByRole('link', { name: /Create an account/ }).count(), 0)
|
||||||
assert(await page.getByText('Maintenance tonight').isVisible())
|
assert.equal(await page.getByText('Maintenance tonight').count(), 0)
|
||||||
assert(await page.getByText('Sign-in help is available from the media team.').isVisible())
|
assert(await page.getByText('Sign-in help is available from the media team.').isVisible())
|
||||||
const customBannerStyle = await page.getByText('Maintenance tonight').evaluate((element) => ({
|
|
||||||
background: getComputedStyle(element).backgroundColor,
|
|
||||||
border: getComputedStyle(element).borderTopColor,
|
|
||||||
}))
|
|
||||||
assert.deepEqual(customBannerStyle, { background: 'rgb(36, 23, 47)', border: 'rgb(217, 70, 239)' })
|
|
||||||
options = structuredClone(site)
|
options = structuredClone(site)
|
||||||
options.login.showLocalLogin = false
|
options.login.showLocalLogin = false
|
||||||
await openLogin()
|
await openLogin()
|
||||||
@@ -131,7 +126,7 @@ const site = { login: { message: '', showJellyfinLogin: true, showLocalLogin: tr
|
|||||||
await login()
|
await login()
|
||||||
await page.waitForURL(base + '/welcome')
|
await page.waitForURL(base + '/welcome')
|
||||||
assert((await context.cookies()).some((cookie) => cookie.name === 'magent_logged_in' && cookie.value === '1'))
|
assert((await context.cookies()).some((cookie) => cookie.name === 'magent_logged_in' && cookie.value === '1'))
|
||||||
console.log('PASS: both sign-in providers, disabled methods, error states, password visibility, redirect, login message and custom banner colours')
|
console.log('PASS: both sign-in providers, disabled methods, error states, password visibility, redirect, login-only message and hidden site banner')
|
||||||
|
|
||||||
options.banner = { enabled: true, message: 'Custom site banner', tone: 'warning', backgroundColor: '#24172f', borderColor: '#d946ef' }
|
options.banner = { enabled: true, message: 'Custom site banner', tone: 'warning', backgroundColor: '#24172f', borderColor: '#d946ef' }
|
||||||
await page.goto(base + '/admin/site')
|
await page.goto(base + '/admin/site')
|
||||||
|
|||||||
Reference in New Issue
Block a user