task update
This commit is contained in:
@@ -37,4 +37,11 @@ export const doctor_api = {
|
|||||||
const res = await httpClient.delete(`${API_URLS.DOCTOR}${id}/delete/`);
|
const res = await httpClient.delete(`${API_URLS.DOCTOR}${id}/delete/`);
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async export() {
|
||||||
|
const res = await httpClient.get(`${API_URLS.DOCTOR_EXPORT}`, {
|
||||||
|
responseType: "blob",
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { doctor_api } from "@/features/doctors/lib/api";
|
||||||
import type { DoctorListResData } from "@/features/doctors/lib/data";
|
import type { DoctorListResData } from "@/features/doctors/lib/data";
|
||||||
import AddedDoctor from "@/features/doctors/ui/AddedDoctor";
|
import AddedDoctor from "@/features/doctors/ui/AddedDoctor";
|
||||||
import { Button } from "@/shared/ui/button";
|
import { Button } from "@/shared/ui/button";
|
||||||
@@ -9,8 +10,11 @@ import {
|
|||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "@/shared/ui/dialog";
|
} from "@/shared/ui/dialog";
|
||||||
import { Input } from "@/shared/ui/input";
|
import { Input } from "@/shared/ui/input";
|
||||||
import { Plus } from "lucide-react";
|
import { useMutation } from "@tanstack/react-query";
|
||||||
|
import type { AxiosError } from "axios";
|
||||||
|
import { CloudDownload, Loader2, Plus } from "lucide-react";
|
||||||
import type { Dispatch, SetStateAction } from "react";
|
import type { Dispatch, SetStateAction } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
searchName: string;
|
searchName: string;
|
||||||
@@ -49,6 +53,45 @@ const FilterDoctor = ({
|
|||||||
setEditingPlan,
|
setEditingPlan,
|
||||||
editingPlan,
|
editingPlan,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: async () => {
|
||||||
|
const res = await doctor_api.export();
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
onSuccess: (data: Blob) => {
|
||||||
|
// Blob URL yaratish
|
||||||
|
const url = window.URL.createObjectURL(
|
||||||
|
new Blob([data], {
|
||||||
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// <a> elementi orqali yuklab olish
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.setAttribute("download", "doctor_export.xlsx"); // Fayl nomi
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
|
||||||
|
// Blob URL-ni ozod qilish
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
toast.success("Excel muvaffaqiyatli yuklab olindi", {
|
||||||
|
position: "top-center",
|
||||||
|
richColors: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (err: AxiosError) => {
|
||||||
|
const errMessage = err.response?.data as { message: string };
|
||||||
|
const messageText = errMessage.message;
|
||||||
|
|
||||||
|
toast.error(messageText || "Xatolik yuz berdi", {
|
||||||
|
richColors: true,
|
||||||
|
position: "top-center",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-end gap-2 w-full">
|
<div className="flex justify-end gap-2 w-full">
|
||||||
<Input
|
<Input
|
||||||
@@ -87,6 +130,17 @@ const FilterDoctor = ({
|
|||||||
onChange={(e) => setSearchUser(e.target.value)}
|
onChange={(e) => setSearchUser(e.target.value)}
|
||||||
className="w-full md:w-48"
|
className="w-full md:w-48"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="default"
|
||||||
|
className="bg-blue-500 cursor-pointer hover:bg-blue-500"
|
||||||
|
onClick={() => mutate()}
|
||||||
|
disabled={isPending}
|
||||||
|
>
|
||||||
|
<CloudDownload className="!h-5 !w-5" /> Excel formatda yuklash
|
||||||
|
{isPending && <Loader2 className="animate-spin" />}
|
||||||
|
</Button>
|
||||||
|
|
||||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -38,4 +38,11 @@ export const pharmacies_api = {
|
|||||||
const res = await httpClient.delete(`${API_URLS.PHARMACIES}${id}/delete/`);
|
const res = await httpClient.delete(`${API_URLS.PHARMACIES}${id}/delete/`);
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async export() {
|
||||||
|
const res = await httpClient.get(`${API_URLS.PHARMACIES_EXPORT}`, {
|
||||||
|
responseType: "blob",
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -123,9 +123,9 @@ export interface PharmaciesListData {
|
|||||||
|
|
||||||
export interface CreatePharmaciesReq {
|
export interface CreatePharmaciesReq {
|
||||||
name: string;
|
name: string;
|
||||||
inn: string;
|
inn?: string;
|
||||||
owner_phone: string;
|
owner_phone: string;
|
||||||
responsible_phone: string;
|
responsible_phone?: string;
|
||||||
district_id: number;
|
district_id: number;
|
||||||
place_id: number;
|
place_id: number;
|
||||||
user_id: number;
|
user_id: number;
|
||||||
@@ -136,9 +136,9 @@ export interface CreatePharmaciesReq {
|
|||||||
|
|
||||||
export interface UpdatePharmaciesReq {
|
export interface UpdatePharmaciesReq {
|
||||||
name: string;
|
name: string;
|
||||||
inn: string;
|
inn?: string;
|
||||||
owner_phone: string;
|
owner_phone: string;
|
||||||
responsible_phone: string;
|
responsible_phone?: string;
|
||||||
longitude: number;
|
longitude: number;
|
||||||
latitude: number;
|
latitude: number;
|
||||||
extra_location: { longitude: number; latitude: number };
|
extra_location: { longitude: number; latitude: number };
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import z from "zod";
|
|||||||
|
|
||||||
export const PharmForm = z.object({
|
export const PharmForm = z.object({
|
||||||
name: z.string().min(1, { message: "Majburiy maydon" }),
|
name: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
inn: z.string().min(1, { message: "Majburiy maydon" }),
|
inn: z.string().optional(),
|
||||||
phone_number: z.string().min(1, { message: "Majburiy maydon" }),
|
phone_number: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
additional_phone: z.string().min(1, { message: "Majburiy maydon" }),
|
additional_phone: z.string().optional(),
|
||||||
district: z.string().min(1, { message: "Majburiy maydon" }),
|
district: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
user: z.string().min(1, { message: "Majburiy maydon" }),
|
user: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
object: z.string().min(1, { message: "Majburiy maydon" }),
|
object: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
|
|||||||
@@ -249,36 +249,31 @@ const AddedPharmacies = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function onSubmit(values: z.infer<typeof PharmForm>) {
|
function onSubmit(values: z.infer<typeof PharmForm>) {
|
||||||
|
const baseBody = {
|
||||||
|
extra_location: {
|
||||||
|
latitude: Number(values.lat),
|
||||||
|
longitude: Number(values.long),
|
||||||
|
},
|
||||||
|
latitude: Number(values.lat),
|
||||||
|
longitude: Number(values.long),
|
||||||
|
name: values.name,
|
||||||
|
owner_phone: onlyNumber(values.phone_number),
|
||||||
|
...(values.additional_phone && {
|
||||||
|
responsible_phone: onlyNumber(values.additional_phone),
|
||||||
|
}),
|
||||||
|
...(values.inn && { inn: values.inn }), // 👈 faqat bo‘lsa yuboriladi
|
||||||
|
};
|
||||||
|
|
||||||
if (initialValues) {
|
if (initialValues) {
|
||||||
edit({
|
edit({
|
||||||
id: initialValues.id,
|
id: initialValues.id,
|
||||||
body: {
|
body: baseBody,
|
||||||
extra_location: {
|
|
||||||
latitude: Number(values.lat),
|
|
||||||
longitude: Number(values.long),
|
|
||||||
},
|
|
||||||
latitude: Number(values.lat),
|
|
||||||
longitude: Number(values.long),
|
|
||||||
inn: values.inn,
|
|
||||||
name: values.name,
|
|
||||||
owner_phone: onlyNumber(values.phone_number),
|
|
||||||
responsible_phone: onlyNumber(values.additional_phone),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
mutate({
|
mutate({
|
||||||
|
...baseBody,
|
||||||
district_id: Number(values.district),
|
district_id: Number(values.district),
|
||||||
extra_location: {
|
|
||||||
latitude: Number(values.lat),
|
|
||||||
longitude: Number(values.long),
|
|
||||||
},
|
|
||||||
latitude: Number(values.lat),
|
|
||||||
longitude: Number(values.long),
|
|
||||||
inn: values.inn,
|
|
||||||
name: values.name,
|
|
||||||
owner_phone: onlyNumber(values.phone_number),
|
|
||||||
place_id: Number(values.object),
|
place_id: Number(values.object),
|
||||||
responsible_phone: onlyNumber(values.additional_phone),
|
|
||||||
user_id: Number(values.user),
|
user_id: Number(values.user),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -343,7 +338,7 @@ const AddedPharmacies = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
<Input
|
<Input
|
||||||
placeholder="+998 90 123-45-67"
|
placeholder="+998 90 123-45-67"
|
||||||
{...field}
|
{...field}
|
||||||
value={formatPhone(field.value)}
|
value={field.value && formatPhone(field.value)}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { pharmacies_api } from "@/features/pharmacies/lib/api";
|
||||||
import type { PharmaciesListData } from "@/features/pharmacies/lib/data";
|
import type { PharmaciesListData } from "@/features/pharmacies/lib/data";
|
||||||
import AddedPharmacies from "@/features/pharmacies/ui/AddedPharmacies";
|
import AddedPharmacies from "@/features/pharmacies/ui/AddedPharmacies";
|
||||||
import { Button } from "@/shared/ui/button";
|
import { Button } from "@/shared/ui/button";
|
||||||
@@ -9,8 +10,11 @@ import {
|
|||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "@/shared/ui/dialog";
|
} from "@/shared/ui/dialog";
|
||||||
import { Input } from "@/shared/ui/input";
|
import { Input } from "@/shared/ui/input";
|
||||||
import { Plus } from "lucide-react";
|
import { useMutation } from "@tanstack/react-query";
|
||||||
|
import type { AxiosError } from "axios";
|
||||||
|
import { CloudDownload, Loader2, Plus } from "lucide-react";
|
||||||
import type { Dispatch, SetStateAction } from "react";
|
import type { Dispatch, SetStateAction } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
searchName: string;
|
searchName: string;
|
||||||
@@ -41,6 +45,45 @@ const PharmaciesFilter = ({
|
|||||||
setEditingPlan,
|
setEditingPlan,
|
||||||
editingPlan,
|
editingPlan,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const { mutate, isPending } = useMutation({
|
||||||
|
mutationFn: async () => {
|
||||||
|
const res = await pharmacies_api.export();
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
onSuccess: (data: Blob) => {
|
||||||
|
// Blob URL yaratish
|
||||||
|
const url = window.URL.createObjectURL(
|
||||||
|
new Blob([data], {
|
||||||
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// <a> elementi orqali yuklab olish
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.setAttribute("download", "dorixonalar.xlsx"); // Fayl nomi
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
|
||||||
|
// Blob URL-ni ozod qilish
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
toast.success("Excel muvaffaqiyatli yuklab olindi", {
|
||||||
|
position: "top-center",
|
||||||
|
richColors: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (err: AxiosError) => {
|
||||||
|
const errMessage = err.response?.data as { message: string };
|
||||||
|
const messageText = errMessage.message;
|
||||||
|
|
||||||
|
toast.error(messageText || "Xatolik yuz berdi", {
|
||||||
|
richColors: true,
|
||||||
|
position: "top-center",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-end gap-2 w-full">
|
<div className="flex justify-end gap-2 w-full">
|
||||||
<Input
|
<Input
|
||||||
@@ -67,6 +110,15 @@ const PharmaciesFilter = ({
|
|||||||
onChange={(e) => setSearchUser(e.target.value)}
|
onChange={(e) => setSearchUser(e.target.value)}
|
||||||
className="w-full md:w-48"
|
className="w-full md:w-48"
|
||||||
/>
|
/>
|
||||||
|
<Button
|
||||||
|
variant="default"
|
||||||
|
className="bg-blue-500 cursor-pointer hover:bg-blue-500"
|
||||||
|
onClick={() => mutate()}
|
||||||
|
disabled={isPending}
|
||||||
|
>
|
||||||
|
<CloudDownload className="!h-5 !w-5" /> Excel formatda yuklash
|
||||||
|
{isPending && <Loader2 className="animate-spin" />}
|
||||||
|
</Button>
|
||||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export interface PlanListData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PlanCreateReq {
|
export interface PlanCreateReq {
|
||||||
title: string;
|
// title: string;
|
||||||
description: string;
|
description: string;
|
||||||
date: string;
|
date: string;
|
||||||
user_id: number;
|
user_id: number;
|
||||||
@@ -63,7 +63,7 @@ export interface PlanCreateReq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PlanUpdateReq {
|
export interface PlanUpdateReq {
|
||||||
title: string;
|
// title: string;
|
||||||
description: string;
|
description: string;
|
||||||
date: string;
|
date: string;
|
||||||
longitude: number;
|
longitude: number;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import z from "zod";
|
import z from "zod";
|
||||||
|
|
||||||
export const createPlanFormData = z.object({
|
export const createPlanFormData = z.object({
|
||||||
name: z.string().min(1, { message: "Majburiy maydon" }),
|
// name: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
description: z.string().min(1, { message: "Majburiy maydon" }),
|
description: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
user: z.string().min(1, { message: "Majburiy maydon" }),
|
user: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
date: z.string().min(1, { message: "Majburiy maydon" }),
|
date: z.string().min(1, { message: "Majburiy maydon" }),
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import {
|
|||||||
FormItem,
|
FormItem,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/shared/ui/form";
|
} from "@/shared/ui/form";
|
||||||
import { Input } from "@/shared/ui/input";
|
|
||||||
import { Label } from "@/shared/ui/label";
|
import { Label } from "@/shared/ui/label";
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/shared/ui/popover";
|
import { Popover, PopoverContent, PopoverTrigger } from "@/shared/ui/popover";
|
||||||
import { Textarea } from "@/shared/ui/textarea";
|
import { Textarea } from "@/shared/ui/textarea";
|
||||||
@@ -49,7 +48,7 @@ const AddedPlan = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
const form = useForm<z.infer<typeof createPlanFormData>>({
|
const form = useForm<z.infer<typeof createPlanFormData>>({
|
||||||
resolver: zodResolver(createPlanFormData),
|
resolver: zodResolver(createPlanFormData),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: initialValues?.title || "",
|
// name: initialValues?.title || "",
|
||||||
description: initialValues?.description || "",
|
description: initialValues?.description || "",
|
||||||
user: initialValues ? String(initialValues.user.id) : "",
|
user: initialValues ? String(initialValues.user.id) : "",
|
||||||
date: initialValues ? initialValues?.date : "",
|
date: initialValues ? initialValues?.date : "",
|
||||||
@@ -180,7 +179,7 @@ const AddedPlan = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
},
|
},
|
||||||
latitude: initialValues.latitude,
|
latitude: initialValues.latitude,
|
||||||
longitude: initialValues.longitude,
|
longitude: initialValues.longitude,
|
||||||
title: data.name,
|
// title: data.name,
|
||||||
},
|
},
|
||||||
id: initialValues.id,
|
id: initialValues.id,
|
||||||
});
|
});
|
||||||
@@ -194,7 +193,7 @@ const AddedPlan = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
},
|
},
|
||||||
latitude: lat,
|
latitude: lat,
|
||||||
longitude: long,
|
longitude: long,
|
||||||
title: data.name,
|
// title: data.name,
|
||||||
doctor_id: data.doctor_id ? Number(data.doctor_id) : null,
|
doctor_id: data.doctor_id ? Number(data.doctor_id) : null,
|
||||||
pharmacy_id: data.pharmacy_id ? Number(data.pharmacy_id) : null,
|
pharmacy_id: data.pharmacy_id ? Number(data.pharmacy_id) : null,
|
||||||
user_id: Number(data.user),
|
user_id: Number(data.user),
|
||||||
@@ -499,7 +498,7 @@ const AddedPlan = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<FormField
|
{/* <FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="name"
|
name="name"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
@@ -515,7 +514,7 @@ const AddedPlan = ({ initialValues, setDialogOpen }: Props) => {
|
|||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ export const API_URLS = {
|
|||||||
REGIONS: `${API_V}admin/region/`,
|
REGIONS: `${API_V}admin/region/`,
|
||||||
DISTRICT: `${API_V}admin/district/`,
|
DISTRICT: `${API_V}admin/district/`,
|
||||||
DOCTOR: `${API_V}admin/doctor/`,
|
DOCTOR: `${API_V}admin/doctor/`,
|
||||||
|
DOCTOR_EXPORT: `${API_V}admin/doctor/export/`,
|
||||||
OBJECT: `${API_V}admin/place/`,
|
OBJECT: `${API_V}admin/place/`,
|
||||||
PHARMACIES: `${API_V}admin/pharmacy/`,
|
PHARMACIES: `${API_V}admin/pharmacy/`,
|
||||||
|
PHARMACIES_EXPORT: `${API_V}admin/pharmacy/export/`,
|
||||||
PLANS: `${API_V}admin/plan/`,
|
PLANS: `${API_V}admin/plan/`,
|
||||||
PILL: `${API_V}admin/product/`,
|
PILL: `${API_V}admin/product/`,
|
||||||
LOCATION: `${API_V}admin/location/`,
|
LOCATION: `${API_V}admin/location/`,
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
ClipboardList,
|
ClipboardList,
|
||||||
FileText,
|
FileText,
|
||||||
Hospital,
|
Hospital,
|
||||||
ListChecks,
|
|
||||||
LogOut,
|
LogOut,
|
||||||
Map,
|
Map,
|
||||||
MapPin,
|
MapPin,
|
||||||
@@ -77,11 +76,11 @@ const items = [
|
|||||||
url: "/dashboard/reports",
|
url: "/dashboard/reports",
|
||||||
icon: ClipboardList,
|
icon: ClipboardList,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: "Tur planlar",
|
// title: "Tur planlar",
|
||||||
url: "/dashboard/tour-plan",
|
// url: "/dashboard/tour-plan",
|
||||||
icon: ListChecks,
|
// icon: ListChecks,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: "Hududlar",
|
title: "Hududlar",
|
||||||
url: "/dashboard/region",
|
url: "/dashboard/region",
|
||||||
|
|||||||
@@ -10,4 +10,8 @@ export default defineConfig({
|
|||||||
resolve: {
|
resolve: {
|
||||||
alias: [{ find: "@", replacement: path.resolve(__dirname, "src") }],
|
alias: [{ find: "@", replacement: path.resolve(__dirname, "src") }],
|
||||||
},
|
},
|
||||||
|
server: {
|
||||||
|
port: 5175,
|
||||||
|
host: true, // barcha hostlarga ruxsat
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user