feat: způsob přihlášení a správa obchodů podle konfigurace serveru
CI / Generate TypeScript types (push) Successful in 12s
CI / Server unit tests (push) Successful in 26s
CI / Build server (push) Successful in 32s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m47s
CI / Build and push Docker image (push) Successful in 49s
CI / Notify (push) Successful in 2s
CI / Generate TypeScript types (push) Successful in 12s
CI / Server unit tests (push) Successful in 26s
CI / Build server (push) Successful in 32s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m47s
CI / Build and push Docker image (push) Successful in 49s
CI / Notify (push) Successful in 2s
This commit is contained in:
10 files changed
+185
-82
No files matched your search
+70
-38
@@ -1,29 +1,37 @@
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { useAuth } from './context/auth';
|
||||
import { login } from '../../types';
|
||||
import { useAppConfig } from './hooks/useGroupLimits';
|
||||
import './Login.css';
|
||||
|
||||
/**
|
||||
* Formulář pro prvotní zadání přihlašovacího jména.
|
||||
* Přihlášení. Podle konfigurace serveru buď přihlásí uživatele automaticky přes důvěryhodné
|
||||
* hlavičky z proxy (bez formuláře), nebo zobrazí formulář pro zadání jména. Když se konfigurace
|
||||
* nenačte, zkusí nejprve přihlášení „naprázdno" a jinak zobrazí formulář (původní chování).
|
||||
*/
|
||||
export default function Login() {
|
||||
const auth = useAuth();
|
||||
const { loaded, trustedHeaders } = useAppConfig();
|
||||
const loginRef = useRef<HTMLInputElement>(null);
|
||||
const [trustedError, setTrustedError] = useState<string>();
|
||||
const [attempt, setAttempt] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (auth && !auth.login) {
|
||||
// Vyzkoušíme přihlášení "naprázdno", pokud projde, přihlásili nás trusted headers
|
||||
login().then(response => {
|
||||
const token = response.data;
|
||||
if (token) {
|
||||
auth?.setToken(token as unknown as string); // TODO vyřešit, API definice je špatně, je to skutečně string
|
||||
}
|
||||
}).catch(error => {
|
||||
// nezajímá nás
|
||||
});
|
||||
}
|
||||
}, [auth]);
|
||||
if (!auth || auth.login || !loaded || trustedHeaders === false) return;
|
||||
// Přihlášení přes hlavičky z proxy (případně pokus „naprázdno", pokud nevíme, jak server přihlašuje)
|
||||
setTrustedError(undefined);
|
||||
login().then(response => {
|
||||
const token = response.data;
|
||||
if (token) {
|
||||
auth.setToken(token as unknown as string); // TODO vyřešit, API definice je špatně, je to skutečně string
|
||||
} else if (trustedHeaders) {
|
||||
setTrustedError((response.error as any)?.error ?? 'Přihlášení přes proxy se nezdařilo.');
|
||||
}
|
||||
}).catch(() => {
|
||||
if (trustedHeaders) setTrustedError('Server je nedostupný. Zkuste to prosím za chvíli.');
|
||||
});
|
||||
}, [auth, loaded, trustedHeaders, attempt]);
|
||||
|
||||
const doLogin = useCallback(async () => {
|
||||
const length = loginRef?.current?.value.length && loginRef.current.value.replaceAll(/\s/g, '').length
|
||||
@@ -35,36 +43,60 @@ export default function Login() {
|
||||
}
|
||||
}, [auth]);
|
||||
|
||||
if (!auth?.login) {
|
||||
if (auth?.login) {
|
||||
return <div>Neplatný stav</div>
|
||||
}
|
||||
|
||||
const header = <>
|
||||
<h1 className='login-logo'>Luncher</h1>
|
||||
<p className='login-subtitle'>Aplikace pro profesionální management obědů</p>
|
||||
</>;
|
||||
|
||||
// Přihlašuje proxy — formulář se jménem nedává smysl
|
||||
if (!loaded || trustedHeaders) {
|
||||
return (
|
||||
<div className='login-page'>
|
||||
<div className='login-card'>
|
||||
<h1 className='login-logo'>Luncher</h1>
|
||||
<p className='login-subtitle'>Aplikace pro profesionální management obědů</p>
|
||||
<div className='login-form'>
|
||||
<div>
|
||||
<label htmlFor="login-input">Zobrazované jméno</label>
|
||||
<input
|
||||
id="login-input"
|
||||
ref={loginRef}
|
||||
type='text'
|
||||
placeholder="Např. Jan Novák"
|
||||
onKeyDown={event => {
|
||||
if (event.key === 'Enter') {
|
||||
doLogin()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p className='hint'>
|
||||
Zadejte jméno nebo přezdívku, pod kterou vás kolegové snadno identifikují.
|
||||
Jméno je možné kdykoli změnit.
|
||||
</p>
|
||||
{header}
|
||||
{trustedError ? (
|
||||
<div className='login-form'>
|
||||
<p className='login-error'>{trustedError}</p>
|
||||
<Button onClick={() => setAttempt(a => a + 1)}>Zkusit znovu</Button>
|
||||
</div>
|
||||
<Button onClick={doLogin}>Pokračovat</Button>
|
||||
</div>
|
||||
) : (
|
||||
<p className='hint'>Přihlašuji…</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <div>Neplatný stav</div>
|
||||
|
||||
return (
|
||||
<div className='login-page'>
|
||||
<div className='login-card'>
|
||||
{header}
|
||||
<div className='login-form'>
|
||||
<div>
|
||||
<label htmlFor="login-input">Zobrazované jméno</label>
|
||||
<input
|
||||
id="login-input"
|
||||
ref={loginRef}
|
||||
type='text'
|
||||
placeholder="Např. Jan Novák"
|
||||
onKeyDown={event => {
|
||||
if (event.key === 'Enter') {
|
||||
doLogin()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<p className='hint'>
|
||||
Zadejte jméno nebo přezdívku, pod kterou vás kolegové snadno identifikují.
|
||||
Jméno je možné kdykoli změnit.
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={doLogin}>Pokračovat</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user