[front]: api fetch

This commit is contained in:
it-is-not-alright 2024-10-21 02:42:57 +04:00
parent fd5c724342
commit ef20e8e4e3
54 changed files with 144 additions and 14 deletions

View File

@ -0,0 +1,2 @@
// export const BASE_URL = 'http://localhost:8000/api';
export const BASE_URL = 'http://192.168.1.110:8000/api';

View File

@ -0,0 +1 @@
export { downloadImage, getWindmillData } from './service';

View File

@ -0,0 +1,26 @@
import { WindmillFormStore } from '@components/ux/windmill-form';
import { BASE_URL } from './constants';
import { GetWindmillDataRes } from './types';
import { getWindmillDataParams } from './utils';
export const getWindmillData = async (store: Partial<WindmillFormStore>) => {
const params = getWindmillDataParams(store);
const url = `${BASE_URL}/floris/get_windmill_data?${params}`;
const init: RequestInit = {
method: 'GET',
};
const res: Response = await fetch(url, init);
const data: GetWindmillDataRes = await res.json();
return data;
};
export const downloadImage = async (imageName: string) => {
const url = `${BASE_URL}/floris/download_image/${imageName}`;
const init: RequestInit = {
method: 'GET',
};
const res: Response = await fetch(url, init);
const data = await res.blob();
return data;
};

View File

@ -0,0 +1,4 @@
export type GetWindmillDataRes = {
file_name: string;
data: number[];
};

View File

@ -0,0 +1,9 @@
import { WindmillFormStore } from '@components/ux/windmill-form';
export const getWindmillDataParams = (store: Partial<WindmillFormStore>) => {
const layoutX = store.windmills?.map((row) => `layout_x=${row.x}`).join('&');
const layoutY = store.windmills?.map((row) => `layout_y=${row.y}`).join('&');
const dateStart = `date_start=${store.dateFrom?.substring(0, 10)}`;
const dateEnd = `date_end=${store.dateTo?.substring(0, 10)}`;
return `${layoutX}&${layoutY}&${dateStart}&${dateEnd}`;
};

1
front/src/api/index.tsx Normal file
View File

@ -0,0 +1 @@
export * from './floris';

View File

@ -1,13 +1,31 @@
import { Heading } from '@components/ui';
import { WindmillForm } from '@components/ux';
import React from 'react';
import { WindmillFormResponse } from '@components/ux/windmill-form';
import React, { useState } from 'react';
import styles from './styles.module.scss';
export function HomePage() {
const [formResponse, setFormResponse] = useState<WindmillFormResponse>({
power: [],
image: '',
});
const handleFormResponse = (response: WindmillFormResponse) => {
setFormResponse(response);
};
return (
<div className={styles.home}>
<div className={styles.about}>
<WindmillForm className={styles.form} />
<div className={styles.page}>
<div className={styles.wrapperForm}>
<WindmillForm onResponse={handleFormResponse} />
</div>
<div className={styles.result}>
<Heading tag="h3">Result</Heading>
<div className={styles.power}>{formResponse.power.join(' ')}</div>
<div className={styles.image}>
{formResponse.image && <img src={formResponse.image} alt="Image" />}
</div>
</div>
</div>
);

View File

@ -1,11 +1,41 @@
.about {
.page {
display: grid;
padding: 20px;
gap: 20px;
grid-template:
'. form .' auto
/ auto minmax(0, 380px) auto;
'. form result .' auto
/ auto minmax(0, 380px) minmax(0, 700px) auto;
}
.form {
.wrapperForm {
grid-area: form;
}
.result {
display: grid;
padding: 20px;
border-radius: 10px;
background-color: var(--clr-layer-200);
box-shadow: 0px 1px 2px var(--clr-shadow-100);
gap: 20px;
grid-area: result;
grid-template-columns: 1fr;
}
.image {
width: 100%;
img {
max-width: 100%;
border-radius: 10px;
}
}
@media (width <= 1000px) {
.page {
grid-template:
'form' auto
'result' auto
/ 1fr;
}
}

View File

@ -2,20 +2,28 @@ import { Button, DateInput, Heading } from '@components/ui';
import { Controller, useForm } from '@utils/form';
import clsx from 'clsx';
import React from 'react';
import { downloadImage, getWindmillData } from 'src/api';
import { WindmillTable } from '../windmill-table';
import { initialValues } from './constants';
import styles from './styles.module.scss';
import { WindmillFormProps, WindmillFormStore } from './types';
export function WindmillForm({ className, ...props }: WindmillFormProps) {
const { control, reset } = useForm<WindmillFormStore>({
export function WindmillForm({
onResponse,
className,
...props
}: WindmillFormProps) {
const { control, reset, getValues } = useForm<WindmillFormStore>({
initialValues,
});
const classNames = clsx(className, styles.form);
const handleSubmit = (event: React.FormEvent) => {
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
const res = await getWindmillData(getValues());
const image = await downloadImage(res.file_name);
onResponse({ power: res.data, image: URL.createObjectURL(image) });
};
const handleResetButtonClick = () => {

View File

@ -1,2 +1,6 @@
export { WindmillForm } from './component';
export { type WindmillConfig } from './types';
export {
type WindmillConfig,
type WindmillFormResponse,
type WindmillFormStore,
} from './types';

View File

@ -10,4 +10,11 @@ export type WindmillFormStore = {
windmills: WindmillConfig[];
};
export type WindmillFormProps = {} & React.ComponentProps<'form'>;
export type WindmillFormResponse = {
power: number[];
image: string;
};
export type WindmillFormProps = {
onResponse: (response: WindmillFormResponse) => void;
} & React.ComponentProps<'form'>;

View File

@ -31,7 +31,7 @@ export function WindmillTable({ value, onChange }: WindmillTableProps) {
};
return (
<div>
<div className={styles.table}>
<header className={styles.header}>
<Span className={styles.span} />
<Span className={styles.span}>x</Span>

View File

@ -1,3 +1,9 @@
.table {
border-radius: 10px;
background-color: var(--clr-layer-200);
box-shadow: 0px 2px 2px var(--clr-shadow-100);
}
.header {
display: grid;
grid-template-columns: 46px 1fr 1fr 1fr;

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
server/src/.cache.sqlite Normal file

Binary file not shown.

View File

@ -9,10 +9,24 @@ from fastapi.staticfiles import StaticFiles
from routers.floris_router import router as floris_router
from routers.floris_template_router import router as floris_template_router
from routers.weather_router import router as weather_router
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost:5000",
"*"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.mount("/static", StaticFiles(directory=Path("../static")), name="static")
app.mount("/public", StaticFiles(directory=Path("../public")), name="public")