Skip to content

Commit

Permalink
feat: auth page
Browse files Browse the repository at this point in the history
  • Loading branch information
Nilumilak committed Dec 17, 2024
1 parent a7aae05 commit 7b6d6f4
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 112 deletions.
3 changes: 3 additions & 0 deletions contract/src/main/resources/swagger/kafbat-ui-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2256,7 +2256,10 @@ paths:

/auth:
post:
tags:
- ApplicationConfig
summary: Authenticate
operationId: authenticate
requestBody:
required: true
content:
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/AuthPage/AuthPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import { useAuthSettings } from 'lib/hooks/api/appConfig';

import Footer from './Footer/Footer';
import Header from './Header/Header';
import SignIn from './SignIn/SignIn';
import * as S from './AuthPage.styled';
Expand All @@ -12,8 +11,9 @@ function AuthPage() {
return (
<S.AuthPageStyled>
<Header />
{data && <SignIn appAuthenticationSettings={data} />}
<Footer />
{data && (
<SignIn authType={data.authType} oAuthProviders={data.oAuthProviders} />
)}
</S.AuthPageStyled>
);
}
Expand Down
45 changes: 0 additions & 45 deletions frontend/src/components/AuthPage/Footer/Footer.styled.tsx

This file was deleted.

28 changes: 0 additions & 28 deletions frontend/src/components/AuthPage/Footer/Footer.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const Form = styled.form`
align-items: center;
justify-content: center;
gap: 40px;
width: 100%;
div {
width: 100%;
Expand All @@ -19,6 +20,7 @@ export const Fieldset = styled.fieldset`
justify-content: center;
gap: 16px;
border: none;
width: 100%;
`;

export const Field = styled.div`
Expand All @@ -35,3 +37,20 @@ export const Label = styled.label`
font-weight: 500;
line-height: 16px;
`;

export const ErrorMessage = styled.div`
display: flex;
column-gap: 2px;
align-items: center;
justify-content: center;
font-weight: 400;
font-size: 14px;
line-height: 20px;
`;

export const ErrorMessageText = styled.span`
${({ theme }) => theme.auth_page.signIn.errorMessage};
font-weight: 400;
font-size: 14px;
line-height: 20px;
`;
91 changes: 68 additions & 23 deletions frontend/src/components/AuthPage/SignIn/BasicSignIn/BasicSignIn.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react';
import { Button } from 'components/common/Button/Button';
import Input from 'components/common/Input/Input';
import { FormProvider, useForm } from 'react-hook-form';
import { Controller, FormProvider, useForm } from 'react-hook-form';
import { useAuthenticate } from 'lib/hooks/api/appConfig';
import AlertIcon from 'components/common/Icons/AlertIcon';
import { useNavigate } from 'react-router-dom';

import * as S from './BasicSignIn.styled';

Expand All @@ -11,36 +14,78 @@ interface FormValues {
}

function BasicSignIn() {
const methods = useForm<FormValues>();
const methods = useForm<FormValues>({
defaultValues: { username: '', password: '' },
});
const navigate = useNavigate();
const { mutateAsync } = useAuthenticate();

const onSubmit = async (data: FormValues) => {
await mutateAsync(data, {
onSuccess(response) {
if (response.raw.url.includes('error')) {
methods.setError('root', { message: 'error' });
} else {
navigate('/');
}
},
});
};

return (
<FormProvider {...methods}>
<S.Form style={{ width: '100%' }}>
<S.Fieldset style={{ width: '100%' }}>
<S.Field>
<S.Label htmlFor="username">Username</S.Label>
<Input
name="username"
id="username"
placeholder="Enter your username"
style={{ borderRadius: '8px' }}
/>
</S.Field>
<S.Field>
<S.Label htmlFor="password">Password</S.Label>
<Input
name="password"
id="password"
placeholder="Enter your password"
style={{ borderRadius: '8px' }}
/>
</S.Field>
<S.Form onSubmit={methods.handleSubmit(onSubmit)}>
<S.Fieldset>
{methods.formState.errors.root && (
<S.ErrorMessage>
<AlertIcon />
<S.ErrorMessageText>
Username or password entered incorrectly
</S.ErrorMessageText>
</S.ErrorMessage>
)}
<Controller
name="username"
control={methods.control}
render={({ field }) => (
<S.Field>
<S.Label htmlFor={field.name}>Username</S.Label>
<Input
onChange={field.onChange}
value={field.value}
name={field.name}
id={field.name}
placeholder="Enter your username"
style={{ borderRadius: '8px' }}
/>
</S.Field>
)}
/>
<Controller
name="password"
control={methods.control}
render={({ field }) => (
<S.Field>
<S.Label htmlFor={field.name}>Password</S.Label>
<Input
onChange={field.onChange}
value={field.value}
name={field.name}
type="password"
id={field.name}
placeholder="Enter your password"
style={{ borderRadius: '8px' }}
/>
</S.Field>
)}
/>
</S.Fieldset>
<Button
buttonSize="L"
buttonType="primary"
onClick={() => console.log('click')}
type="submit"
style={{ width: '100%', borderRadius: '8px' }}
disabled={!methods.formState.isValid}
>
Log in
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import styled, { css } from 'styled-components';
import GitHubIcon from 'components/common/Icons/GitHubIcon';
import { Link } from 'react-router-dom';
import { Button } from 'components/common/Button/Button';

export const AuthCardStyled = styled.div(
Expand Down Expand Up @@ -64,4 +63,4 @@ export const ServiceButton = styled(Button)`
border-radius: 8px;
font-size: 14px;
text-decoration: none;
`
`;
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function AuthCard({ serviceName, authPath, Icon = ServiceImage }: Props) {
<S.ServiceButton
buttonSize="L"
buttonType="primary"
to={`http://localhost:8080${authPath}`}
to={`${window.basePath}${authPath}`}
>
Log in with {serviceName}
</S.ServiceButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ function OAuthSignIn({ oAuthProviders }: Props) {
<AuthCard
key={provider.clientName}
authPath={provider.authorizationUri}
Icon={ServiceIconMap[provider.clientName?.toLowerCase() || 'unknownService']}
Icon={
ServiceIconMap[
provider.clientName?.toLowerCase() || 'unknownService'
]
}
serviceName={provider.clientName || ''}
/>
))}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/AuthPage/SignIn/SignIn.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const SignInStyled = styled.div`
justify-content: center;
width: 320px;
gap: 56px;
flex-grow: 1;
`;

export const SignInTitle = styled.span(
Expand Down
14 changes: 7 additions & 7 deletions frontend/src/components/AuthPage/SignIn/SignIn.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import React from 'react';
import { AppAuthenticationSettings, AuthType } from 'generated-sources';
import { AuthType, OAuthProvider } from 'generated-sources';

import BasicSignIn from './BasicSignIn/BasicSignIn';
import * as S from './SignIn.styled';
import OAuthSignIn from './OAuthSignIn/OAuthSignIn';

interface Props {
appAuthenticationSettings: AppAuthenticationSettings;
authType?: string;
oAuthProviders?: OAuthProvider[];
}

function SignInForm({ appAuthenticationSettings }: Props) {
const { authType, oAuthProviders } = appAuthenticationSettings;

function SignInForm({ authType, oAuthProviders }: Props) {
return (
<S.SignInStyled>
<S.SignInTitle>Sign in</S.SignInTitle>
{(authType === AuthType.LDAP ||
authType === AuthType.LOGIN_FORM) && <BasicSignIn />}
{(authType === AuthType.LDAP || authType === AuthType.LOGIN_FORM) && (
<BasicSignIn />
)}
{authType === AuthType.OAUTH2 && (
<OAuthSignIn oAuthProviders={oAuthProviders} />
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/NavBar/UserInfo/UserInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const UserInfo = () => {
</S.Wrapper>
}
>
<DropdownItem href={`${window.basePath}/logout`}>
<DropdownItem href="logout">
<S.LogoutLink>Log out</S.LogoutLink>
</DropdownItem>
</Dropdown>
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/components/common/Icons/AlertIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

const AlertIcon: React.FC = () => {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9.09265 2.06673C8.60703 1.25046 7.39297 1.25046 6.90735 2.06673L1.17092 11.7088C0.685293 12.5251 1.29232 13.5454 2.26357 13.5454H13.7364C14.7077 13.5454 15.3147 12.5251 14.8291 11.7088L9.09265 2.06673ZM7 6C7 5.44772 7.44772 5 8 5C8.55228 5 9 5.44772 9 6V8C9 8.55228 8.55228 9 8 9C7.44772 9 7 8.55228 7 8V6ZM7 11C7 10.4477 7.44772 10 8 10C8.55228 10 9 10.4477 9 11C9 11.5523 8.55228 12 8 12C7.44772 12 7 11.5523 7 11Z"
fill="#E63B19"
/>
</svg>
);
};

export default AlertIcon;
9 changes: 9 additions & 0 deletions frontend/src/components/contexts/GlobalSettingsContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useAppInfo } from 'lib/hooks/api/appConfig';
import React from 'react';
import { ApplicationInfoEnabledFeaturesEnum } from 'generated-sources';
import { useNavigate } from 'react-router-dom';

interface GlobalSettingsContextProps {
hasDynamicConfig: boolean;
Expand All @@ -15,6 +16,14 @@ export const GlobalSettingsProvider: React.FC<
React.PropsWithChildren<unknown>
> = ({ children }) => {
const info = useAppInfo();
const navigate = useNavigate();

React.useEffect(() => {
if (info.data?.raw.url.includes('auth')) {
navigate('auth');
}
}, [info.data?.raw.url]);

const value = React.useMemo(() => {
const features = info.data?.enabledFeatures || [];
return {
Expand Down
Loading

0 comments on commit 7b6d6f4

Please sign in to comment.