From c88bf296a91cb043a4bab9d33ebe853ffa57ca0b Mon Sep 17 00:00:00 2001 From: maxnes3 Date: Wed, 30 Oct 2024 00:57:52 +0400 Subject: [PATCH] minimal front --- src/pages/home/home.page.tsx | 5 +- src/shared/api/index.ts | 0 .../components/button/button.component.tsx | 14 ++++- src/shared/components/button/index.ts | 2 +- .../components/button/styles.module.scss | 20 +++++++ .../selector/selector.component.tsx | 49 ++++++++++++--- .../components/selector/styles.module.scss | 15 +++++ src/shared/types/predict.ts | 18 ++++-- src/widgets/form/form.widget.tsx | 60 +++++++++++++++++-- src/widgets/form/styles.module.scss | 25 +++----- 10 files changed, 169 insertions(+), 39 deletions(-) delete mode 100644 src/shared/api/index.ts diff --git a/src/pages/home/home.page.tsx b/src/pages/home/home.page.tsx index 97b6234..73acbe0 100644 --- a/src/pages/home/home.page.tsx +++ b/src/pages/home/home.page.tsx @@ -1,9 +1,12 @@ +import Form from '@/widgets/form/form.widget'; import classes from './styles.module.scss'; const HomePage = () => { return (
-
+
+
+
); }; diff --git a/src/shared/api/index.ts b/src/shared/api/index.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/shared/components/button/button.component.tsx b/src/shared/components/button/button.component.tsx index 0652297..202f5b7 100644 --- a/src/shared/components/button/button.component.tsx +++ b/src/shared/components/button/button.component.tsx @@ -1,7 +1,17 @@ +import React, { FormEvent } from 'react'; import classes from './styles.module.scss'; -const Button = () => { - return <>; +type ButtonProps = { + label: string; + onClick: (e: FormEvent) => Promise; +}; + +const Button: React.FC = ({ label, onClick }) => { + return ( + + ); }; export default Button; diff --git a/src/shared/components/button/index.ts b/src/shared/components/button/index.ts index 77a63e2..e0e8b8e 100644 --- a/src/shared/components/button/index.ts +++ b/src/shared/components/button/index.ts @@ -1 +1 @@ -export { default as Button} from './button.component'; +export { default as Button } from './button.component'; diff --git a/src/shared/components/button/styles.module.scss b/src/shared/components/button/styles.module.scss index e69de29..c30be80 100644 --- a/src/shared/components/button/styles.module.scss +++ b/src/shared/components/button/styles.module.scss @@ -0,0 +1,20 @@ +.button { + background-color: rgba(255, 255, 255, 0.2); // прозрачный белый фон + border: 2px solid var(--primary-white); // белая обводка + border-radius: 8px; // закруглённые углы + color: var(--primary-white); // белый текст + padding: 10px 20px; // внутренних отступов + font-size: 16px; // размер шрифта + cursor: pointer; // курсор при наведении + transition: background-color 0.3s ease; // плавный переход фона + + &:hover { + background-color: rgba(255, 255, 255, 0.4); // изменение цвета фона при наведении + } + + &:focus { + outline: none; // убираем стандартный контур при фокусировке + box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5); // добавляем тень при фокусировке + } +} + \ No newline at end of file diff --git a/src/shared/components/selector/selector.component.tsx b/src/shared/components/selector/selector.component.tsx index 202ed73..5f9d46d 100644 --- a/src/shared/components/selector/selector.component.tsx +++ b/src/shared/components/selector/selector.component.tsx @@ -1,18 +1,51 @@ -import { FC } from 'react'; +import { FC, useState } from 'react'; import classes from './styles.module.scss'; type SelectorProps = { - handleSetValue: () => void; + field: string; + handleSetValue: (field: string, value: string) => void; list: string[]; }; -const Selector: FC = ({ handleSetValue, list }) => { +const Selector: FC = ({ field, handleSetValue, list }) => { + const [inputValue, setInputValue] = useState(''); + + const handleChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setInputValue(value); + handleSetValue(field, value); + }; + + const handleInputChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setInputValue(value); + handleSetValue(field, value); + }; + return ( -
- {list.map((item) => ( - - ))} -
+
+ + +
); }; diff --git a/src/shared/components/selector/styles.module.scss b/src/shared/components/selector/styles.module.scss index e69de29..4f33558 100644 --- a/src/shared/components/selector/styles.module.scss +++ b/src/shared/components/selector/styles.module.scss @@ -0,0 +1,15 @@ +.selector { + background-color: rgba(255, 255, 255, 0.2); // прозрачный белый + border: 2px solid var(--primary-white); // белая рамка + border-radius: 8px; // закруглённые углы + color: var(--primary-white); // белый текст + padding: 8px; + font-size: 16px; + cursor: pointer; + + option { + background-color: rgba(255, 255, 255, 0.2); // цвет фона для выпадающего списка + color: var(--primary-white); // белый текст в выпадающем списке + } + } + \ No newline at end of file diff --git a/src/shared/types/predict.ts b/src/shared/types/predict.ts index 8032c2f..d409a7a 100644 --- a/src/shared/types/predict.ts +++ b/src/shared/types/predict.ts @@ -1,7 +1,17 @@ export type PredictRequestType = { - -} + brand: string; + processor: string; + ram: string; + os: string; + ssd: string; + display: number; + gpu: string; + weight: number; + battery_size: number; + release_year: number; + display_type: string; +}; export type PredictResponseType = { - -} \ No newline at end of file + predicted_price: number; +}; diff --git a/src/widgets/form/form.widget.tsx b/src/widgets/form/form.widget.tsx index b2a6ebe..bfb2e4b 100644 --- a/src/widgets/form/form.widget.tsx +++ b/src/widgets/form/form.widget.tsx @@ -3,20 +3,68 @@ import { PredictRequestType, PredictResponseType, } from '@/shared/types/predict'; -import { useState } from 'react'; +import { FormEvent, useCallback, useState } from 'react'; import classes from './styles.module.scss'; +import { Button } from '@/shared/components/button'; +import { Selector } from '@/shared/components/selector'; const Form = () => { - const [request, setRequest] = useState({}); - const [response, setResponse] = useState({}); + const [request, setRequest] = useState({ + brand: '', + processor: '', + ram: '', + os: '', + ssd: '', + display: -1, + gpu: '', + weight: -1, + battery_size: -1, + release_year: -1, + display_type: '', + }); + const [response, setResponse] = useState({ + predicted_price: -1, + }); - const handleGetPredict = async () => { + const fields = Object.keys(request); + + const handleInputChange = useCallback( + (updatedRequest: PredictRequestType) => { + setRequest(updatedRequest); + }, + [], + ); + + const updateField = (field: string, value: string) => { + handleInputChange({ + ...request, + [field]: value, + }); + }; + + const handleGetPredict = async (event: FormEvent) => { + event.preventDefault(); const newResponse = await api.predictPrice(request); + setResponse(newResponse); }; return ( - -
+ +
+ {fields.map((field) => ( + updateField(field, value)} + list={[]} + field={field} + /> + ))} +
+