complete laptop
This commit is contained in:
parent
244aed205b
commit
63a5ecd0e4
5
src/declaration.d.ts
vendored
5
src/declaration.d.ts
vendored
@ -6,3 +6,8 @@ declare module '*.svg' {
|
||||
>;
|
||||
export default ReactComponent;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const value: string;
|
||||
export default value;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import Form from '@/widgets/form/form.widget';
|
||||
import classes from './styles.module.scss';
|
||||
import Laptop from '@shared/assets/icons/laptop.svg';
|
||||
|
||||
@ -6,9 +5,7 @@ const HomePage = () => {
|
||||
return (
|
||||
<div className={classes.home}>
|
||||
<Laptop className={classes.laptop} />
|
||||
<div className={classes.container}>
|
||||
<Form />
|
||||
</div>
|
||||
<div className={classes.container}></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,8 +1,14 @@
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import Layout from '@app/layout/layout';
|
||||
import HomePage from '@pages/home/home.page';
|
||||
import { LaptopPage } from '@pages/laptop';
|
||||
// import { TVPage } from '@pages/tv/tv.page';
|
||||
|
||||
const routes = [{ path: '/', element: <HomePage /> }];
|
||||
const routes = [
|
||||
{ path: '/', element: <HomePage /> },
|
||||
{ path: '/laptop', element: <LaptopPage /> },
|
||||
// { path: '/tv', element: <TVPage /> },
|
||||
];
|
||||
|
||||
const Index = () => {
|
||||
return (
|
||||
|
1
src/pages/laptop/index.ts
Normal file
1
src/pages/laptop/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as LaptopPage } from './laptop.page';
|
84
src/pages/laptop/laptop.page.tsx
Normal file
84
src/pages/laptop/laptop.page.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import Form from '@/widgets/form/form.widget';
|
||||
import classes from './styles.module.scss';
|
||||
import Laptop from '@shared/assets/images/laptop.png';
|
||||
import { FormEvent, useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
LaptopCreatePredictType,
|
||||
LaptopGetDataPredictType,
|
||||
PredictResponseType,
|
||||
} from '@/shared/types';
|
||||
import { apiLaptop } from '@/shared/api';
|
||||
|
||||
const LaptopPredictPage = () => {
|
||||
const [requestSelectorsData, setRequestSelectorsData] = useState<
|
||||
LaptopGetDataPredictType | undefined
|
||||
>();
|
||||
|
||||
const [request, setRequest] = useState<LaptopCreatePredictType>({
|
||||
processor: '',
|
||||
ram: 0,
|
||||
os: '',
|
||||
ssd: 0,
|
||||
display_size: 0,
|
||||
resolution: '',
|
||||
matrix_type: '',
|
||||
gpu: '',
|
||||
});
|
||||
|
||||
const [response, setResponse] = useState<PredictResponseType>({
|
||||
predicted_price: undefined,
|
||||
});
|
||||
|
||||
const handleGetPredict = async (event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
console.log(request);
|
||||
const newResponse = await apiLaptop.predictPrice(request);
|
||||
setResponse(newResponse);
|
||||
};
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
(updatedRequest: LaptopCreatePredictType) => {
|
||||
setRequest(updatedRequest);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const updateField = (
|
||||
field: keyof LaptopGetDataPredictType,
|
||||
value: string | number,
|
||||
) => {
|
||||
handleInputChange({
|
||||
...request,
|
||||
[field]: value,
|
||||
});
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const responseSelectorData = await apiLaptop.getDataForRequest();
|
||||
if (!responseSelectorData) {
|
||||
return;
|
||||
}
|
||||
setRequestSelectorsData(responseSelectorData);
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={classes.laptop}>
|
||||
<img src={Laptop} className={classes.icon} />
|
||||
<div className={classes.container}>
|
||||
<Form
|
||||
selectorsData={requestSelectorsData}
|
||||
updateField={updateField}
|
||||
handleGetPredict={handleGetPredict}
|
||||
response={response}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LaptopPredictPage;
|
36
src/pages/laptop/styles.module.scss
Normal file
36
src/pages/laptop/styles.module.scss
Normal file
@ -0,0 +1,36 @@
|
||||
@use '../../shared/assets/styles/adaptive' as adaptive;
|
||||
|
||||
$adaptive: (
|
||||
desktop: (
|
||||
flex-direction: row,
|
||||
size: 250px,
|
||||
container-width: 768px
|
||||
),
|
||||
table: (
|
||||
flex-direction: row,
|
||||
size: 250px,
|
||||
container-width: 425px
|
||||
),
|
||||
mobile: (
|
||||
flex-direction: column,
|
||||
size: auto,
|
||||
container-width: auto
|
||||
),
|
||||
);
|
||||
|
||||
.laptop {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
@include adaptive.set-adaptive($adaptive, flex-direction, flex-direction);
|
||||
|
||||
.icon {
|
||||
@include adaptive.set-adaptive($adaptive, width, size);
|
||||
@include adaptive.set-adaptive($adaptive, height, size);
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 15px;
|
||||
@include adaptive.set-adaptive($adaptive, width, container-width);
|
||||
}
|
||||
}
|
0
src/pages/tv/index.ts
Normal file
0
src/pages/tv/index.ts
Normal file
36
src/pages/tv/styles.module.scss
Normal file
36
src/pages/tv/styles.module.scss
Normal file
@ -0,0 +1,36 @@
|
||||
@use '../../shared/assets/styles/adaptive' as adaptive;
|
||||
|
||||
$adaptive: (
|
||||
desktop: (
|
||||
flex-direction: row,
|
||||
size: 250px,
|
||||
container-width: 768px
|
||||
),
|
||||
table: (
|
||||
flex-direction: row,
|
||||
size: 250px,
|
||||
container-width: 425px
|
||||
),
|
||||
mobile: (
|
||||
flex-direction: column,
|
||||
size: auto,
|
||||
container-width: auto
|
||||
),
|
||||
);
|
||||
|
||||
.tv {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
@include adaptive.set-adaptive($adaptive, flex-direction, flex-direction);
|
||||
|
||||
.icon {
|
||||
@include adaptive.set-adaptive($adaptive, width, size);
|
||||
@include adaptive.set-adaptive($adaptive, height, size);
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 15px;
|
||||
@include adaptive.set-adaptive($adaptive, width, container-width);
|
||||
}
|
||||
}
|
73
src/pages/tv/tv.page.tsx
Normal file
73
src/pages/tv/tv.page.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
// import Form from '@/widgets/form/form.widget';
|
||||
// import classes from './styles.module.scss';
|
||||
// import TV from '@shared/assets/images/tv.png';
|
||||
// import { FormEvent, useCallback, useEffect, useState } from 'react';
|
||||
// import {
|
||||
// TVCreatePredictType,
|
||||
// TVGetDataPredictType,
|
||||
// PredictResponseType,
|
||||
// } from '@/shared/types';
|
||||
// import { apiTV } from '@/shared/api';
|
||||
|
||||
// const TVPredictPage = () => {
|
||||
// const [requestSelectorsData, setRequestSelectorsData] = useState<
|
||||
// TVGetDataPredictType | undefined
|
||||
// >();
|
||||
|
||||
// const [request, setRequest] = useState<TVCreatePredictType>({
|
||||
// display
|
||||
// });
|
||||
|
||||
// const [response, setResponse] = useState<PredictResponseType>({
|
||||
// predicted_price: undefined,
|
||||
// });
|
||||
|
||||
// const handleGetPredict = async (event: FormEvent) => {
|
||||
// event.preventDefault();
|
||||
// console.log(request);
|
||||
// const newResponse = await apiTV.predictPrice(request);
|
||||
// setResponse(newResponse);
|
||||
// };
|
||||
|
||||
// const handleInputChange = useCallback(
|
||||
// (updatedRequest: TVCreatePredictType) => {
|
||||
// setRequest(updatedRequest);
|
||||
// },
|
||||
// [],
|
||||
// );
|
||||
|
||||
// const updateField = (field: string, value: string) => {
|
||||
// handleInputChange({
|
||||
// ...request,
|
||||
// [field]: value,
|
||||
// });
|
||||
// };
|
||||
|
||||
// useEffect(() => {
|
||||
// const fetchData = async () => {
|
||||
// const responseSelectorData = await apiTV.getDataForRequest();
|
||||
// if (!responseSelectorData) {
|
||||
// return;
|
||||
// }
|
||||
// setRequestSelectorsData(responseSelectorData);
|
||||
// };
|
||||
|
||||
// fetchData();
|
||||
// }, []);
|
||||
|
||||
// return (
|
||||
// <div className={classes.tv}>
|
||||
// <img src={TV} className={classes.icon} />
|
||||
// <div className={classes.container}>
|
||||
// <Form
|
||||
// selectorsData={requestSelectorsData}
|
||||
// updateField={updateField}
|
||||
// handleGetPredict={handleGetPredict}
|
||||
// response={response}
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default TVPredictPage;
|
40
src/shared/api/api.laptop.ts
Normal file
40
src/shared/api/api.laptop.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
LaptopGetDataPredictType,
|
||||
LaptopCreatePredictType,
|
||||
PredictResponseType,
|
||||
} from '../types';
|
||||
|
||||
class ApiLaptop {
|
||||
readonly baseURL = import.meta.env.VITE_SERVER_URL;
|
||||
|
||||
getDataForRequest = async (): Promise<LaptopGetDataPredictType> => {
|
||||
try {
|
||||
const response = await axios.get<LaptopGetDataPredictType>(
|
||||
`${this.baseURL}/get_unique_data_laptop`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error predicting price:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
predictPrice = async (
|
||||
data: LaptopCreatePredictType,
|
||||
): Promise<PredictResponseType> => {
|
||||
try {
|
||||
const response = await axios.post<PredictResponseType>(
|
||||
`${this.baseURL}/predict_price/laptop/`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error predicting price:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const apiLaptop = new ApiLaptop();
|
||||
export default apiLaptop;
|
@ -1,24 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { PredictRequestType, PredictResponseType } from '../types/predict';
|
||||
|
||||
class Api {
|
||||
readonly baseURL = import.meta.env.VITE_SERVER_URL;
|
||||
|
||||
predictPrice = async (
|
||||
data: PredictRequestType,
|
||||
): Promise<PredictResponseType> => {
|
||||
try {
|
||||
const response = await axios.post<PredictResponseType>(
|
||||
`${this.baseURL}/predict_price`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error predicting price:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const api = new Api();
|
||||
export default api;
|
40
src/shared/api/api.tv.ts
Normal file
40
src/shared/api/api.tv.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
TVCreatePredictType,
|
||||
TVGetDataPredictType,
|
||||
PredictResponseType,
|
||||
} from '../types';
|
||||
|
||||
class ApiTV {
|
||||
readonly baseURL = import.meta.env.VITE_SERVER_URL;
|
||||
|
||||
getDataForRequest = async (): Promise<TVGetDataPredictType> => {
|
||||
try {
|
||||
const response = await axios.get<TVGetDataPredictType>(
|
||||
`${this.baseURL}/get_unique_data_tv`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error predicting price:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
predictPrice = async (
|
||||
data: TVCreatePredictType,
|
||||
): Promise<PredictResponseType> => {
|
||||
try {
|
||||
const response = await axios.post<PredictResponseType>(
|
||||
`${this.baseURL}/predict_price/tv/`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error predicting price:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const apiTV = new ApiTV();
|
||||
export default apiTV;
|
2
src/shared/api/index.ts
Normal file
2
src/shared/api/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { default as apiLaptop } from './api.laptop';
|
||||
export { default as apiTV } from './api.tv';
|
BIN
src/shared/assets/images/laptop.png
Normal file
BIN
src/shared/assets/images/laptop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
src/shared/assets/images/tv.png
Normal file
BIN
src/shared/assets/images/tv.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
1
src/shared/types/index.ts
Normal file
1
src/shared/types/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './predict';
|
@ -1,15 +1,43 @@
|
||||
export type PredictRequestType = {
|
||||
brand: string;
|
||||
export type LaptopCreatePredictType = {
|
||||
processor: string;
|
||||
ram: number;
|
||||
os: string;
|
||||
ssd: number;
|
||||
display: number;
|
||||
display_size: number;
|
||||
resolution: string;
|
||||
matrix_type: string;
|
||||
gpu: string;
|
||||
weight: number;
|
||||
battery_size: number;
|
||||
release_year: number;
|
||||
display_type: string;
|
||||
};
|
||||
|
||||
export type LaptopGetDataPredictType = {
|
||||
processor: string[];
|
||||
ram: number[];
|
||||
os: string[];
|
||||
ssd: number[];
|
||||
display_size: number[];
|
||||
resolution: string[];
|
||||
matrix_type: string[];
|
||||
gpu: string[];
|
||||
};
|
||||
|
||||
export type TVCreatePredictType = {
|
||||
display: string;
|
||||
tuners: string;
|
||||
features: string;
|
||||
os: string;
|
||||
power_of_volume: string;
|
||||
screen_size: number;
|
||||
color: string;
|
||||
};
|
||||
|
||||
export type TVGetDataPredictType = {
|
||||
display: string[];
|
||||
tuners: string[];
|
||||
features: string[];
|
||||
os: string[];
|
||||
power_of_volume: string[];
|
||||
screen_size: number[];
|
||||
color: string[];
|
||||
};
|
||||
|
||||
export type PredictResponseType = {
|
||||
|
@ -1,71 +1,42 @@
|
||||
import api from '@/shared/api/api';
|
||||
import {
|
||||
PredictRequestType,
|
||||
PredictResponseType,
|
||||
} from '@/shared/types/predict';
|
||||
import { FormEvent, useCallback, useState } from 'react';
|
||||
import { PredictResponseType } from '@/shared/types/predict';
|
||||
import { FormEvent } from 'react';
|
||||
import classes from './styles.module.scss';
|
||||
import { Button } from '@/shared/components/button';
|
||||
import { Selector } from '@/shared/components/selector';
|
||||
import { mockUpOptions } from '@/shared/constants';
|
||||
import { Expander } from '@/shared/components/expander';
|
||||
|
||||
const Form = () => {
|
||||
const [request, setRequest] = useState<PredictRequestType>({
|
||||
brand: 'Apple',
|
||||
processor: 'Core i5 10th Gen',
|
||||
ram: 16,
|
||||
os: 'Windows 11',
|
||||
ssd: 1024,
|
||||
display: 15.3,
|
||||
gpu: 'NVIDIA GeForce RTX 3060',
|
||||
weight: 2.0,
|
||||
battery_size: 90,
|
||||
release_year: 2023,
|
||||
display_type: '4K',
|
||||
});
|
||||
const [response, setResponse] = useState<PredictResponseType>({
|
||||
predicted_price: undefined,
|
||||
});
|
||||
type FormType<T> = {
|
||||
selectorsData: T | undefined;
|
||||
updateField: (field: keyof T, value: string | number) => void;
|
||||
handleGetPredict: (e: FormEvent) => Promise<void>;
|
||||
response: PredictResponseType;
|
||||
};
|
||||
|
||||
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();
|
||||
console.log(request);
|
||||
const newResponse = await api.predictPrice(request);
|
||||
setResponse(newResponse);
|
||||
};
|
||||
const Form = <T extends Record<string, string[] | number[]>>({
|
||||
selectorsData,
|
||||
updateField,
|
||||
handleGetPredict,
|
||||
response,
|
||||
}: FormType<T>) => {
|
||||
const fields = selectorsData
|
||||
? (Object.keys(selectorsData) as Array<keyof T>)
|
||||
: [];
|
||||
|
||||
return (
|
||||
<form className={classes.form}>
|
||||
<div className={classes.selectorList}>
|
||||
{fields.map((field) => (
|
||||
<Expander key={field} title={field}>
|
||||
<Expander key={field as string} title={field as string}>
|
||||
<Selector
|
||||
handleSetValue={updateField}
|
||||
list={mockUpOptions[field]}
|
||||
field={field}
|
||||
list={selectorsData ? selectorsData[field] : []}
|
||||
field={field as string}
|
||||
/>
|
||||
</Expander>
|
||||
))}
|
||||
</div>
|
||||
<Button onClick={(e: FormEvent) => handleGetPredict(e)}>Submit</Button>
|
||||
{response.predicted_price && (
|
||||
{response.predicted_price !== undefined && (
|
||||
<span style={{ color: 'white' }}>
|
||||
Ответ: {response.predicted_price}
|
||||
</span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user