325 lines
6.9 KiB
TypeScript
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();
|