Skip to content

Commit

Permalink
fix password ui input
Browse files Browse the repository at this point in the history
  • Loading branch information
vladbyk89 committed Aug 20, 2024
1 parent afdbc4c commit d615fda
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 180 deletions.
54 changes: 30 additions & 24 deletions src/view/components/passwordUi/PasswordInput.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { useRef, Dispatch, SetStateAction, useEffect, useState } from 'react';
import styles from "./passwordUi.module.scss";
import { useRef, Dispatch, SetStateAction } from 'react';
import styles from './passwordUi.module.scss';

interface PasswordProps {
passwordLength: 4;
values: string[],
handleSubmit: () => void
setValues: Dispatch<SetStateAction<string[]>>
values: string[];
handleSubmit: () => void;
setValues: Dispatch<SetStateAction<string[]>>;
}

const PasswordInput = ({ handleSubmit, passwordLength: length, values, setValues }: PasswordProps) => {
const PasswordInput = ({
handleSubmit,
passwordLength: length,
values,
setValues,
}: PasswordProps) => {
const inputs = useRef<(HTMLInputElement | null)[]>([]);
const [isSubmitted, setIsSubmitted] = useState(false)

const handleChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
const handleChange = (
event: React.ChangeEvent<HTMLInputElement>,
index: number
) => {
const val = event.target.value;
if (/^[0-9]$/.test(val) || val === '') {
const newValues = [...values];
Expand All @@ -22,35 +29,34 @@ const PasswordInput = ({ handleSubmit, passwordLength: length, values, setValues
inputs.current[index + 1]?.focus();
}
}
}
};

const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, index: number) => {
if (event.key === "Backspace" && !values[index] && index > 0) {
const handleKeyDown = (
event: React.KeyboardEvent<HTMLInputElement>,
index: number
) => {
if (event.key === 'Backspace' && !values[index] && index > 0) {
inputs.current[index - 1]?.focus();
}
}

useEffect(() => {
if (values.every((val => val !== '')) && (!isSubmitted)) {
setIsSubmitted(true)
if (event.key === 'Enter') {
handleSubmit();
}
else {
setIsSubmitted(false)
}
}, [values, handleSubmit]);
};

return (
<div className={styles.passwordUi__inputSection} >
<div className={styles.passwordUi__inputSection}>
{values.map((val, index) => (
<input
key={index}
ref={(element) => { inputs.current[index] = element }}
ref={(element) => {
inputs.current[index] = element;
}}
maxLength={1}
type="text"
type='text'
value={val}
onKeyDown={(event) => handleKeyDown(event, index)}
onChange={(event) => handleChange(event, index)}
onChange={(e) => handleChange(e, index)}
onKeyDown={(e) => handleKeyDown(e, index)}
/>
))}
</div>
Expand Down
83 changes: 38 additions & 45 deletions src/view/components/passwordUi/PasswordUi.tsx
Original file line number Diff line number Diff line change
@@ -1,94 +1,89 @@
"use client"
import { Dispatch, SetStateAction, useState } from "react"
import { useNavigate } from "react-router-dom"
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

//styles
import styles from "./passwordUi.module.scss"
import styles from './passwordUi.module.scss';

//images
import passwordUiImgBlue from "../../../assets/images/passwordUiImgBlue.png"
import passwordUiImgRed from "../../../assets/images/passwordUiImgRed.png"
import passwordUiImgGreen from "../../../assets/images/passwordUiImgGreen.png"
import passwordUiImgBlue from '../../../assets/images/passwordUiImgBlue.png';
import passwordUiImgRed from '../../../assets/images/passwordUiImgRed.png';
import passwordUiImgGreen from '../../../assets/images/passwordUiImgGreen.png';

//custom components
import Button from "../buttons/button/Button"
import PasswordInput from "./PasswordInput.tsx"
import { useLanguage } from "@/controllers/hooks/useLanguages";


interface PasswordProps {
setPasswordCheck: Dispatch<SetStateAction<boolean>>,
}

function PasswordUi({ setPasswordCheck }: PasswordProps) {

import Button from '../buttons/button/Button';
import PasswordInput from './PasswordInput.tsx';
import { useLanguage } from '@/controllers/hooks/useLanguages';

export default function PasswordUi({
setPasswordCheck,
}: {
setPasswordCheck: React.Dispatch<React.SetStateAction<boolean>>;
}) {
const navigate = useNavigate();
const { t } = useLanguage()
const { t } = useLanguage();

const PASSWORD_CODE = 7538
const PASSWORD_LENGTH = 4
const PASSWORD_CODE = 7538;
const PASSWORD_LENGTH = 4;
const MAX_TRIES = 3;

const [triesCounter, setTriesCounter] = useState(MAX_TRIES)
const [triesCounter, setTriesCounter] = useState(MAX_TRIES);
const [values, setValues] = useState(Array(PASSWORD_LENGTH).fill(''));
const [passwordState, setPasswordState] = useState({
img: passwordUiImgBlue,
text: t("Enter your 4-digit passcode to unlock group access"),
textStyle: styles.passwordUi__statusSection__passwordTextDefault
text: t('Enter your 4-digit passcode to unlock group access'),
textStyle: styles.passwordUi__statusSection__passwordTextDefault,
});

function handleSubmit() {

const enteredCode = Number(values.join(""));
const enteredCode = Number(values.join(''));

try {
if (enteredCode === PASSWORD_CODE) {
setPasswordState({
img: passwordUiImgGreen,
text: t(`Bravo! Your password is correct. Welcome aboard!`),
textStyle: styles.passwordUi__statusSection__passwordTextCorrect
textStyle: styles.passwordUi__statusSection__passwordTextCorrect,
});

setTimeout(() => {
setPasswordCheck(true);
}, 1000);

} else {
setPasswordState({
img: passwordUiImgRed,
text: t(`Something went wrong. Please try again!`),
textStyle: styles.passwordUi__statusSection__passwordTextIncorrect
textStyle: styles.passwordUi__statusSection__passwordTextIncorrect,
});

setTriesCounter(prev => {
setTriesCounter((prev) => {
const newTriesCounter = prev - 1;
if (newTriesCounter <= 0) {
navigate("/401");
navigate('/401');
}

return newTriesCounter;
});
}
}
catch (err) {
console.error(err)
} catch (err) {
console.error(err);
}
}


return (
<div className={styles.passwordUi}>
<div className={styles.passwordUi__imageSection}>
<img src={passwordState.img} />
</div>
<img src={passwordState.img} />

<div className={styles.passwordUi__statusSection}>
<p className={passwordState.textStyle}>{passwordState.text}
</p>
<p className={passwordState.textStyle}>{passwordState.text}</p>
</div>

<div className={styles.passwordUi__inputSection}>
<PasswordInput handleSubmit={handleSubmit} passwordLength={PASSWORD_LENGTH} values={values} setValues={setValues} />
<PasswordInput
handleSubmit={handleSubmit}
passwordLength={PASSWORD_LENGTH}
values={values}
setValues={setValues}
/>
</div>

<div className={styles.passwordUi__triesLeft}>
Expand All @@ -99,11 +94,9 @@ function PasswordUi({ setPasswordCheck }: PasswordProps) {
<Button
text={t('Submit')}
onClick={() => handleSubmit()}
className="btn btn--affirmation"
className='btn btn--affirmation'
/>
</div>
</div>
)
);
}

export default PasswordUi
130 changes: 64 additions & 66 deletions src/view/components/passwordUi/passwordUi.module.scss
Original file line number Diff line number Diff line change
@@ -1,79 +1,77 @@
@import url("https://fonts.googleapis.com/css2?family=Bellefair&display=swap");
@import url('https://fonts.googleapis.com/css2?family=Bellefair&display=swap');

.passwordUi {
width: 23rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 60ch;
height: 100svh;

&__imageSection {
img {
width: 15rem;
height: 16rem;
}
}
img {
width: 40%;
height: auto;
}

&__statusSection {
margin-top: 4rem;
line-height: 1.5rem;
width: 15rem;
&__statusSection {
line-height: 1.5rem;
width: 100%;
text-align: center;

p {
font-size: 1.1rem;
text-align: center;
font-weight: 400;
}
p {
font-size: 1.1rem;
font-weight: 400;
}

&__passwordTextDefault {
color: var(--h2Color);
}
&__passwordTextIncorrect {
color: var(--incorrectText);
}
&__passwordTextCorrect {
color: var(--correctText);
}
}
&__passwordTextDefault {
color: var(--h2Color);
}
&__passwordTextIncorrect {
color: var(--incorrectText);
}
&__passwordTextCorrect {
color: var(--correctText);
}
}

&__inputSection {
direction: ltr;
margin-top: 1rem;
display: flex;
gap: 0.7rem;
border-radius: 2px;
width: 15rem;
height: 4rem;
&__inputSection {
direction: ltr;
margin-top: 1rem;
display: flex;
gap: 0.7rem;
border-radius: 2px;
width: 15rem;
height: 4rem;

input {
font-family: "Bellefair";
align-items: center;
text-align: center;
font-size: 2.1rem;
font-weight: 400;
color: white;
background-color: var(--button-blue);
}
}
input {
font-family: 'Bellefair';
align-items: center;
text-align: center;
font-size: 2.1rem;
font-weight: 400;
color: white;
background-color: var(--button-blue);
}
}

&__triesLeft {
margin-top: 4rem;
line-height: 1.5rem;
width: 15rem;
&__triesLeft {
margin-top: 4rem;
line-height: 1.5rem;
width: 15rem;

p {
font-size: 1rem;
text-align: center;
font-weight: 400;
}
}
p {
font-size: 1rem;
text-align: center;
font-weight: 400;
}
}

&__buttonSection {
margin-top: 4rem;
&__buttonSection {
margin-top: 4rem;

button {
justify-content: center;
width: 12.5vw;
}
}
button {
justify-content: center;
width: 12.5vw;
}
}
}
Loading

0 comments on commit d615fda

Please sign in to comment.