Revamp login page (#21256)
* revamp login page * fix test * update signup form design * update order of carousel * update images and locales * update responsiveness * remove welcome locale * add animation to images * add styles for ai * updated images (cherry picked from commit d298fc00c97f073114e2b46a8c6ea073968079ee)
Before Width: | Height: | Size: 1011 KiB After Width: | Height: | Size: 834 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 770 KiB |
Before Width: | Height: | Size: 820 KiB |
Before Width: | Height: | Size: 832 KiB |
Before Width: | Height: | Size: 562 KiB |
Before Width: | Height: | Size: 678 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 40 KiB |
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { kebabCase, map } from 'lodash';
|
||||
import loginClassBase from './LoginClassBase';
|
||||
|
||||
const {
|
||||
dataDiscovery,
|
||||
dataQuality,
|
||||
governance,
|
||||
dataInsightPlural,
|
||||
dataCollaboration,
|
||||
...rest
|
||||
} = loginClassBase.carouselImages();
|
||||
|
||||
export const LOGIN_SLIDE = [
|
||||
{
|
||||
title: 'data-discovery',
|
||||
image: dataDiscovery,
|
||||
descriptionKey: 'enables-end-to-end-metadata-management',
|
||||
},
|
||||
{
|
||||
title: 'data-quality',
|
||||
image: dataQuality,
|
||||
descriptionKey: 'discover-your-data-and-unlock-the-value-of-data-assets',
|
||||
},
|
||||
{
|
||||
title: 'governance',
|
||||
image: governance,
|
||||
descriptionKey: 'assess-data-reliability-with-data-profiler-lineage',
|
||||
},
|
||||
...(dataInsightPlural
|
||||
? [
|
||||
{
|
||||
title: 'data-insight-plural',
|
||||
image: dataInsightPlural,
|
||||
descriptionKey: 'fosters-collaboration-among-producers-and-consumers',
|
||||
},
|
||||
]
|
||||
: map(rest, (item, key) => ({
|
||||
title: kebabCase(key),
|
||||
image: item,
|
||||
descriptionKey: kebabCase(key) + '-description',
|
||||
}))),
|
||||
{
|
||||
title: 'data-collaboration',
|
||||
image: dataCollaboration,
|
||||
descriptionKey: 'deeply-understand-table-relations-message',
|
||||
},
|
||||
];
|
@ -10,22 +10,90 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import collaborationImg from '../assets/img/login-screen/data-collaboration.png';
|
||||
import discoveryImg from '../assets/img/login-screen/data-discovery.png';
|
||||
import governanceImg from '../assets/img/login-screen/data-governance.png';
|
||||
import insightImg from '../assets/img/login-screen/data-insights.png';
|
||||
import dataQualityImg from '../assets/img/login-screen/data-quality.png';
|
||||
import collaborationImg from '../assets/img/login-screen/collaboration/collaboration-main.png';
|
||||
import collaborationMenu from '../assets/img/login-screen/collaboration/collaboration-menu.png';
|
||||
import collaborationTabs from '../assets/img/login-screen/collaboration/collaboration-tabs.png';
|
||||
import discoveryDataAssets from '../assets/img/login-screen/discovery/discovery-data-asset.png';
|
||||
import discoveryLanguage from '../assets/img/login-screen/discovery/discovery-language.png';
|
||||
import discoveryImg from '../assets/img/login-screen/discovery/discovery-main.png';
|
||||
import governanceItems from '../assets/img/login-screen/governance/governance-items.png';
|
||||
import governanceList from '../assets/img/login-screen/governance/governance-list.png';
|
||||
import governanceImg from '../assets/img/login-screen/governance/governance-main.png';
|
||||
import governanceReviewer from '../assets/img/login-screen/governance/governance-reviewer.png';
|
||||
import dataObservabilityImg from '../assets/img/login-screen/observability/observability-main.png';
|
||||
import observabilityTestcase from '../assets/img/login-screen/observability/observability-testcase.png';
|
||||
|
||||
class LoginClassBase {
|
||||
public carouselImages(): Record<string, string> {
|
||||
return {
|
||||
dataDiscovery: discoveryImg,
|
||||
dataQuality: dataQualityImg,
|
||||
governance: governanceImg,
|
||||
dataInsightPlural: insightImg,
|
||||
dataCollaboration: collaborationImg,
|
||||
};
|
||||
public getLoginCarouselContent() {
|
||||
const carouselContent = [
|
||||
{
|
||||
title: 'governance',
|
||||
image: governanceImg,
|
||||
descriptionKey: 'assess-data-reliability-with-data-profiler-lineage',
|
||||
width: '500px',
|
||||
image1: {
|
||||
image: governanceList,
|
||||
width: '120px',
|
||||
position: 'governance-top-left',
|
||||
},
|
||||
image2: {
|
||||
image: governanceItems,
|
||||
width: '160px',
|
||||
position: 'governance-middle-right',
|
||||
},
|
||||
image3: {
|
||||
image: governanceReviewer,
|
||||
width: '220px',
|
||||
position: 'governance-bottom-right',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'data-collaboration',
|
||||
image: collaborationImg,
|
||||
descriptionKey: 'deeply-understand-table-relations-message',
|
||||
width: '350px',
|
||||
image1: {
|
||||
image: collaborationTabs,
|
||||
width: '200px',
|
||||
position: 'collab-top-left',
|
||||
},
|
||||
image2: {
|
||||
image: collaborationMenu,
|
||||
width: '200px',
|
||||
position: 'collab-middle-right',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'data-observability',
|
||||
image: dataObservabilityImg,
|
||||
descriptionKey:
|
||||
'discover-your-data-and-unlock-the-value-of-data-assets',
|
||||
width: '370px',
|
||||
image1: {
|
||||
image: observabilityTestcase,
|
||||
width: '250px',
|
||||
position: 'observability-bottom-right',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'data-discovery',
|
||||
image: discoveryImg,
|
||||
descriptionKey: 'enables-end-to-end-metadata-management',
|
||||
width: '500px',
|
||||
image1: {
|
||||
image: discoveryLanguage,
|
||||
width: '130px',
|
||||
position: 'discovery-top-right',
|
||||
},
|
||||
image2: {
|
||||
image: discoveryDataAssets,
|
||||
width: '130px',
|
||||
position: 'discovery-middle-right',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return carouselContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Woche",
|
||||
"weekly-usage": "Wöchentliche Verwendung",
|
||||
"weight": "Gewichtung",
|
||||
"welcome-to": "Velkommen til",
|
||||
"whats-new": "Neuigkeiten",
|
||||
"whats-new-version": "Änderungen in ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Week",
|
||||
"weekly-usage": "Weekly Usage",
|
||||
"weight": "Weight",
|
||||
"welcome-to": "Welcome to",
|
||||
"whats-new": "What's New",
|
||||
"whats-new-version": "What's New ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Semana",
|
||||
"weekly-usage": "Uso semanal",
|
||||
"weight": "Peso",
|
||||
"welcome-to": "Bienvenido a",
|
||||
"whats-new": "Novedades",
|
||||
"whats-new-version": "Qué hay de nuevo ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Semaine",
|
||||
"weekly-usage": "Utilisation Hebdomadaire",
|
||||
"weight": "Poids",
|
||||
"welcome-to": "Bienvenue à",
|
||||
"whats-new": "Nouveautés",
|
||||
"whats-new-version": "Nouveautés ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Semana",
|
||||
"weekly-usage": "Uso semanal",
|
||||
"weight": "Peso",
|
||||
"welcome-to": "Benvido a",
|
||||
"whats-new": "Novidades",
|
||||
"whats-new-version": "Novidades ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "שבוע",
|
||||
"weekly-usage": "שימוש שבועי",
|
||||
"weight": "משקל",
|
||||
"welcome-to": "ברוך הבא ל־",
|
||||
"whats-new": "מה חדש",
|
||||
"whats-new-version": "מה חדש ({{version}})",
|
||||
"widget": "ווידג'ט",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "週",
|
||||
"weekly-usage": "Weekly Usage",
|
||||
"weight": "重み",
|
||||
"welcome-to": "ようこそ",
|
||||
"whats-new": "最新情報",
|
||||
"whats-new-version": "What's New ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "주",
|
||||
"weekly-usage": "주간 사용량",
|
||||
"weight": "가중치",
|
||||
"welcome-to": "환영합니다",
|
||||
"whats-new": "새로운 소식",
|
||||
"whats-new-version": "새로운 소식 ({{version}})",
|
||||
"widget": "위젯",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "आठवडा",
|
||||
"weekly-usage": "साप्ताहिक वापर",
|
||||
"weight": "वजन",
|
||||
"welcome-to": "आपले स्वागत आहे",
|
||||
"whats-new": "नवीन काय आहे",
|
||||
"whats-new-version": "नवीन काय आहे ({{version}})",
|
||||
"widget": "विजेट",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Week",
|
||||
"weekly-usage": "Wekelijks gebruik",
|
||||
"weight": "Gewicht",
|
||||
"welcome-to": "Welkom bij",
|
||||
"whats-new": "Wat is nieuw",
|
||||
"whats-new-version": "Wat is nieuw ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "هفته",
|
||||
"weekly-usage": "استفاده هفتگی",
|
||||
"weight": "وزن",
|
||||
"welcome-to": "خوش آمدید به",
|
||||
"whats-new": "چه چیز جدید است",
|
||||
"whats-new-version": "چه چیز جدید است ({{version}})",
|
||||
"widget": "ویجت",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Semana",
|
||||
"weekly-usage": "Uso Semanal",
|
||||
"weight": "Peso",
|
||||
"welcome-to": "Bem-vindo ao",
|
||||
"whats-new": "Novidades",
|
||||
"whats-new-version": "Novidades ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Semana",
|
||||
"weekly-usage": "Uso Semanal",
|
||||
"weight": "Peso",
|
||||
"welcome-to": "Bem-vindo a",
|
||||
"whats-new": "Novidades",
|
||||
"whats-new-version": "Novidades ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "Неделя",
|
||||
"weekly-usage": "Еженедельное использование",
|
||||
"weight": "Вес",
|
||||
"welcome-to": "Добро пожаловать в",
|
||||
"whats-new": "Новости",
|
||||
"whats-new-version": "What's New ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "สัปดาห์",
|
||||
"weekly-usage": "การใช้งานรายสัปดาห์",
|
||||
"weight": "น้ำหนัก",
|
||||
"welcome-to": "ยินดีต้อนรับสู่",
|
||||
"whats-new": "สิ่งที่ใหม่",
|
||||
"whats-new-version": "สิ่งที่ใหม่ ({{version}})",
|
||||
"widget": "วิดเจ็ต",
|
||||
|
@ -1521,6 +1521,7 @@
|
||||
"week": "周",
|
||||
"weekly-usage": "周使用率",
|
||||
"weight": "权重",
|
||||
"welcome-to": "欢迎来到",
|
||||
"whats-new": "最新消息",
|
||||
"whats-new-version": "最新消息 ({{version}})",
|
||||
"widget": "Widget",
|
||||
|
@ -14,9 +14,11 @@
|
||||
import { act, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { LOGIN_SLIDE } from '../../constants/Login.constants';
|
||||
import loginClassBase from '../../constants/LoginClassBase';
|
||||
import LoginCarousel from './LoginCarousel';
|
||||
|
||||
const LOGIN_SLIDE = loginClassBase.getLoginCarouselContent();
|
||||
|
||||
describe('Test LoginCarousel component', () => {
|
||||
it('renders the carousel container', () => {
|
||||
render(<LoginCarousel />);
|
||||
|
@ -14,33 +14,75 @@
|
||||
import { Carousel, Typography } from 'antd';
|
||||
import { t } from 'i18next';
|
||||
import { uniqueId } from 'lodash';
|
||||
import React from 'react';
|
||||
import { LOGIN_SLIDE } from '../../constants/Login.constants';
|
||||
import React, { useState } from 'react';
|
||||
import loginClassBase from '../../constants/LoginClassBase';
|
||||
|
||||
const LoginCarousel = () => {
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
const carouselContent = loginClassBase.getLoginCarouselContent();
|
||||
|
||||
return (
|
||||
<div className="carousal-container" data-testid="carousel-container">
|
||||
<Carousel autoplay dots autoplaySpeed={3000} easing="ease-in-out">
|
||||
{LOGIN_SLIDE.map((data) => (
|
||||
<Carousel
|
||||
autoplay
|
||||
dots
|
||||
autoplaySpeed={5000}
|
||||
beforeChange={(_, next) => setCurrentIndex(next)}
|
||||
easing="ease-in-out"
|
||||
effect="fade">
|
||||
{carouselContent.map((data, idx) => (
|
||||
<div
|
||||
className="text-center"
|
||||
data-testid="slider-container"
|
||||
key={uniqueId()}>
|
||||
<Typography.Title className="text-primary" level={1}>
|
||||
key={uniqueId() + '-' + currentIndex + '-' + idx}>
|
||||
<Typography.Title className="carousel-header" level={1}>
|
||||
{t(`label.${data.title}`)}
|
||||
</Typography.Title>
|
||||
<p
|
||||
className="m-b-lg carousal-description text-grey-muted"
|
||||
className="m-b-lg carousal-description"
|
||||
data-testid="carousel-slide-description">
|
||||
{t(`message.${data.descriptionKey}`)}
|
||||
</p>
|
||||
<div className="image-container">
|
||||
<img
|
||||
alt="slider"
|
||||
key={`main-${currentIndex}-${idx}`}
|
||||
loading="lazy"
|
||||
src={data.image}
|
||||
style={{ display: 'initial' }}
|
||||
width="750px"
|
||||
width={data.width}
|
||||
/>
|
||||
{data.image1 && (
|
||||
<img
|
||||
alt="slider"
|
||||
className={data.image1.position}
|
||||
key={`img1-${currentIndex}-${idx}`}
|
||||
loading="lazy"
|
||||
src={data.image1.image}
|
||||
width={data.image1.width}
|
||||
/>
|
||||
)}
|
||||
{data.image2 && (
|
||||
<img
|
||||
alt="slider"
|
||||
className={data.image2.position}
|
||||
key={`img2-${currentIndex}-${idx}`}
|
||||
loading="lazy"
|
||||
src={data.image2.image}
|
||||
width={data.image2.width}
|
||||
/>
|
||||
)}
|
||||
{data.image3 && (
|
||||
<img
|
||||
alt="slider"
|
||||
className={data.image3.position}
|
||||
key={`img3-${currentIndex}-${idx}`}
|
||||
loading="lazy"
|
||||
src={data.image3.image}
|
||||
width={data.image3.width}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
|
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Col, Divider, Form, Input, Row, Typography } from 'antd';
|
||||
import { Button, Col, Form, Input, Row, Typography } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -33,6 +33,7 @@ import { EMAIL_REG_EX } from '../../constants/regex.constants';
|
||||
import { AuthProvider } from '../../generated/settings/settings';
|
||||
import { useAlertStore } from '../../hooks/useAlertStore';
|
||||
import { useApplicationStore } from '../../hooks/useApplicationStore';
|
||||
import brandClassBase from '../../utils/BrandData/BrandClassBase';
|
||||
import './login.style.less';
|
||||
import LoginCarousel from './LoginCarousel';
|
||||
|
||||
@ -46,6 +47,8 @@ const SignInPage = () => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const brandName = brandClassBase.getPageTitle();
|
||||
|
||||
const { isAuthProviderBasic, isAuthProviderLDAP } = useMemo(() => {
|
||||
return {
|
||||
isAuthProviderBasic:
|
||||
@ -166,16 +169,16 @@ const SignInPage = () => {
|
||||
return (
|
||||
<>
|
||||
<DocumentTitle title={t('label.sign-in')} />
|
||||
<Row className="h-full" data-testid="signin-page">
|
||||
<Col className="bg-white" span={8}>
|
||||
<Row className="login-form-container" data-testid="signin-page">
|
||||
<Col span={10}>
|
||||
<div
|
||||
className={classNames('mt-24 text-center flex-center flex-col', {
|
||||
className={classNames('form-item', {
|
||||
'sso-container': !isAuthProviderBasic,
|
||||
})}>
|
||||
<BrandImage height="auto" width={200} />
|
||||
<Typography.Text className="mt-8 w-80 text-xl font-medium text-grey-muted">
|
||||
{t('message.om-description')}{' '}
|
||||
</Typography.Text>
|
||||
<BrandImage isMonoGram height="auto" width={50} />
|
||||
<Typography.Title className="header-text" level={3}>
|
||||
{t('label.welcome-to')} {brandName}
|
||||
</Typography.Title>
|
||||
{alert && (
|
||||
<div className="login-alert">
|
||||
<AlertBar
|
||||
@ -209,22 +212,38 @@ const SignInPage = () => {
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Input autoFocus placeholder={t('label.email')} />
|
||||
<Input
|
||||
autoFocus
|
||||
className="input-field"
|
||||
placeholder={t('label.email')}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
data-testid="password"
|
||||
label={t('label.password')}
|
||||
label={
|
||||
<div className="label-flex">
|
||||
<Typography.Text className="mr-1">
|
||||
{t('label.password')}
|
||||
</Typography.Text>
|
||||
<Typography.Link
|
||||
data-testid="forgot-password"
|
||||
onClick={onClickForgotPassword}>
|
||||
{t('label.forgot-password')}
|
||||
</Typography.Link>
|
||||
</div>
|
||||
}
|
||||
name="password"
|
||||
requiredMark={false}
|
||||
rules={[{ required: true }]}>
|
||||
<Input.Password
|
||||
autoComplete="off"
|
||||
className="input-field"
|
||||
placeholder={t('label.password')}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Button
|
||||
className="w-full"
|
||||
className="w-full p-y-lg d-flex flex-center"
|
||||
data-testid="login"
|
||||
disabled={loading}
|
||||
htmlType="submit"
|
||||
@ -235,21 +254,9 @@ const SignInPage = () => {
|
||||
</Form>
|
||||
{!isAuthProviderLDAP && (
|
||||
<>
|
||||
<div className="mt-8" onClick={onClickForgotPassword}>
|
||||
<Typography.Link underline data-testid="forgot-password">
|
||||
{t('label.forgot-password')}
|
||||
</Typography.Link>
|
||||
</div>
|
||||
{authConfig?.enableSelfSignup && (
|
||||
<>
|
||||
<Divider className="w-min-0 mt-8 mb-12 justify-center">
|
||||
<Typography.Text className="text-sm" type="secondary">
|
||||
{t('label.or-lowercase')}
|
||||
</Typography.Text>
|
||||
</Divider>
|
||||
|
||||
<div className="mt-4 d-flex flex-center">
|
||||
<Typography.Text className="mr-4">
|
||||
<Typography.Text className="mr-1">
|
||||
{t('message.new-to-the-platform')}
|
||||
</Typography.Text>
|
||||
<Button
|
||||
@ -261,7 +268,6 @@ const SignInPage = () => {
|
||||
})}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
@ -271,11 +277,11 @@ const SignInPage = () => {
|
||||
)}
|
||||
</div>
|
||||
</Col>
|
||||
<Col className="relative" span={16}>
|
||||
<Col className="form-carousel-container" span={14}>
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
alt="Login Background"
|
||||
className="w-full h-full"
|
||||
className="w-full h-max-full"
|
||||
data-testid="bg-image"
|
||||
src={loginBG}
|
||||
/>
|
||||
|
@ -13,6 +13,120 @@
|
||||
|
||||
@import (reference) url('./../../styles/variables.less');
|
||||
|
||||
.login-form-container {
|
||||
background-color: @grey-100;
|
||||
padding: @size-lg;
|
||||
padding-left: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
padding: @size-md;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form-carousel-container {
|
||||
position: fixed;
|
||||
right: @size-md;
|
||||
top: @size-md;
|
||||
width: calc(58.33% - @size-md * 2);
|
||||
height: calc(100vh - @size-md * 2);
|
||||
overflow: hidden;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.form-item {
|
||||
background-color: @white;
|
||||
border-radius: @border-radius-lg;
|
||||
box-shadow: 0px 24px 48px -12px rgba(10, 13, 18, 0.18);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: @size-2xl;
|
||||
padding: @size-xl @size-2xl;
|
||||
text-align: center;
|
||||
height: auto;
|
||||
max-width: 500px;
|
||||
margin-left: @size-2xl;
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
margin: @size-md;
|
||||
padding: @size-lg;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
.header-text {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: @grey-800;
|
||||
margin-top: @size-xl;
|
||||
margin-bottom: 0px;
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
font-size: 24px;
|
||||
margin-top: @size-lg;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
color: @grey-text;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
padding: @size-sm @size-md;
|
||||
border-radius: @border-radius-xs;
|
||||
border: 1px solid @grey-22;
|
||||
background-color: @grey-23 !important;
|
||||
}
|
||||
|
||||
.input-field::placeholder {
|
||||
color: @grey-24;
|
||||
}
|
||||
|
||||
#password,
|
||||
#confirmPassword,
|
||||
.input-field:focus {
|
||||
background-color: @grey-23;
|
||||
}
|
||||
|
||||
.label-flex {
|
||||
width: 380px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1600px) {
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-header {
|
||||
color: @white;
|
||||
font-weight: 700;
|
||||
font-size: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-explain-error {
|
||||
text-align: left;
|
||||
}
|
||||
@ -28,20 +142,59 @@
|
||||
}
|
||||
.login-form {
|
||||
margin-top: 3rem;
|
||||
width: 334px;
|
||||
width: 380px;
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
margin: 2rem auto 0;
|
||||
}
|
||||
|
||||
.error-alert {
|
||||
border-color: #fbb4ae;
|
||||
}
|
||||
}
|
||||
.login-alert {
|
||||
margin-top: 1rem;
|
||||
width: 334px;
|
||||
}
|
||||
.carousal-description {
|
||||
width: 750px;
|
||||
width: 600px;
|
||||
text-align: center;
|
||||
margin: 16px auto;
|
||||
padding: 0 48px;
|
||||
color: @grey-200;
|
||||
font-size: @size-md;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInFromLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-50px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInFromRight {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(50px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.carousal-container {
|
||||
@ -52,21 +205,187 @@
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.slick-dots.slick-dots-bottom {
|
||||
position: initial;
|
||||
.slick-active {
|
||||
button {
|
||||
background-color: @primary-color;
|
||||
width: inherit;
|
||||
border-radius: 5px;
|
||||
.image-container {
|
||||
position: relative;
|
||||
z-index: 8;
|
||||
top: 10px;
|
||||
|
||||
.governance-top-left {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 16%;
|
||||
animation: slideInFromLeft 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
left: 22%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
left: 10%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
left: 5%;
|
||||
}
|
||||
}
|
||||
button {
|
||||
background-color: @primary-color;
|
||||
opacity: 0.7;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 50%;
|
||||
|
||||
.governance-middle-right {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 16%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 22%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
right: 10%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
right: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
.governance-bottom-right {
|
||||
position: absolute;
|
||||
bottom: -4%;
|
||||
right: 16%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 22%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
right: 10%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
right: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
.collab-top-left {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
left: 23%;
|
||||
animation: slideInFromLeft 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
left: 30%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
left: 20%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
left: 16%;
|
||||
}
|
||||
}
|
||||
|
||||
.collab-middle-right {
|
||||
position: absolute;
|
||||
top: 44%;
|
||||
right: 20%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 30%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
right: 16%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
right: 12%;
|
||||
}
|
||||
}
|
||||
|
||||
.observability-bottom-right {
|
||||
position: absolute;
|
||||
bottom: -26px;
|
||||
right: 22%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 28%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
right: 18%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
right: 16%;
|
||||
}
|
||||
}
|
||||
|
||||
.discovery-top-right {
|
||||
position: absolute;
|
||||
top: -16px;
|
||||
right: 16%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 22%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1300px) {
|
||||
right: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
.discovery-middle-right {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
right: 16%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 22%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1300px) {
|
||||
right: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
.ai-top-right {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 20%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 28%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1300px) {
|
||||
right: 14%;
|
||||
}
|
||||
}
|
||||
|
||||
.ai-bottom-right {
|
||||
position: absolute;
|
||||
bottom: -28px;
|
||||
right: 16%;
|
||||
animation: slideInFromRight 1.5s ease-in-out;
|
||||
|
||||
@media screen and (min-width: 1700px) {
|
||||
right: 22%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1300px) {
|
||||
right: 12%;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
animation: fadeIn 1s ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Col, Divider, Form, Input, Row, Typography } from 'antd';
|
||||
import { Button, Col, Form, Input, Row, Typography } from 'antd';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -75,11 +75,11 @@ const BasicSignUp = () => {
|
||||
return (
|
||||
<>
|
||||
<DocumentTitle title={t('label.sign-up')} />
|
||||
<Row className="h-full" data-testid="signin-page">
|
||||
<Col className="bg-white" span={10}>
|
||||
<div className="mt-4 text-center flex-center flex-col">
|
||||
<BrandImage height="auto" width={200} />
|
||||
<Typography.Text className="mt-8 w-80 text-xl font-medium text-grey-muted">
|
||||
<Row className="login-form-container" data-testid="signin-page">
|
||||
<Col lg={10} sm={24}>
|
||||
<div className="form-item">
|
||||
<BrandImage height="auto" width={160} />
|
||||
<Typography.Text className="text-lg text-grey-muted m-t-lg">
|
||||
{t('message.om-description')}
|
||||
</Typography.Text>
|
||||
|
||||
@ -109,6 +109,7 @@ const BasicSignUp = () => {
|
||||
rules={[{ whitespace: true, required: true }]}>
|
||||
<Input
|
||||
autoFocus
|
||||
className="input-field"
|
||||
placeholder={t('label.enter-entity-name', {
|
||||
entity: t('label.first-lowercase'),
|
||||
})}
|
||||
@ -121,6 +122,7 @@ const BasicSignUp = () => {
|
||||
name="lastName"
|
||||
rules={[{ whitespace: true, required: true }]}>
|
||||
<Input
|
||||
className="input-field"
|
||||
placeholder={t('label.enter-entity', {
|
||||
entity: t('label.last-name-lowercase'),
|
||||
})}
|
||||
@ -131,6 +133,7 @@ const BasicSignUp = () => {
|
||||
name="email"
|
||||
rules={[{ type: 'email', required: true }]}>
|
||||
<Input
|
||||
className="input-field"
|
||||
placeholder={t('label.enter-entity', {
|
||||
entity: t('label.email-lowercase'),
|
||||
})}
|
||||
@ -150,6 +153,7 @@ const BasicSignUp = () => {
|
||||
]}>
|
||||
<Input.Password
|
||||
autoComplete="off"
|
||||
className="input-field"
|
||||
placeholder={t('label.enter-entity', {
|
||||
entity: t('label.password-lowercase'),
|
||||
})}
|
||||
@ -180,22 +184,20 @@ const BasicSignUp = () => {
|
||||
]}>
|
||||
<Input.Password
|
||||
autoComplete="off"
|
||||
className="input-field"
|
||||
placeholder={t('label.confirm-password')}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Button className="w-full" htmlType="submit" type="primary">
|
||||
<Button
|
||||
className="w-full p-y-lg d-flex flex-center"
|
||||
htmlType="submit"
|
||||
type="primary">
|
||||
{t('label.create-entity', {
|
||||
entity: t('label.account'),
|
||||
})}
|
||||
</Button>
|
||||
|
||||
<Divider className="w-min-0 mt-8 mb-12 justify-center">
|
||||
<Typography.Text type="secondary">
|
||||
{t('label.or-lowercase')}
|
||||
</Typography.Text>
|
||||
</Divider>
|
||||
|
||||
<div className="mt-4 d-flex flex-center">
|
||||
<Typography.Text className="mr-4">
|
||||
{t('message.already-a-user')}
|
||||
@ -214,7 +216,7 @@ const BasicSignUp = () => {
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
<Col className="relative" span={14}>
|
||||
<Col className="form-carousel-container" lg={14} sm={0}>
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
alt="bg-image"
|
||||
|
@ -102,6 +102,7 @@
|
||||
@blue-26: #1849a9;
|
||||
@blue-27: #2196f3;
|
||||
@blue-28: #e3f2fd4d;
|
||||
@grey-text: #2c2c2c;
|
||||
|
||||
@partial-success-1: #06a4a4;
|
||||
@partial-success-2: #bdeeee;
|
||||
@ -125,6 +126,9 @@
|
||||
@grey-19: #363f72;
|
||||
@grey-20: #dce3ec;
|
||||
@grey-21: #ababab;
|
||||
@grey-22: #d9d9d9;
|
||||
@grey-23: #f7f7f7;
|
||||
@grey-24: #979797;
|
||||
|
||||
@text-grey-muted: @grey-4;
|
||||
@de-active-color: #6b7280;
|
||||
|