diff --git a/src/components/foot.js b/src/components/foot.js new file mode 100644 index 0000000..9b50842 --- /dev/null +++ b/src/components/foot.js @@ -0,0 +1,91 @@ +import React from 'react'; + +import '../styles/general.scss'; + +import SmallCubeComponent from './smallCube.js'; + + +const FootComponent = () => { + return ( + + ) +} + + +export default FootComponent diff --git a/src/components/forms/formGenerator.js b/src/components/forms/formGenerator.js index 51605f2..634d9aa 100644 --- a/src/components/forms/formGenerator.js +++ b/src/components/forms/formGenerator.js @@ -109,6 +109,8 @@ export const FormGenerator = ({ ? <> : @@ -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" } /> +
+
+ { input.validationInfo } +
+
) } @@ -178,7 +190,17 @@ const PasswordInputGenerator = ({ autoComplete='off' ref={input.ref} type='password' + onChange={input.onChange} + className={ [ "Empty", "Success"].includes(input.validationInfo) ? "" : "input-incorrect" } /> +
+
+ { input.validationInfo } +
+
) } diff --git a/src/components/forms/user_auth/userLogin.js b/src/components/forms/user_auth/userLogin.js index b79596d..f9b2054 100644 --- a/src/components/forms/user_auth/userLogin.js +++ b/src/components/forms/user_auth/userLogin.js @@ -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, diff --git a/src/components/forms/user_auth/userRegister.js b/src/components/forms/user_auth/userRegister.js index 0253a06..f204d7d 100644 --- a/src/components/forms/user_auth/userRegister.js +++ b/src/components/forms/user_auth/userRegister.js @@ -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,57 +12,131 @@ 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 (
- { } -export default UserRegisterForm \ No newline at end of file +export default UserRegisterForm diff --git a/src/components/graphic-container.js b/src/components/largeCube.js similarity index 78% rename from src/components/graphic-container.js rename to src/components/largeCube.js index 7468ece..0f31347 100644 --- a/src/components/graphic-container.js +++ b/src/components/largeCube.js @@ -1,9 +1,9 @@ import React from 'react'; -import '../styles/LoginPage.cube.scss'; +import '../styles/large.cube.scss'; -const GraphicContainerComponent = () => { +const LargeCubeComponent = () => { return (
@@ -19,4 +19,4 @@ const GraphicContainerComponent = () => { } -export default GraphicContainerComponent +export default LargeCubeComponent diff --git a/src/components/smallCube.js b/src/components/smallCube.js new file mode 100644 index 0000000..4af000f --- /dev/null +++ b/src/components/smallCube.js @@ -0,0 +1,25 @@ +import React from 'react'; + +import '../styles/small.cube.scss'; + + +const SmallCubeComponent = () => { + return ( +
+
+
+
+
+
+
+
+
+
+ XGPU +
+
+ ) +} + + +export default SmallCubeComponent diff --git a/src/pages/landing.js b/src/pages/landing.js index 633279f..3dd0f20 100644 --- a/src/pages/landing.js +++ b/src/pages/landing.js @@ -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 ( -
+

Affordable. Efficient. Accessible.

GUARANTED.

Minimize your expenses without compromising on quality.
- Our platform is built for individuals + Our platform is built for individuals who need top-tier rendering +
- who need top-tier rendering without the top-tier investment. + without the top-tier investment.

+

+ GPU IS IMPORTANT... +

- - GPU Is Important... + ...But GPU server can be very expensive. +
+ Configuration and administration take too long time. +
+ + Everything of that needs so much additional knowledge. + +

+

+ We Offer Ready Solution. +

+

+ Boost your GPU power for your 3D and AI models stuff +
+ + without overpay for servers...
- ...but + + ...without overtime for environment adjustments! + +

+

+ "OK... So What Makes You So Different?" +

+

+ GUARANTED +

+

+ We only win if you win. You won't carry all the risk, we'll share it +

+

+ RESLUTS +

+

+ Our first priority is to get you results. +

+

+ LOCAL +

+

+

+

+ SPECIALIZED +

+

-
- +
+
+
) } diff --git a/src/pages/user/login.js b/src/pages/user/login.js index 91626fb..8099f8b 100644 --- a/src/pages/user/login.js +++ b/src/pages/user/login.js @@ -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 = () => {

XGPU

- +
diff --git a/src/styles/general.scss b/src/styles/general.scss index 57150fd..effd229 100644 --- a/src/styles/general.scss +++ b/src/styles/general.scss @@ -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,135 +46,249 @@ body, html { } } - .landing { - text-align: center; - padding: 20px; - background: $header-background; - color: $title-color; - z-index: 3; // Ensure the login form is above the cube - position: relative; // Required for z-index to take effect + .landing-container { + display: flex; + flex-direction: column; + width: 100%; - h1 { - font-size: 60px; - font-weight: 800; - color: $title-color; - } + .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 + position: relative; // Required for z-index to take effect - h2 { - font-size: 60px; - font-weight: 700; - color: $title-color; - } + h1 { + font-size: 60px; + font-weight: 800; + color: $title-color; + } - p { - font-size: 20px; - font-weight: 400; - color: $subtitle-color; - } + h2 { + font-size: 60px; + font-weight: 700; + color: $title-color; + } - span { - font-size: 20px; - font-weight: 400; - padding-left: 5px; - } + h3 { + font-size: 45px; + font-weight: 700; + color: $title-color; + } - .span-white { - color: $title-color; - } + h4 { + font-size: 30px; + font-weight: 700; + color: $title-color; + margin-bottom: 0px; + } - .span-first-color { - color: $first-color; - } + p { + font-size: 20px; + font-weight: 400; + color: $subtitle-color; + } + + span { + font-size: 20px; + font-weight: 400; + padding-left: 5px; + } + + .span-white { + color: $title-color; + } + + .span-first-color { + color: $first-color; + } - button { - margin-top: 35px; - margin-bottom: 35px; - padding-top: 20px; - padding: 25px; - border-radius: 5px; - background: $button-background; - font-size: 20px; - font-family: $font-family-default; - font-weight: 800; - color: rgba(0,0,0,0.5); - border: none; - cursor: pointer; - transition-duration: 0.1s; - } + button { + margin-top: 35px; + margin-bottom: 35px; + padding-top: 20px; + padding: 25px; + border-radius: 5px; + background: $button-background; + font-size: 20px; + font-family: $font-family-default; + font-weight: 800; + color: rgba(0,0,0,0.5); + border: none; + cursor: pointer; + transition-duration: 0.1s; + } - button:hover { - background-color: green; - color: black + button:hover { + background-color: green; + 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: $form-background; - padding: 50px; - width: 350px; - color: $subtitle-color; - // border: 2px solid $border-color; - border-radius: 10px; + background: none; + margin-top: 0px; + } + } - margin-top: -400px; - margin-right: auto; - margin-left: auto; + .form { + background: $form-background; + padding: 50px; + width: 350px; + color: $subtitle-color; + // border: 2px solid $border-color; + border-radius: 10px; - z-index: 2; // Ensure the login form is above the cube - position: relative; // Required for z-index to take effect + margin-top: -400px; + margin-right: auto; + margin-left: auto; - .form-field { + z-index: 2; // Ensure the login form is above the cube + position: relative; // Required for z-index to take effect + + .form-field { + margin-bottom: 15px; + + label { + display: block; margin-bottom: 15px; - - label { - display: block; - margin-bottom: 15px; - } - - input { - width: 90%; - padding: 5%; - background: $input-background; - border: 1px solid $border-color; - border-radius: 5px; - color: white; - transition-duration: 0.5s; - } - - input:hover { - border-color: rgba(111,108,106,1); - } - - input:active { - background-color: rgba(0,128,0,1); - } + text-align: left; + font-weight: 700; } - button { + input { + width: 90%; padding: 5%; - width: 100%; - margin-top: 30px; + background: $input-background; + border: 1px solid $border-color; border-radius: 5px; - background: $button-background; - font-family: $font-family-default; - font-weight: 800; - color: rgba(0,0,0,0.5); - border: none; - cursor: pointer; - transition-duration: 0.1s; + color: white; + transition-duration: 0.5s; } - button:hover { - background-color: green; - color: black + input:hover { + border-color: rgba(111,108,106,1); + } + + input:active { + 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; + } + } + + button { + padding: 5%; + width: 100%; + margin-top: 30px; + border-radius: 5px; + background: $button-background; + font-family: $font-family-default; + font-weight: 700; + color: rgba(0,0,0,0.5); + border: none; + cursor: pointer; + transition-duration: 0.1s; + } + + button:hover { + 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; } } } diff --git a/src/styles/LoginPage.cube.scss b/src/styles/large.cube.scss similarity index 100% rename from src/styles/LoginPage.cube.scss rename to src/styles/large.cube.scss diff --git a/src/styles/small.cube.scss b/src/styles/small.cube.scss new file mode 100644 index 0000000..99f545e --- /dev/null +++ b/src/styles/small.cube.scss @@ -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; + } +}