Files
WhiteNightsAdminPanel/src/shared/store/CityStore/index.ts

325 lines
6.9 KiB
TypeScript

import {
authInstance,
languageInstance,
Language,
languageStore,
countryStore,
CashedCountries,
} from "@shared";
import { makeAutoObservable, runInAction } from "mobx";
export type City = {
id?: number;
name: string;
country: string;
country_code: string;
arms: string;
};
export type CashedCities = {
ru: {
data: City[];
loaded: boolean;
};
en: {
data: City[];
loaded: boolean;
};
zh: {
data: City[];
loaded: boolean;
};
};
export type CashedCity = {
ru: City | null;
en: City | null;
zh: City | null;
};
class CityStore {
cities: CashedCities = {
ru: {
data: [],
loaded: false,
},
en: {
data: [],
loaded: false,
},
zh: {
data: [],
loaded: false,
},
};
city: Record<string, CashedCity> = {};
constructor() {
makeAutoObservable(this);
}
ruCities: {
data: City[];
loaded: boolean;
} = {
data: [],
loaded: false,
};
getRuCities = async () => {
if (this.ruCities.loaded) {
return;
}
const response = await languageInstance("ru").get(`/city`);
runInAction(() => {
this.ruCities.data = response.data;
this.ruCities.loaded = true;
});
};
getCities = async (language: keyof CashedCities) => {
if (this.cities[language].loaded) {
return;
}
const response = await languageInstance(language).get(`/city`);
runInAction(() => {
this.cities[language].data = response.data;
this.cities[language].loaded = true;
});
};
getCity = async (code: string, language: keyof CashedCities) => {
if (this.city[code]?.[language] && this.city[code][language] !== null) {
return;
}
const response = await languageInstance(language).get(`/city/${code}`);
runInAction(() => {
if (!this.city[code]) {
this.city[code] = {
ru: null,
en: null,
zh: null,
};
}
this.city[code][language] = response.data;
});
return response.data;
};
deleteCity = async (code: string) => {
await authInstance.delete(`/city/${code}`);
runInAction(() => {
for (const secondaryLanguage of ["ru", "en", "zh"] as Language[]) {
this.cities[secondaryLanguage].data = this.cities[
secondaryLanguage
].data.filter((city) => city.id !== Number(code));
if (this.city[code]) {
this.city[code][secondaryLanguage] = null;
}
}
});
};
createCityData = {
country_code: "",
arms: "",
ru: {
name: "",
},
en: {
name: "",
},
zh: {
name: "",
},
};
setCreateCityData = (
name: string,
country_code: string,
arms: string,
language: keyof CashedCities
) => {
this.createCityData = {
...this.createCityData,
country_code: country_code,
arms: arms,
[language]: {
name: name,
},
};
};
async createCity() {
const language = languageStore.language as Language;
const { country_code, arms } = this.createCityData;
const { name } = this.createCityData[language];
if (!name || !country_code) {
return;
}
try {
// Create city in primary language
const cityPayload = {
name,
country:
countryStore.countries[language as keyof CashedCountries]?.data.find(
(c) => c.code === country_code
)?.name || "",
country_code,
...(arms ? { arms } : {}),
};
const cityResponse = await languageInstance(language).post(
"/city",
cityPayload
);
const cityId = cityResponse.data.id;
// Create/update other language versions
for (const secondaryLanguage of (["ru", "en", "zh"] as Language[]).filter(
(l) => l !== language
)) {
const { name: secondaryName } = this.createCityData[secondaryLanguage];
// Get country name in secondary language
const countryName =
countryStore.countries[secondaryLanguage]?.data.find(
(c) => c.code === country_code
)?.name || "";
const patchPayload = {
name: secondaryName || "",
country: countryName,
country_code: country_code || "",
...(arms ? { arms } : {}),
};
const patchResponse = await languageInstance(secondaryLanguage).patch(
`/city/${cityId}`,
patchPayload
);
runInAction(() => {
this.cities[secondaryLanguage].data = [
...this.cities[secondaryLanguage].data,
patchResponse.data,
];
});
}
// Update primary language data
runInAction(() => {
this.cities[language].data = [
...this.cities[language].data,
cityResponse.data,
];
});
// Reset form data
runInAction(() => {
this.createCityData = {
country_code: "",
arms: "",
ru: { name: "" },
en: { name: "" },
zh: { name: "" },
};
});
} catch (error) {
console.error("Error creating city:", error);
throw error;
}
}
editCityData = {
country_code: "",
arms: "",
ru: {
name: "",
},
en: {
name: "",
},
zh: {
name: "",
},
};
setEditCityData = (
name: string,
country_code: string,
arms: string,
language: keyof CashedCities
) => {
this.editCityData = {
...this.editCityData,
country_code: country_code,
arms: arms,
[language]: {
name: name,
},
};
};
editCity = async (code: string) => {
for (const language of ["ru", "en", "zh"]) {
const { country_code, arms } = this.editCityData;
const { name } = this.editCityData[language as keyof CashedCities];
const { countries } = countryStore;
const country = countries[language as keyof CashedCities].data.find(
(country) => country.code === country_code
);
await languageInstance(language as Language).patch(`/city/${code}`, {
name,
country: country?.name || "",
country_code: country_code,
arms,
});
runInAction(() => {
if (this.city[code]) {
this.city[code][language as keyof CashedCities] = {
name,
country: country?.name || "",
country_code: country_code,
arms,
};
}
if (this.cities[language as keyof CashedCities]) {
this.cities[language as keyof CashedCities].data = this.cities[
language as keyof CashedCities
].data.map((city) =>
city.id === Number(code)
? {
id: city.id,
name,
country: country?.name || "",
country_code: country_code,
arms,
}
: city
);
}
});
}
};
}
export const cityStore = new CityStore();