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

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

#7 Обернул главный компонент Provider-ом, прописал валидацию полей чтобы не отправлять на сервер пустые значения, прописал логику показа ошибки снизу, и показа loader, при отправке данных. Добавил логику отправки сообщений через store. В файле store.ts добавил requestReducer
parent 23c5d165
"use client";
import { Box, Button, Container, Grid2, Typography } from "@mui/material";
import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
import { ChangeEvent, FormEvent, useState } from "react";
import InputField from "./components/InputField";
'use client';
import { Box, Button, Container, Grid2, Typography } from '@mui/material';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import { ChangeEvent, useEffect, useState } from 'react';
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 {
decoded: string;
......@@ -11,16 +16,53 @@ interface IFormData {
}
export default function Home() {
const dispatch = useAppDispatch();
const { loading, result, error } = useAppSelector((state) => state.request);
const [formData, setFormData] = useState<IFormData>({
encoded: "",
decoded: "",
password: "",
encoded: '',
decoded: '',
password: '',
});
const submitFormHandler = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const onCypherHandler = (): void => {
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 { name, value } = e.target;
setFormData((prevData) => ({
......@@ -30,100 +72,115 @@ export default function Home() {
};
return (
<div className="App">
<Container sx={{ marginTop: 2 }} maxWidth="lg">
<Typography
variant="h3"
sx={{
fontSize: {
xs: "24px",
sm: "36px",
},
}}
>
Cypher Coder/Decoder
</Typography>
<Box
sx={{
maxWidth: {
xs: "90%",
sm: "80%",
lg: "70%",
},
}}
component="form"
autoComplete="off"
onSubmit={submitFormHandler}
paddingY={2}
>
<Grid2 container direction="column" spacing={2}>
<InputField
name="Decoded"
value={formData.decoded}
onChange={onInputChangeHandler}
/>
<Grid2
container
alignItems="center"
sx={{
flexDirection: {
xs: "column",
md: "row",
},
}}
>
<Grid2 size={7}>
<InputField
name="Password"
value={formData.password}
onChange={onInputChangeHandler}
/>
</Grid2>
<Grid2 container justifyContent={{}}>
<Grid2>
<Button
size="small"
variant="contained"
startIcon={<ArrowDownwardIcon />}
>
<Typography
sx={{
display: { xs: "none", md: "inline" },
}}
>
Encode
</Typography>
</Button>
<Provider store={store}>
<div className="App">
<Container sx={{ marginTop: 2 }} maxWidth="lg">
<Typography
variant="h3"
sx={{
fontSize: {
xs: '24px',
sm: '36px',
},
}}
>
Cypher Coder/Decoder
</Typography>
<Box
sx={{
maxWidth: {
xs: '90%',
sm: '80%',
lg: '70%',
},
}}
component="form"
autoComplete="off"
padding={2}
>
<Grid2 container direction="column" spacing={2}>
<InputField
name="Decoded"
value={formData.decoded}
onChange={onInputChangeHandler}
/>
<Grid2
container
alignItems="center"
sx={{
flexDirection: {
xs: 'column',
md: 'row',
},
}}
>
<Grid2 size={7}>
<InputField
name="Password"
value={formData.password}
onChange={onInputChangeHandler}
/>
</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>
<Button
size="small"
variant="contained"
startIcon={
<ArrowDownwardIcon sx={{ transform: "rotate(180deg)" }} />
}
>
<Typography
sx={{
display: { xs: "none", md: "inline" },
}}
<Grid2>
<Button
size="small"
variant="contained"
startIcon={
<ArrowDownwardIcon
sx={{ transform: 'rotate(180deg)' }}
/>
}
onClick={onCypherHandler}
>
Decode
</Typography>
</Button>
<Typography
sx={{
display: { xs: 'none', md: 'inline' },
}}
>
Decode
</Typography>
</Button>
</Grid2>
</Grid2>
</Grid2>
<InputField
name="Encoded"
value={formData.encoded}
onChange={onInputChangeHandler}
/>
</Grid2>
</Box>
<InputField
name="Encoded"
value={formData.encoded}
onChange={onInputChangeHandler}
/>
</Grid2>
</Box>
</Container>
</div>
{loading && (
<div className="loader">
<div className="lds-ripple">
<div></div>
<div></div>
</div>
</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({
reducer: {
request: requestReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
\ No newline at end of file
export type AppDispatch = typeof store.dispatch;
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