Skip to content

Commit

Permalink
updated UI part to load cities and select filter city
Browse files Browse the repository at this point in the history
  • Loading branch information
Yariki committed Mar 24, 2024
1 parent 3d8b39e commit 085086b
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 19 deletions.
5 changes: 3 additions & 2 deletions dimria-fe/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useEffect} from 'react';
import Loading from './Components/Loading';
import {useDispatch, useSelector} from "react-redux";
import {fetchAdvertsStart} from "./redux/adverts/advertSlices";
import {fetchAdvertsStart, fetchCitiesStart} from "./redux/adverts/advertSlices";
import {selectAdverts, selectAdvertLoading} from "./redux/adverts/selectors";

import {AdvertsPage} from "./Components/AdvertsPage";
Expand All @@ -13,7 +13,8 @@ function App() {
const loading = useSelector(selectAdvertLoading);

useEffect(() => {
dispatch(fetchAdvertsStart());
dispatch(fetchAdvertsStart(-1));
dispatch(fetchCitiesStart());
}, []);

return (
Expand Down
47 changes: 42 additions & 5 deletions dimria-fe/src/Components/AdvertList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
import {selectAdverts} from "../../redux/adverts/selectors";
import {useSelector} from "react-redux";
import {AnalyticalTable, Grid, Link} from "@ui5/webcomponents-react";
import React from "react";
import {selectAdverts, selectCities, selectCitiesLoading} from "../../redux/adverts/selectors";
import {useDispatch, useSelector} from "react-redux";
import {AnalyticalTable, Grid, Link, Select, Option} from "@ui5/webcomponents-react";
import React, { useEffect } from "react";
import {Icon} from "@ui5/webcomponents-react";
import "@ui5/webcomponents-icons/dist/AllIcons.js"
import {AdvertDto} from "../../models/AdvertDto";
import { fetchAdvertsStart } from "../../redux/adverts/advertSlices";


export interface AdvertListProps {
onSelectedAdvert: (advert: AdvertDto) => void;
onLinkClick: (advertId: string) => void;
}


export const AdvertList = (props: AdvertListProps) => {

const dispatch = useDispatch();
const adverts = useSelector(selectAdverts);
const cities = useSelector(selectCities);
const citiesLoading = useSelector(selectCitiesLoading);

const [selectedCity, setSelectedCity] = React.useState<number | null>(null);

const options = [{city_id: -1, city_name: 'All'}, ...cities || []];

const {onLinkClick} = props;

useEffect(() => {

if(selectedCity === null || isNaN(selectedCity)){
return;
}

dispatch(fetchAdvertsStart(selectedCity));
},[selectedCity])

const columns = [
{
Header: 'Advert ID',
Expand Down Expand Up @@ -80,6 +98,21 @@ export const AdvertList = (props: AdvertListProps) => {

return (
<>
{
!citiesLoading &&
(<div>
<label>City</label>
<Select onChange={(e) =>
{
setSelectedCity(parseInt(e.detail.selectedOption.getAttribute('data-id') ?? '-1'));
}
}>
{options.map((city) => {
return <Option key={city.city_id} data-id={city.city_id}>{city.city_name}</Option>
})}
</Select>
</div>)
}
{ adverts && <AnalyticalTable
header="Adverts"
selectionMode="SingleSelect"
Expand All @@ -90,4 +123,8 @@ export const AdvertList = (props: AdvertListProps) => {
</>
);

};
};

function dispatch(arg0: { payload: number; type: "advert/fetchAdvertsStart"; }) {
throw new Error("Function not implemented.");
}
5 changes: 5 additions & 0 deletions dimria-fe/src/models/CityDto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

export interface CityDto{
city_id: number;
city_name: string;
}
29 changes: 26 additions & 3 deletions dimria-fe/src/redux/adverts/advertSlices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { PayloadAction, createSlice } from "@reduxjs/toolkit";
import {AdvertDto} from "../../models/AdvertDto";
import {AdvertDetailsDto} from "../../models/AdvertDetailsDto";
import {Action} from "../../models/types";
import { CityDto } from "../../models/CityDto";
import { fetchCities } from "./requests";


export interface AdvertsState {
Expand All @@ -11,6 +13,9 @@ export interface AdvertsState {
details: AdvertDetailsDto | null;
detailsLoading: boolean;
detailsError: string | null;
cities: CityDto[] | null;
loadingCities: boolean;
citiesError: string | null;
}

const initState : AdvertsState = {
Expand All @@ -19,14 +24,17 @@ const initState : AdvertsState = {
error: '',
details: null,
detailsLoading: false,
detailsError: ''
detailsError: '',
cities: null,
loadingCities: false,
citiesError: ''
}

export const advertSlice = createSlice({
name: 'advert',
initialState: () => initState,
reducers : {
fetchAdvertsStart: (state: AdvertsState) => {
fetchAdvertsStart: (state: AdvertsState, action: Action<number>) => {
state.loading = true;
state.error = '';
},
Expand All @@ -53,6 +61,18 @@ export const advertSlice = createSlice({
state.details = null;
state.detailsLoading = false;
state.detailsError = action.payload;
},
fetchCitiesStart: (state: AdvertsState) => {
state.loadingCities = true;
},
fetchCitiesSuccess: (state: AdvertsState, action: Action<any>) => {
state.cities = action.payload as CityDto[];
state.loadingCities = false;
},
fetchCitiesFailure: (state: AdvertsState, action: Action<string>) => {
state.cities = null;
state.loadingCities = false;
state.citiesError = action.payload;
}
}
});
Expand All @@ -63,7 +83,10 @@ export const {
fetchAdvertsFailure,
fetchAdvertDetailsStart,
fetchAdvertDetailsSuccess,
fetchAdvertDetailsFailure
fetchAdvertDetailsFailure,
fetchCitiesStart,
fetchCitiesSuccess,
fetchCitiesFailure
} = advertSlice.actions;

export default advertSlice.reducer;
10 changes: 8 additions & 2 deletions dimria-fe/src/redux/adverts/requests.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import axios from 'axios';

export const fetchAdverts = async () => {
export const fetchAdverts = async (cityId: number) => {
//return await axios.get('https://dimria-advert-prices.azurewebsites.net/api/get_advertisements');
return await axios.get('http://localhost:7071/api/get_advertisements');
return await axios.get(`http://localhost:7071/api/get_advertisements/${cityId}`);
}

export const fetchAdvertDetails = async (advertId: string) => {
//return await axios.get(`https://dimria-advert-prices.azurewebsites.net/api/get_advert_details/${advertId}`);
return await axios.get(`http://localhost:7071/api/get_advert_details/${advertId}`);
}

export const fetchCities = async () => {
//return await axios.get('https://dimria-advert-prices.azurewebsites.net/api/get_cities');
return await axios.get('http://localhost:7071/api/get_cities');
}


export const delay = (ms: number) => new Promise(res => setTimeout(res, ms));

24 changes: 21 additions & 3 deletions dimria-fe/src/redux/adverts/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@ import {
fetchAdvertsFailure,
fetchAdvertDetailsStart,
fetchAdvertDetailsSuccess,
fetchAdvertDetailsFailure
fetchAdvertDetailsFailure,
fetchCitiesStart,
fetchCitiesSuccess,
fetchCitiesFailure
} from './advertSlices';
import {fetchAdverts, fetchAdvertDetails, delay} from "./requests";
import {fetchAdverts, fetchAdvertDetails, fetchCities} from "./requests";
import {Action} from "../../models/types";

function* fetchAdvertsAsync(action: ReturnType<typeof fetchAdvertsStart> ) {
try {

const cityId = action.payload;

// @ts-ignore
const response = yield call(fetchAdverts);
const response = yield call(fetchAdverts, cityId);
yield put(fetchAdvertsSuccess(response.data));
} catch (error) {
yield put(fetchAdvertsFailure("Error fetching data"));
Expand Down Expand Up @@ -41,7 +47,19 @@ function* fetchAdvertDetailsAsync(action: Action<string> ) {
}
}

function* fetchCitiesAsync() {
try {
// @ts-ignore
const response = yield call(fetchCities);
yield put(fetchCitiesSuccess(response.data));
} catch (error) {
yield put(fetchCitiesFailure("Error fetching cities"));
console.log(error);
}
}

export function* advertsSaga() {
yield takeLatest(fetchAdvertsStart.type, fetchAdvertsAsync);
yield takeLatest(fetchAdvertDetailsStart.type, fetchAdvertDetailsAsync);
yield takeLatest(fetchCitiesStart.type, fetchCitiesAsync);
}
3 changes: 3 additions & 0 deletions dimria-fe/src/redux/adverts/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const selectAdvertError = (state: State) => state.advert.error;
export const selectDetails = (state: State) => state.advert.details;
export const selectDetailsLoading = (state: State) => state.advert.detailsLoading;
export const selectDetailsError = (state: State) => state.advert.detailsError;
export const selectCities = (state: State) => state.advert.cities;
export const selectCitiesLoading = (state: State) => state.advert.loadingCities;
export const selectCitiesError = (state: State) => state.advert.citiesError;



2 changes: 1 addition & 1 deletion dimria/dimria_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def get_advert_details(advertId: int) -> AdvertDetails:
return details


def get_cities():
def get_http_cities():
cities = []

for item in SEARCH_ITEMS:
Expand Down
6 changes: 3 additions & 3 deletions function_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pydantic.tools import parse_obj_as
from dimria.cosmos_db import process_advert

from dimria.dimria_requests import search_adverts, get_advert_details
from dimria.dimria_requests import get_http_cities, search_adverts, get_advert_details
from dimria.handle_details import build_ptoho_url, parse_photos, build_main_advert_url
from dimria.models.AdvertDetails import AdvertDetails, parse_details_from_json
from dimria.models.AdvertsList import AdvertsList
Expand Down Expand Up @@ -161,8 +161,8 @@ def get_advert_details(req: func.HttpRequest) -> func.HttpResponse:
return func.HttpResponse(data, status_code=200, headers=HEADERS)

@app.route("get_cities", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS )
def get_cities() -> func.HttpResponse:
items = get_cities()
def get_cities(req: func.HttpRequest) -> func.HttpResponse:
items = get_http_cities()

return func.HttpResponse(json.dumps(items), status_code=200, headers=HEADERS)

0 comments on commit 085086b

Please sign in to comment.