Commit 18c39174 authored by bekzat kapan's avatar bekzat kapan

#7 Обернул главный компонент Provider-ом, прописал валидацию полей чтобы не…

#7 Обернул главный компонент Provider-ом, прописал валидацию полей чтобы не отправлять на сервер пустые значения, прописал логику показа ошибки снизу, и показа loader, при отправке данных. Добавил логику отправки сообщений через store. В файле store.ts добавил requestReducer
parent 23c5d165
"use client"; 'use client';
import { Box, Button, Container, Grid2, Typography } from "@mui/material"; import { Box, Button, Container, Grid2, Typography } from '@mui/material';
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward"; import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import { ChangeEvent, FormEvent, useState } from "react"; import { ChangeEvent, useEffect, useState } from 'react';
import InputField from "./components/InputField"; import InputField from './components/InputField';
import '@/animations/Loader.css';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { Provider } from 'react-redux';
import { store } from '@/store/store';
import { encodeMessage, decodeMessage } from '@/features/requestSlice';
interface IFormData { interface IFormData {
decoded: string; decoded: string;
...@@ -11,16 +16,53 @@ interface IFormData { ...@@ -11,16 +16,53 @@ interface IFormData {
} }
export default function Home() { export default function Home() {
const dispatch = useAppDispatch();
const { loading, result, error } = useAppSelector((state) => state.request);
const [formData, setFormData] = useState<IFormData>({ const [formData, setFormData] = useState<IFormData>({
encoded: "", encoded: '',
decoded: "", decoded: '',
password: "", password: '',
}); });
const submitFormHandler = (e: FormEvent<HTMLFormElement>) => { const onCypherHandler = (): void => {
e.preventDefault(); if (!formData.password.trim()) {
alert('Please, type in password!');
return;
}
if (!formData.encoded.trim()) {
alert('Please fill in the "Decoded" field!');
return;
}
dispatch(
encodeMessage({ password: formData.password, message: formData.decoded })
);
};
const onDecypherHandler = (): void => {
if (!formData.password.trim()) {
alert('Please, type in password!');
return;
}
if (!formData.decoded.trim()) {
alert('Please fill in the "Decoded" field!');
return;
}
dispatch(
decodeMessage({ password: formData.password, message: formData.decoded })
);
}; };
useEffect(() => {
if (result) {
if (formData.decoded) {
setFormData((prev) => ({ ...prev, encoded: result }));
} else {
setFormData((prev) => ({ ...prev, decoded: result }));
}
}
}, [result]);
const onInputChangeHandler = (e: ChangeEvent<HTMLInputElement>) => { const onInputChangeHandler = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target; const { name, value } = e.target;
setFormData((prevData) => ({ setFormData((prevData) => ({
...@@ -30,100 +72,115 @@ export default function Home() { ...@@ -30,100 +72,115 @@ export default function Home() {
}; };
return ( return (
<div className="App"> <Provider store={store}>
<Container sx={{ marginTop: 2 }} maxWidth="lg"> <div className="App">
<Typography <Container sx={{ marginTop: 2 }} maxWidth="lg">
variant="h3" <Typography
sx={{ variant="h3"
fontSize: { sx={{
xs: "24px", fontSize: {
sm: "36px", xs: '24px',
}, sm: '36px',
}} },
> }}
Cypher Coder/Decoder >
</Typography> Cypher Coder/Decoder
<Box </Typography>
sx={{ <Box
maxWidth: { sx={{
xs: "90%", maxWidth: {
sm: "80%", xs: '90%',
lg: "70%", sm: '80%',
}, lg: '70%',
}} },
component="form" }}
autoComplete="off" component="form"
onSubmit={submitFormHandler} autoComplete="off"
paddingY={2} padding={2}
> >
<Grid2 container direction="column" spacing={2}> <Grid2 container direction="column" spacing={2}>
<InputField <InputField
name="Decoded" name="Decoded"
value={formData.decoded} value={formData.decoded}
onChange={onInputChangeHandler} onChange={onInputChangeHandler}
/> />
<Grid2 <Grid2
container container
alignItems="center" alignItems="center"
sx={{ sx={{
flexDirection: { flexDirection: {
xs: "column", xs: 'column',
md: "row", md: 'row',
}, },
}} }}
> >
<Grid2 size={7}> <Grid2 size={7}>
<InputField <InputField
name="Password" name="Password"
value={formData.password} value={formData.password}
onChange={onInputChangeHandler} onChange={onInputChangeHandler}
/> />
</Grid2>
<Grid2 container justifyContent={{}}>
<Grid2>
<Button
size="small"
variant="contained"
startIcon={<ArrowDownwardIcon />}
>
<Typography
sx={{
display: { xs: "none", md: "inline" },
}}
>
Encode
</Typography>
</Button>
</Grid2> </Grid2>
<Grid2 container>
<Grid2>
<Button
size="small"
variant="contained"
startIcon={<ArrowDownwardIcon />}
onClick={onDecypherHandler}
>
<Typography
sx={{
display: { xs: 'none', md: 'inline' },
}}
>
Encode
</Typography>
</Button>
</Grid2>
<Grid2> <Grid2>
<Button <Button
size="small" size="small"
variant="contained" variant="contained"
startIcon={ startIcon={
<ArrowDownwardIcon sx={{ transform: "rotate(180deg)" }} /> <ArrowDownwardIcon
} sx={{ transform: 'rotate(180deg)' }}
> />
<Typography }
sx={{ onClick={onCypherHandler}
display: { xs: "none", md: "inline" },
}}
> >
Decode <Typography
</Typography> sx={{
</Button> display: { xs: 'none', md: 'inline' },
}}
>
Decode
</Typography>
</Button>
</Grid2>
</Grid2> </Grid2>
</Grid2> </Grid2>
<InputField
name="Encoded"
value={formData.encoded}
onChange={onInputChangeHandler}
/>
</Grid2> </Grid2>
</Box>
<InputField {loading && (
name="Encoded" <div className="loader">
value={formData.encoded} <div className="lds-ripple">
onChange={onInputChangeHandler} <div></div>
/> <div></div>
</Grid2> </div>
</Box> </div>
</Container> )}
</div> {error && <Typography color="error">{error}</Typography>}
</Container>
</div>
</Provider>
); );
} }
import { configureStore } from "@reduxjs/toolkit"; import { configureStore } from '@reduxjs/toolkit';
import requestReducer from '@/features/requestSlice';
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
request: requestReducer,
}, },
}); });
export type RootState = ReturnType<typeof store.getState>; export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch; export type AppDispatch = typeof store.dispatch;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment