feat(improvements): improve landing page & add new components + forms validation
improve landing page, improve register component (add proffesional validation, change styles + etc), add footer component (with small rotated cube as logo), improve formGeneratorfeat/x_gpu/new_version
parent
b91896e6a5
commit
9da564e2e6
|
|
@ -0,0 +1,91 @@
|
|||
import React from 'react';
|
||||
|
||||
import '../styles/general.scss';
|
||||
|
||||
import SmallCubeComponent from './smallCube.js';
|
||||
|
||||
|
||||
const FootComponent = () => {
|
||||
return (
|
||||
<footer>
|
||||
<div className="content-container">
|
||||
<div className="content">
|
||||
<div className="section">
|
||||
<SmallCubeComponent />
|
||||
</div>
|
||||
<div className="section">
|
||||
<h4>
|
||||
<a>
|
||||
BUSINESS
|
||||
</a>
|
||||
</h4>
|
||||
<h4>
|
||||
<a>
|
||||
SIGN IN
|
||||
</a>
|
||||
</h4>
|
||||
<h4>
|
||||
<a>
|
||||
SIGN UP
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
<div className="section">
|
||||
<h4>
|
||||
Company
|
||||
</h4>
|
||||
</div>
|
||||
<div className="section">
|
||||
<a>
|
||||
About Us
|
||||
</a>
|
||||
</div>
|
||||
<div className="section">
|
||||
<a>
|
||||
Contact Us
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
<div className="section">
|
||||
<h4>
|
||||
Resources
|
||||
</h4>
|
||||
</div>
|
||||
<div className="section">
|
||||
<a>
|
||||
Blog
|
||||
</a>
|
||||
</div>
|
||||
<div className="section">
|
||||
<a>
|
||||
Help Center
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
<div className="section">
|
||||
</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
<div className="section">
|
||||
</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
<div className="section">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bottom">
|
||||
<p>
|
||||
© {new Date().getFullYear()} FehuDev. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default FootComponent
|
||||
|
|
@ -109,6 +109,8 @@ export const FormGenerator = ({
|
|||
? <></>
|
||||
: <button
|
||||
type='submit'
|
||||
disabled={ info.allowButtonAction }
|
||||
className={ info.allowButtonAction === false ? "button-disabled" : "" }
|
||||
>
|
||||
{ info.button_value }
|
||||
</button>
|
||||
|
|
@ -145,7 +147,17 @@ const TextInputGenerator = ({
|
|||
id={input.name + info.action + info.endpoint + 'Input'}
|
||||
autoComplete='off'
|
||||
ref={input.ref}
|
||||
onChange={input.onChange}
|
||||
className={ [ "Empty", "Success"].includes(input.validationInfo) ? "" : "input-incorrect" }
|
||||
/>
|
||||
<div
|
||||
className="popup"
|
||||
style={ [ "Empty", "Success"].includes(input.validationInfo) ? {"display": "none", "height": "0px"} : {"display": "block"} }
|
||||
>
|
||||
<div className="popup-content">
|
||||
{ input.validationInfo }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -178,7 +190,17 @@ const PasswordInputGenerator = ({
|
|||
autoComplete='off'
|
||||
ref={input.ref}
|
||||
type='password'
|
||||
onChange={input.onChange}
|
||||
className={ [ "Empty", "Success"].includes(input.validationInfo) ? "" : "input-incorrect" }
|
||||
/>
|
||||
<div
|
||||
className="popup"
|
||||
style={ [ "Empty", "Success"].includes(input.validationInfo) ? {"display": "none", "height": "0px"} : {"display": "block"} }
|
||||
>
|
||||
<div className="popup-content">
|
||||
{ input.validationInfo }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const UserLoginForm = () => {
|
|||
|
||||
// const dispatch = useDispatch()
|
||||
// const { info } = useSelector( userAuthSelector )
|
||||
const info = ""
|
||||
const info = "" // if redux is integrated - delete this line
|
||||
|
||||
let refList = [
|
||||
usernameInput,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
// import { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
import { userCrudSelector } from '../../../redux/slices/userCrudSlice'
|
||||
import userCrudAsyncThunk from '../../../redux/asyncThunks/userCrudAsyncThunk'
|
||||
// import { userCrudSelector } from '../../../redux/slices/userCrudSlice'
|
||||
// import userCrudAsyncThunk from '../../../redux/asyncThunks/userCrudAsyncThunk'
|
||||
|
||||
import FormGenerator from '../formGenerator'
|
||||
|
||||
|
|
@ -12,52 +12,126 @@ const UserRegisterForm = () => {
|
|||
|
||||
const usernameInput = React.createRef()
|
||||
const passwordInput = React.createRef()
|
||||
const emailInput = React.createRef()
|
||||
const confirmPasswordInput = React.createRef()
|
||||
|
||||
const dispatch = useDispatch()
|
||||
const { info } = useSelector( userCrudSelector )
|
||||
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
|
||||
|
||||
const [usernameValidationInfo, setUsernameValidationInfo] = useState("Empty")
|
||||
const [passwordValidationInfo, setPasswordValidationInfo] = useState("Empty")
|
||||
const [confirmPasswordValidationInfo, setConfirmPasswordValidationInfo] = useState("Empty")
|
||||
|
||||
const [password, setPassword] = useState("")
|
||||
const [confirmPassword, setConfirmPassword] = useState("")
|
||||
|
||||
const [allowButtonAction, setAllowButtonAction] = useState(false)
|
||||
|
||||
const usernameValidation = (event) => {
|
||||
if (event.target.value === "") {
|
||||
setUsernameValidationInfo("Email is required.")
|
||||
} else if(!emailRegex.test(event.target.value)) {
|
||||
setUsernameValidationInfo("Please provide correct email")
|
||||
} else {
|
||||
setUsernameValidationInfo("Success")
|
||||
}
|
||||
}
|
||||
|
||||
const passwordValidation = (event) => {
|
||||
|
||||
setPassword(event.target.value)
|
||||
|
||||
if (event.target.value === "") {
|
||||
setPasswordValidationInfo("Password is required.")
|
||||
} else if(!passwordRegex.test(event.target.value)) {
|
||||
setPasswordValidationInfo("Password require:\n - At least 8 characters,\n - At least one uppercase letter,\n - At least one lowercase letter,\n - At least one digit,\n - At least one special character.")
|
||||
} else {
|
||||
setPasswordValidationInfo("Success")
|
||||
}
|
||||
|
||||
if(event.target.value !== confirmPassword) {
|
||||
setConfirmPasswordValidationInfo("Passwords are different.")
|
||||
} else {
|
||||
setConfirmPasswordValidationInfo("Success")
|
||||
}
|
||||
}
|
||||
|
||||
const confirmPasswordValidation = (event) => {
|
||||
|
||||
setConfirmPassword(event.target.value)
|
||||
|
||||
if(event.target.value !== password) {
|
||||
setConfirmPasswordValidationInfo("Passwords are different.")
|
||||
} else {
|
||||
setConfirmPasswordValidationInfo("Success")
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setAllowButtonAction(
|
||||
usernameValidationInfo === "Success"
|
||||
&& passwordValidationInfo === "Success"
|
||||
&& confirmPasswordValidationInfo === "Success"
|
||||
)
|
||||
}, [
|
||||
allowButtonAction,
|
||||
usernameValidationInfo,
|
||||
passwordValidationInfo,
|
||||
confirmPasswordValidationInfo
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
// const dispatch = useDispatch()
|
||||
// const { info } = useSelector( userCrudSelector )
|
||||
const info = "" // if redux is integrated - delete this line
|
||||
|
||||
let refList = [
|
||||
usernameInput,
|
||||
passwordInput,
|
||||
emailInput
|
||||
confirmPasswordInput
|
||||
]
|
||||
|
||||
let inputList = [
|
||||
{
|
||||
type: 'info',
|
||||
action: 'Create',
|
||||
endpint: 'user/auth/login',
|
||||
button_value: 'Sign Up'
|
||||
endpint: 'user/auth/register',
|
||||
button_value: 'SIGN UP',
|
||||
allowButtonAction: allowButtonAction
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'Username',
|
||||
ref: usernameInput
|
||||
name: 'EMAIL',
|
||||
ref: usernameInput,
|
||||
onChange: usernameValidation,
|
||||
validationInfo: usernameValidationInfo
|
||||
},
|
||||
{
|
||||
type: 'password',
|
||||
name: 'Password',
|
||||
ref: passwordInput
|
||||
name: 'PASSWORD',
|
||||
ref: passwordInput,
|
||||
onChange: passwordValidation,
|
||||
validationInfo: passwordValidationInfo
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'Email',
|
||||
ref: emailInput
|
||||
type: 'password',
|
||||
name: 'CONFIRM PASSWORD',
|
||||
ref: confirmPasswordInput,
|
||||
onChange: confirmPasswordValidation,
|
||||
validationInfo: confirmPasswordValidationInfo
|
||||
}
|
||||
]
|
||||
|
||||
const register = async ( refs ) => {
|
||||
let pass = {
|
||||
username: refs[0].current.value,
|
||||
password: refs[1].current.value,
|
||||
email: refs[2].current.value,
|
||||
password: refs[1].current.value
|
||||
}
|
||||
dispatch(
|
||||
userCrudAsyncThunk.fetchRegister(
|
||||
pass
|
||||
)
|
||||
)
|
||||
// dispatch(
|
||||
// userCrudAsyncThunk.fetchRegister(
|
||||
// pass
|
||||
// )
|
||||
// )
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react';
|
||||
|
||||
import '../styles/LoginPage.cube.scss';
|
||||
import '../styles/large.cube.scss';
|
||||
|
||||
|
||||
const GraphicContainerComponent = () => {
|
||||
const LargeCubeComponent = () => {
|
||||
return (
|
||||
<div className="graphic-container">
|
||||
<div className="cube">
|
||||
|
|
@ -19,4 +19,4 @@ const GraphicContainerComponent = () => {
|
|||
}
|
||||
|
||||
|
||||
export default GraphicContainerComponent
|
||||
export default LargeCubeComponent
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import React from 'react';
|
||||
|
||||
import '../styles/small.cube.scss';
|
||||
|
||||
|
||||
const SmallCubeComponent = () => {
|
||||
return (
|
||||
<div className="graphic-container">
|
||||
<div className="cube">
|
||||
<div className="face-front"></div>
|
||||
<div className="face-back"></div>
|
||||
<div className="face-right"></div>
|
||||
<div className="face-left"></div>
|
||||
<div className="face-top"></div>
|
||||
<div className="face-bottom"></div>
|
||||
</div>
|
||||
<div className="title">
|
||||
XGPU
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default SmallCubeComponent
|
||||
|
|
@ -2,36 +2,83 @@ import React from 'react';
|
|||
|
||||
import '../styles/general.scss';
|
||||
|
||||
import GraphicContainerComponent from '../components/graphic-container.js';
|
||||
import UserRegisterForm from '../components/forms/user_auth/userRegister.js';
|
||||
import FootComponent from '../components/foot.js';
|
||||
|
||||
const LandingPage = () => {
|
||||
return (
|
||||
<div className="login-container">
|
||||
<div className="landing-container">
|
||||
<header className="landing">
|
||||
<h2>Affordable. Efficient. Accessible.</h2>
|
||||
<h1>GUARANTED.</h1>
|
||||
<p>
|
||||
Minimize your expenses without compromising on quality.
|
||||
<br />
|
||||
Our platform is built for individuals
|
||||
Our platform is built for individuals who need top-tier rendering
|
||||
<br />
|
||||
<span className="span-white">
|
||||
who need top-tier rendering without the top-tier investment.
|
||||
without the top-tier investment.
|
||||
</span>
|
||||
</p>
|
||||
<button>
|
||||
GET A DEMO
|
||||
</button>
|
||||
<h4>
|
||||
GPU IS IMPORTANT...
|
||||
</h4>
|
||||
<p>
|
||||
<span className="span-first-color">
|
||||
GPU Is Important...
|
||||
...But <span className="span-white">GPU server can be very expensive.</span>
|
||||
<br />
|
||||
Configuration and administration<span className="span-white"> take too long time.</span>
|
||||
<br />
|
||||
<span className="span-white">
|
||||
Everything of that needs so much additional knowledge.
|
||||
</span>
|
||||
</p>
|
||||
<h2>
|
||||
We Offer Ready Solution.
|
||||
</h2>
|
||||
<p>
|
||||
Boost your GPU power for your 3D and AI models stuff
|
||||
<br />
|
||||
<span className="span-white">
|
||||
without overpay for servers...
|
||||
</span>
|
||||
<br />
|
||||
...but
|
||||
<span className="span-white">
|
||||
...without overtime for environment adjustments!
|
||||
</span>
|
||||
</p>
|
||||
<h2>
|
||||
"OK... So What Makes You So Different?"
|
||||
</h2>
|
||||
<h4>
|
||||
GUARANTED
|
||||
</h4>
|
||||
<p>
|
||||
We only win if you win. You won't carry all the risk, we'll share it
|
||||
</p>
|
||||
<h4>
|
||||
RESLUTS
|
||||
</h4>
|
||||
<p>
|
||||
Our first priority is to get you results.
|
||||
</p>
|
||||
<h4>
|
||||
LOCAL
|
||||
</h4>
|
||||
<p>
|
||||
</p>
|
||||
<h4>
|
||||
SPECIALIZED
|
||||
</h4>
|
||||
<p>
|
||||
</p>
|
||||
</header>
|
||||
<main className="main-content">
|
||||
<GraphicContainerComponent />
|
||||
<main className="secondary-content">
|
||||
<UserRegisterForm />
|
||||
</main>
|
||||
<FootComponent />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import React from 'react';
|
||||
|
||||
import '../../styles/general.scss';
|
||||
import '../../styles/LoginPage.cube.scss';
|
||||
|
||||
import GraphicContainerComponent from '../../components/graphic-container.js';
|
||||
import LargeCubeComponent from '../../components/largeCube.js';
|
||||
import UserLoginForm from '../../components/forms/user_auth/userLogin.js';
|
||||
|
||||
|
||||
|
|
@ -14,7 +13,7 @@ const LoginPage = () => {
|
|||
<h1>XGPU</h1>
|
||||
</header>
|
||||
<main className="main-content">
|
||||
<GraphicContainerComponent />
|
||||
<LargeCubeComponent />
|
||||
<UserLoginForm />
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ $font-family-default: neue-haas-unica, sans-serif;
|
|||
|
||||
body, html {
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
font-family: $font-family-default;
|
||||
tab-size: 4;
|
||||
background: $background-color;
|
||||
|
|
@ -33,8 +32,6 @@ body, html {
|
|||
// #0a670a 60%,
|
||||
// black 100%
|
||||
// );
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
|
|
@ -49,9 +46,15 @@ body, html {
|
|||
}
|
||||
}
|
||||
|
||||
.landing-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
.landing {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
background: $header-background;
|
||||
color: $title-color;
|
||||
z-index: 3; // Ensure the login form is above the cube
|
||||
|
|
@ -69,6 +72,19 @@ body, html {
|
|||
color: $title-color;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 45px;
|
||||
font-weight: 700;
|
||||
color: $title-color;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: $title-color;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
|
|
@ -111,13 +127,23 @@ body, html {
|
|||
color: black
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-content {
|
||||
//flex: 1;
|
||||
//display: flex;
|
||||
margin-top: 0%;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.secondary-content {
|
||||
width: 100%;
|
||||
background: $form-background;
|
||||
|
||||
.form {
|
||||
background: none;
|
||||
margin-top: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
background: $form-background;
|
||||
|
|
@ -140,6 +166,8 @@ body, html {
|
|||
label {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
input {
|
||||
|
|
@ -157,7 +185,33 @@ body, html {
|
|||
}
|
||||
|
||||
input:active {
|
||||
background-color: rgba(0,128,0,1);
|
||||
background-color: rgba(0,120,0,1);
|
||||
}
|
||||
|
||||
.input-correct {
|
||||
background: rgba(0,120,0,1);
|
||||
border: 1px solid $border-color;
|
||||
}
|
||||
|
||||
.input-incorrect {
|
||||
background: rgba(120,8,0,1);
|
||||
border: 1px solid red;
|
||||
}
|
||||
}
|
||||
|
||||
.popup {
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
padding: 15px;
|
||||
background: rgba(120,8,0,0.5);
|
||||
border: 1px solid red;
|
||||
border-radius: 5px;
|
||||
white-space: pre-line;
|
||||
transition-duration: 0.5s;
|
||||
|
||||
.popup-content {
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +222,7 @@ body, html {
|
|||
border-radius: 5px;
|
||||
background: $button-background;
|
||||
font-family: $font-family-default;
|
||||
font-weight: 800;
|
||||
font-weight: 700;
|
||||
color: rgba(0,0,0,0.5);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
|
@ -179,6 +233,63 @@ body, html {
|
|||
background-color: green;
|
||||
color: black
|
||||
}
|
||||
|
||||
.button-disabled {
|
||||
background: gray;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
width: 70%;
|
||||
background: $form-background;
|
||||
text-align: left;
|
||||
padding: 20px 15%;
|
||||
|
||||
.content-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.content {
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.section {
|
||||
flex: 1;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h4 {
|
||||
color: $title-color;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.graphic-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
p, a {
|
||||
color: $subtitle-color;
|
||||
line-height: 1.6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: $title-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
border-top: 1px solid $subtitle-color;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
font-size: 0.8em;
|
||||
color: $subtitle-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
$cube-size: 30px;
|
||||
$cube-color: rgba(0, 140, 0, 0.5);
|
||||
$perspective: 10000px;
|
||||
$animation-duration: 20s;
|
||||
|
||||
@mixin cube-face {
|
||||
position: absolute;
|
||||
width: $cube-size - 4px;
|
||||
height: $cube-size - 4px;
|
||||
background: $cube-color;
|
||||
}
|
||||
|
||||
@keyframes rotateCube {
|
||||
0% {
|
||||
transform: rotateX(0) rotateY(0) rotateZ(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.graphic-container {
|
||||
display: flex;
|
||||
perspective: $perspective;
|
||||
perspective-origin: 50% 100px; // Adjusted for better 3D effect
|
||||
z-index: 1; // Lower z-index than the login form to place it behind
|
||||
|
||||
.cube {
|
||||
width: $cube-size;
|
||||
height: $cube-size;
|
||||
position: relative;
|
||||
margin: auto; // Centers the cube within the graphic container
|
||||
transform-style: preserve-3d;
|
||||
transform-origin: center center; // Rotates around the center of the cube
|
||||
animation: rotateCube $animation-duration infinite linear;
|
||||
|
||||
div {
|
||||
@include cube-face;
|
||||
}
|
||||
|
||||
.face-front { transform: translateZ($cube-size / 2); }
|
||||
.face-back { transform: translateZ(-$cube-size / 2) rotateY(180deg); }
|
||||
.face-right { transform: rotateY(90deg) translateZ($cube-size / 2); }
|
||||
.face-left { transform: rotateY(-90deg) translateZ($cube-size / 2); }
|
||||
.face-top { transform: rotateX(90deg) translateZ($cube-size / 2); }
|
||||
.face-bottom { transform: rotateX(-90deg) translateZ($cube-size / 2); }
|
||||
|
||||
}
|
||||
|
||||
.title {
|
||||
color: white;
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue