* Removed unecesery home page * Added PHP Api that provides auth and replaces the json-server for data storage * Added support for alternate geocode-api * Added registration page
149 lines
3.3 KiB
JavaScript
149 lines
3.3 KiB
JavaScript
import {
|
|
useEffect,
|
|
createContext,
|
|
useState,
|
|
useContext,
|
|
useReducer,
|
|
} from "react";
|
|
|
|
import axios from 'axios';
|
|
|
|
const CitiesContext = createContext();
|
|
const API_URL = import.meta.env.VITE_API_URL;
|
|
|
|
const initialState = {
|
|
cities: [],
|
|
isLoading: false,
|
|
currentCity: {},
|
|
error: "",
|
|
};
|
|
|
|
function reducer(state, action) {
|
|
switch (action.type) {
|
|
case "loading":
|
|
return { ...state, isLoading: true };
|
|
case "cities/loaded":
|
|
return { ...state, isLoading: false,cities: action.payload };
|
|
case "city/loaded":
|
|
return { ...state, currentCity: action.payload, isLoading: false };
|
|
case "cities/created":
|
|
return {
|
|
...state,
|
|
cities: [...state.cities, action.payload],
|
|
isLoading: false,
|
|
currentCity:action.payload
|
|
};
|
|
case "cities/deleted":
|
|
return {
|
|
...state,
|
|
isLoading: false,
|
|
cities: state.cities.filter((city) => city.id !== action.payload),
|
|
currentCity:{}
|
|
};
|
|
case "rejected":
|
|
return { ...state, isLoading: false, error: action.payload };
|
|
default:
|
|
throw new Error(`Action not supported`);
|
|
}
|
|
}
|
|
|
|
|
|
function CitiesProvider({ children }) {
|
|
const [state, dispatch] = useReducer(reducer,initialState);
|
|
const { cities, isLoading, currentCity } = state;
|
|
|
|
|
|
useEffect(function () {
|
|
async function fetchData() {
|
|
dispatch({ type: "loading" });
|
|
try {
|
|
const response = await axios.get(`${API_URL}/get_items`);
|
|
const res = await response.data;
|
|
|
|
dispatch({ type:"cities/loaded", payload: res });
|
|
} catch {
|
|
dispatch({
|
|
type: "rejected",
|
|
payload: "There was an error loading the cities",
|
|
});
|
|
}
|
|
}
|
|
fetchData();
|
|
}, []);
|
|
|
|
async function getCity(id) {
|
|
if(Number(id)===currentCity.id) return;
|
|
dispatch({ type: "loading" });
|
|
try {
|
|
const response = await axios.get(`${API_URL}/get_item?id=${id}`);
|
|
const res = await response.data.json();
|
|
|
|
dispatch({ type: "city/loaded", payload: res });
|
|
} catch {
|
|
dispatch({
|
|
type: "rejected",
|
|
payload: "There was an error loading the city",
|
|
});
|
|
}
|
|
}
|
|
|
|
async function createCity(newCity) {
|
|
dispatch({ type: "loading" });
|
|
try {
|
|
const response = await axios.post(
|
|
`${API_URL}/create_item`,
|
|
newCity,
|
|
{
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
}
|
|
);
|
|
dispatch({ type: "cities/created", payload: response.data });
|
|
} catch (error) {
|
|
dispatch({
|
|
type: "rejected",
|
|
payload: error.response?.data?.message || 'There was an error loading the city',
|
|
});
|
|
}
|
|
}
|
|
|
|
async function deleteCity(id) {
|
|
dispatch({ type: "loading" });
|
|
try {
|
|
const response = await axios.delete(`${API_URL}/delete_item?id=${id}`, {
|
|
method: "DELETE",
|
|
});
|
|
dispatch({ type: "cities/deleted", payload: id });
|
|
} catch {
|
|
dispatch({
|
|
type: "rejected",
|
|
payload: "There was an error deleting the city",
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
return (
|
|
<CitiesContext.Provider
|
|
value={{
|
|
cities,
|
|
isLoading,
|
|
currentCity,
|
|
getCity,
|
|
createCity,
|
|
deleteCity,
|
|
}}
|
|
>
|
|
{children}
|
|
</CitiesContext.Provider>
|
|
);
|
|
}
|
|
|
|
function useCities() {
|
|
const context = useContext(CitiesContext);
|
|
return context;
|
|
}
|
|
|
|
export { CitiesProvider, useCities };
|