From db6bfa7e4060d32b3c716e1cf9570f7da94a05cd Mon Sep 17 00:00:00 2001 From: Samandar Turgunboyev Date: Fri, 5 Dec 2025 17:47:11 +0500 Subject: [PATCH] update new api reques and response --- package-lock.json | 17 + package.json | 1 + src/features/distributed/lib/api.ts | 21 + src/features/distributed/lib/column.tsx | 75 ++++ src/features/distributed/lib/data-table.tsx | 80 ++++ src/features/distributed/lib/data.ts | 24 ++ .../distributed/ui/DistributedAddModal.tsx | 208 +++++++++ .../distributed/ui/DistributedDetail.tsx | 82 ++++ .../distributed/ui/DistributedList.tsx | 66 +++ src/features/district/lib/column.tsx | 9 +- src/features/doctor/lib/column.tsx | 11 +- src/features/doctor/ui/Doctor.tsx | 77 ++-- src/features/home/ui/Home.tsx | 18 + src/features/plan/lib/api.ts | 4 +- src/features/plan/lib/data.ts | 25 +- .../plan/ui/PlanDetailsDialogProps.tsx | 164 ++++--- src/features/plan/ui/addPlans.tsx | 401 +++++++++++++----- src/features/plan/ui/plans.tsx | 28 +- src/features/support/lib/api.ts | 21 + src/features/support/lib/column.tsx | 32 ++ src/features/support/lib/data-table.tsx | 80 ++++ src/features/support/lib/data.ts | 23 + src/features/support/ui/SendSupport.tsx | 217 ++++++++++ src/features/support/ui/SupportList.tsx | 71 ++++ .../DistributedProduct.tsx | 12 + src/pages/support/index.tsx | 12 + src/providers/routing/config.tsx | 18 + src/shared/config/api/URLs.ts | 34 +- src/shared/ui/command.tsx | 184 ++++++++ vite.config.ts | 2 +- 30 files changed, 1755 insertions(+), 262 deletions(-) create mode 100644 src/features/distributed/lib/api.ts create mode 100644 src/features/distributed/lib/column.tsx create mode 100644 src/features/distributed/lib/data-table.tsx create mode 100644 src/features/distributed/lib/data.ts create mode 100644 src/features/distributed/ui/DistributedAddModal.tsx create mode 100644 src/features/distributed/ui/DistributedDetail.tsx create mode 100644 src/features/distributed/ui/DistributedList.tsx create mode 100644 src/features/support/lib/api.ts create mode 100644 src/features/support/lib/column.tsx create mode 100644 src/features/support/lib/data-table.tsx create mode 100644 src/features/support/lib/data.ts create mode 100644 src/features/support/ui/SendSupport.tsx create mode 100644 src/features/support/ui/SupportList.tsx create mode 100644 src/pages/distributed-product/DistributedProduct.tsx create mode 100644 src/pages/support/index.tsx create mode 100644 src/shared/ui/command.tsx diff --git a/package-lock.json b/package-lock.json index 82edb36..5a357f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "axios": "^1.9.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", "date-fns": "^4.1.0", "dayjs": "^1.11.18", "framer-motion": "^12.23.24", @@ -4007,6 +4008,22 @@ "node": ">=6" } }, + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", diff --git a/package.json b/package.json index 05d24f5..78d12ed 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "axios": "^1.9.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", "date-fns": "^4.1.0", "dayjs": "^1.11.18", "framer-motion": "^12.23.24", diff --git a/src/features/distributed/lib/api.ts b/src/features/distributed/lib/api.ts new file mode 100644 index 0000000..9d58604 --- /dev/null +++ b/src/features/distributed/lib/api.ts @@ -0,0 +1,21 @@ +import type { DistributedList } from "@/features/distributed/lib/data"; +import httpClient from "@/shared/config/api/httpClient"; +import { DISTRIBUTED_CREATE, DISTRIBUTED_LIST } from "@/shared/config/api/URLs"; +import type { AxiosResponse } from "axios"; + +export const distributed_api = { + async list(): Promise> { + const res = await httpClient.get(DISTRIBUTED_LIST); + return res; + }, + + async create(body: { + product_id: number; + date: string; + employee_name: string; + quantity: number; + }) { + const res = await httpClient.post(DISTRIBUTED_CREATE, body); + return res; + }, +}; diff --git a/src/features/distributed/lib/column.tsx b/src/features/distributed/lib/column.tsx new file mode 100644 index 0000000..f169a7f --- /dev/null +++ b/src/features/distributed/lib/column.tsx @@ -0,0 +1,75 @@ +import type { DistributedListData } from "@/features/distributed/lib/data"; +import { Button } from "@/shared/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, +} from "@/shared/ui/dropdown-menu"; +import type { ColumnDef } from "@tanstack/react-table"; +import { EllipsisVertical, Eye } from "lucide-react"; + +interface ColumnProps { + handleEdit: (district: DistributedListData) => void; +} + +export const columnsDistributed = ({ + handleEdit, +}: ColumnProps): ColumnDef[] => [ + { + accessorKey: "id", + header: () =>
, + cell: ({ row }) => ( +
{row.index + 1}
+ ), + }, + { + accessorKey: "name", + header: () =>
Xaridoring ismi
, + cell: ({ row }) => ( +
+ {row.original.employee_name} +
+ ), + }, + { + accessorKey: "name-product", + header: () =>
Mahsulot nomi
, + cell: ({ row }) => ( +
{row.original.product.name}
+ ), + }, + { + accessorKey: "name-product", + header: () =>
Soni
, + cell: ({ row }) => ( +
{row.original.quantity}
+ ), + }, + { + id: "actions", + header: () =>
Amallar
, + cell: ({ row }) => { + const district = row.original; + + return ( + + + + + + + + + ); + }, + }, +]; diff --git a/src/features/distributed/lib/data-table.tsx b/src/features/distributed/lib/data-table.tsx new file mode 100644 index 0000000..71cdd71 --- /dev/null +++ b/src/features/distributed/lib/data-table.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { + flexRender, + getCoreRowModel, + useReactTable, + type ColumnDef, +} from "@tanstack/react-table"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/shared/ui/table"; + +interface DataTableProps { + columns: ColumnDef[]; + data: MyDiscrictData[]; +} + +export function DataTableDistributed({ + columns, + data, +}: DataTableProps) { + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + }); + + return ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + ) : ( + + + Hech narsa yo'q + + + )} + +
+
+ ); +} diff --git a/src/features/distributed/lib/data.ts b/src/features/distributed/lib/data.ts new file mode 100644 index 0000000..a68df17 --- /dev/null +++ b/src/features/distributed/lib/data.ts @@ -0,0 +1,24 @@ +export interface DistributedList { + status_code: number; + status: string; + message: string; + data: { + count: number; + next: null | string; + previous: null | string; + results: DistributedListData[]; + }; +} + +export interface DistributedListData { + id: number; + product: { + id: number; + name: string; + price: number; + }; + quantity: number; + employee_name: string; + created_at: string; + date: string; +} diff --git a/src/features/distributed/ui/DistributedAddModal.tsx b/src/features/distributed/ui/DistributedAddModal.tsx new file mode 100644 index 0000000..92e6af9 --- /dev/null +++ b/src/features/distributed/ui/DistributedAddModal.tsx @@ -0,0 +1,208 @@ +import { distributed_api } from "@/features/distributed/lib/api"; +import { order_api } from "@/features/specification/lib/api"; +import formatDate from "@/shared/lib/formatDate"; +import { Button } from "@/shared/ui/button"; +import { Calendar } from "@/shared/ui/calendar"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/shared/ui/command"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/shared/ui/dialog"; +import { Input } from "@/shared/ui/input"; +import { Label } from "@/shared/ui/label"; +import { Popover, PopoverContent, PopoverTrigger } from "@/shared/ui/popover"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { ChevronDownIcon, ChevronsUpDown } from "lucide-react"; +import { useState } from "react"; + +interface Props { + open: boolean; + setOpen: (v: boolean) => void; +} + +export default function DistributedAddModal({ open, setOpen }: Props) { + const [form, setForm] = useState({ + product_id: 0, + date: "", + employee_name: "", + quantity: 0, + }); + + const client = useQueryClient(); + + const { data: product } = useQuery({ + queryKey: ["product_list"], + queryFn: () => order_api.product_list(), + select(data) { + return data.data.data; + }, + }); + + const [openProduct, setOpenProduct] = useState(false); + const [searchProduct, setSearchProduct] = useState(""); + const [openDate, setOpenData] = useState(false); + + const selectedProduct = product?.find((x) => x.id === form.product_id); + + const createMutation = useMutation({ + mutationFn: () => distributed_api.create(form), + onSuccess: () => { + client.invalidateQueries({ queryKey: ["distributed_list"] }); + setOpen(false); + }, + }); + + const handleSubmit = () => { + createMutation.mutate(); + }; + + return ( + + + + Yangi topshirilgan mahsulot qo‘shish + + +
+
+ + + + + + + + + + + + {product && product.length > 0 ? ( + + {product + .filter((p) => + p.name + .toLowerCase() + .includes(searchProduct.toLowerCase()), + ) + .map((p) => ( + { + setForm({ ...form, product_id: p.id }); + setOpenProduct(false); + }} + > + {p.name} + + ))} + + ) : ( + Mahsulot topilmadi + )} + + + + +
+ +
+ + { + const val = e.target.value; + setForm({ ...form, quantity: val === "" ? 0 : Number(val) }); + }} + /> +
+ +
+ + + setForm({ ...form, employee_name: e.target.value }) + } + /> +
+ +
+ + + + + + + + { + if (date) { + setForm({ + ...form, + date: formatDate.format(date, "YYYY-MM-DD"), + }); + setOpenData(false); + } + }} + /> + + +
+
+ + +
+
+ ); +} diff --git a/src/features/distributed/ui/DistributedDetail.tsx b/src/features/distributed/ui/DistributedDetail.tsx new file mode 100644 index 0000000..0269560 --- /dev/null +++ b/src/features/distributed/ui/DistributedDetail.tsx @@ -0,0 +1,82 @@ +import type { DistributedListData } from "@/features/distributed/lib/data"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/shared/ui/dialog"; +import { type Dispatch, type SetStateAction } from "react"; + +interface Props { + open: boolean; + setOpen: Dispatch>; + specification: DistributedListData | null; +} + +const DistributedDetail = ({ open, setOpen, specification }: Props) => { + return ( + + + + + Tafsilot + + + +
+ {/* Asosiy ma'lumotlar - Grid */} +
+ {/* Xaridor */} +
+

+ Xaridorning ismi +

+

+ {specification?.employee_name} +

+
+ + {/* Foydalanuvchi */} + +
+

+ Topshirilgan sanasi +

+

+ {specification?.date} +

+
+
+ + {/* Dorilar ro'yxati */} +
+

+ Topshirilgan dori +

+ +
+
+
+
+
+

+ {specification?.product.name} +

+
+
+ + Miqdor: {specification?.quantity} ta + +
+
+
+
+
+
+
+
+
+ ); +}; + +export default DistributedDetail; diff --git a/src/features/distributed/ui/DistributedList.tsx b/src/features/distributed/ui/DistributedList.tsx new file mode 100644 index 0000000..3cd0e0a --- /dev/null +++ b/src/features/distributed/ui/DistributedList.tsx @@ -0,0 +1,66 @@ +import { distributed_api } from "@/features/distributed/lib/api"; +import { columnsDistributed } from "@/features/distributed/lib/column"; +import type { DistributedListData } from "@/features/distributed/lib/data"; +import { DataTableDistributed } from "@/features/distributed/lib/data-table"; +import DistributedAddModal from "@/features/distributed/ui/DistributedAddModal"; +import DistributedDetail from "@/features/distributed/ui/DistributedDetail"; +import AddedButton from "@/shared/ui/added-button"; +import { Skeleton } from "@/shared/ui/skeleton"; +import { DashboardLayout } from "@/widgets/dashboard-layout/ui"; +import { useQuery } from "@tanstack/react-query"; +import { useState } from "react"; + +const DistributedList = () => { + const { data, isLoading, isError } = useQuery({ + queryKey: ["distributed_list"], + queryFn: () => distributed_api.list(), + }); + const [open, setOpen] = useState(false); + const [added, setAdded] = useState(false); + const [detail, setDetail] = useState(null); + + const handleEdit = (district: DistributedListData) => { + setDetail(district); + setOpen(true); + }; + + const columns = columnsDistributed({ + handleEdit, + }); + + return ( + + setAdded(true)} /> + <> +
+

Topshirilgan mahsulotlar

+ + {isLoading ? ( +
+ {[1, 2, 3].map((i) => ( + + ))} +
+ ) : isError ? ( +

+ Tumanlar yuklanmadi. Qayta urinib ko‘ring. +

+ ) : data ? ( +
+ +
+ ) : ( +

Tumanlar mavjud emas

+ )} +
+ + + +
+ ); +}; + +export default DistributedList; diff --git a/src/features/district/lib/column.tsx b/src/features/district/lib/column.tsx index 04a70fd..05db7a9 100644 --- a/src/features/district/lib/column.tsx +++ b/src/features/district/lib/column.tsx @@ -6,7 +6,7 @@ import { DropdownMenuTrigger, } from "@/shared/ui/dropdown-menu"; import type { ColumnDef } from "@tanstack/react-table"; -import { Edit, EllipsisVertical, Trash } from "lucide-react"; +import { Edit, EllipsisVertical } from "lucide-react"; interface ColumnProps { handleEdit: (district: MyDiscrictData) => void; @@ -15,7 +15,6 @@ interface ColumnProps { export const columnsDistrict = ({ handleEdit, - onDeleteClick, }: ColumnProps): ColumnDef[] => [ { accessorKey: "id", @@ -52,13 +51,13 @@ export const columnsDistrict = ({ > Tahrirlash - + */} ); diff --git a/src/features/doctor/lib/column.tsx b/src/features/doctor/lib/column.tsx index 35335c3..51597f5 100644 --- a/src/features/doctor/lib/column.tsx +++ b/src/features/doctor/lib/column.tsx @@ -7,7 +7,7 @@ import { DropdownMenuTrigger, } from "@/shared/ui/dropdown-menu"; import type { ColumnDef } from "@tanstack/react-table"; -import { Edit, EllipsisVertical, Eye, Trash } from "lucide-react"; +import { Edit, EllipsisVertical, Eye } from "lucide-react"; import type { NavigateFunction } from "react-router-dom"; interface Props { @@ -15,10 +15,7 @@ interface Props { onDeleteClick: (district: DoctorListData) => void; } -export const columns = ({ - router, - onDeleteClick, -}: Props): ColumnDef[] => [ +export const columns = ({ router }: Props): ColumnDef[] => [ { accessorKey: "id", header: () =>
, @@ -95,14 +92,14 @@ export const columns = ({ > Tahrirlash - + */} ); diff --git a/src/features/doctor/ui/Doctor.tsx b/src/features/doctor/ui/Doctor.tsx index 092829f..50fd9f4 100644 --- a/src/features/doctor/ui/Doctor.tsx +++ b/src/features/doctor/ui/Doctor.tsx @@ -11,19 +11,16 @@ import { DialogTitle, } from "@/shared/ui/dialog"; import { DashboardLayout } from "@/widgets/dashboard-layout/ui/DashboardLayout"; -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { AxiosError } from "axios"; -import { Loader2 } from "lucide-react"; +import { useQuery } from "@tanstack/react-query"; import { useState } from "react"; import { useNavigate } from "react-router-dom"; -import { toast } from "sonner"; import { doctor_api } from "../lib/api"; import { columns } from "../lib/column"; import { DataTable } from "../lib/data-table"; const Doctor = () => { const router = useNavigate(); - const queryClinent = useQueryClient(); + // const queryClinent = useQueryClient(); const { data, isLoading, isError, refetch } = useQuery({ queryKey: ["doctor_list"], queryFn: () => doctor_api.list(), @@ -32,41 +29,41 @@ const Doctor = () => { }, }); - const { mutate: deleted, isPending: deletedPending } = useMutation({ - mutationFn: ({ id }: { id: number }) => doctor_api.delete({ id }), - onSuccess: () => { - router("/physician"); - queryClinent.refetchQueries({ queryKey: ["doctor_list"] }); - setSelectedDistrict(null); - setDeleteDialog(false); - }, - onError: (error: AxiosError) => { - const data = error.response?.data as { message?: string }; - const errorData = error.response?.data as { - messages?: { - token_class: string; - token_type: string; - message: string; - }[]; - }; - const errorName = error.response?.data as { - data?: { - name: string[]; - }; - }; + // const { mutate: deleted, isPending: deletedPending } = useMutation({ + // mutationFn: ({ id }: { id: number }) => doctor_api.delete({ id }), + // onSuccess: () => { + // router("/physician"); + // queryClinent.refetchQueries({ queryKey: ["doctor_list"] }); + // setSelectedDistrict(null); + // setDeleteDialog(false); + // }, + // onError: (error: AxiosError) => { + // const data = error.response?.data as { message?: string }; + // const errorData = error.response?.data as { + // messages?: { + // token_class: string; + // token_type: string; + // message: string; + // }[]; + // }; + // const errorName = error.response?.data as { + // data?: { + // name: string[]; + // }; + // }; - const message = - Array.isArray(errorName.data?.name) && errorName.data.name.length - ? errorName.data.name[0] - : data?.message || - (Array.isArray(errorData?.messages) && errorData.messages.length - ? errorData.messages[0].message - : undefined) || - "Xatolik yuz berdi"; + // const message = + // Array.isArray(errorName.data?.name) && errorName.data.name.length + // ? errorName.data.name[0] + // : data?.message || + // (Array.isArray(errorData?.messages) && errorData.messages.length + // ? errorData.messages[0].message + // : undefined) || + // "Xatolik yuz berdi"; - toast.error(message); - }, - }); + // toast.error(message); + // }, + // }); const [deleteDialog, setDeleteDialog] = useState(false); const [selectedDistrict, setSelectedDistrict] = @@ -125,7 +122,7 @@ const Doctor = () => { - + */} diff --git a/src/features/home/ui/Home.tsx b/src/features/home/ui/Home.tsx index 58c23e8..bead137 100644 --- a/src/features/home/ui/Home.tsx +++ b/src/features/home/ui/Home.tsx @@ -4,6 +4,7 @@ import { useMutation } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import clsx from "clsx"; import { + AlertCircle, Banknote, Calendar, FileText, @@ -279,6 +280,23 @@ export default function Home() { + +
+ + +

Yordam

+ + + +

Tarqatilgan dorilar

+ +
); diff --git a/src/features/plan/lib/api.ts b/src/features/plan/lib/api.ts index 1c78040..061e425 100644 --- a/src/features/plan/lib/api.ts +++ b/src/features/plan/lib/api.ts @@ -21,8 +21,8 @@ export const plans_api = { return res; }, - async planIsDone(id: number) { - const res = await httpClient.post(`${PLANS}${id}/complite/`); + async planIsDone({ id, body }: { id: number; body: { comment: string } }) { + const res = await httpClient.post(`${PLANS}${id}/complite/`, body); return res; }, diff --git a/src/features/plan/lib/data.ts b/src/features/plan/lib/data.ts index 684d36e..ab810be 100644 --- a/src/features/plan/lib/data.ts +++ b/src/features/plan/lib/data.ts @@ -1,8 +1,15 @@ export interface CreatePlansReq { title: string; description: string; - date: string; // '2025-11-26' shu kabi jonatish kera apiga - is_done: boolean; + date: string; // "2025-12-05"; + doctor_id: number | null; + pharmacy_id: number | null; + longitude: number; + latitude: number; + extra_location: { + longitude: number; + latitude: number; + }; } export interface GetMyPlansRes { @@ -14,7 +21,12 @@ export interface GetMyPlansRes { title: string; description: string; date: string; - is_done: boolean; + comment: string | null; + doctor: null; + pharmacy: null; + longitude: number; + latitude: number; + extra_location: null; created_at: string; }[]; } @@ -24,6 +36,11 @@ export interface Task { title: string; description: string; date: string; - is_done: boolean; + comment: string | null; + doctor: null; + pharmacy: null; + longitude: number; + latitude: number; + extra_location: null; created_at: string; } diff --git a/src/features/plan/ui/PlanDetailsDialogProps.tsx b/src/features/plan/ui/PlanDetailsDialogProps.tsx index c238341..445ff63 100644 --- a/src/features/plan/ui/PlanDetailsDialogProps.tsx +++ b/src/features/plan/ui/PlanDetailsDialogProps.tsx @@ -5,10 +5,12 @@ import { DialogHeader, DialogTitle, } from "@/shared/ui/dialog"; +import { Textarea } from "@/shared/ui/textarea"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { AxiosError } from "axios"; import clsx from "clsx"; import { format } from "date-fns"; +import { useState } from "react"; import { toast } from "sonner"; import { plans_api } from "../lib/api"; @@ -17,7 +19,12 @@ interface Task { title: string; description: string; date: string; - is_done: boolean; + comment: string | null; + doctor: null; + pharmacy: null; + longitude: number; + latitude: number; + extra_location: null; created_at: string; } @@ -33,11 +40,17 @@ export function PlanDetailsDialog({ task, }: PlanDetailsDialogProps) { const queryClient = useQueryClient(); + const [commentOpen, setCommnetOpen] = useState(false); + const [commentText, setCommnetText] = useState(""); + const { mutate, isPending } = useMutation({ - mutationFn: (id: number) => plans_api.planIsDone(id), + mutationFn: ({ id, body }: { id: number; body: { comment: string } }) => + plans_api.planIsDone({ body, id }), onSuccess: () => { toast.success("Rejangiz bajarildi bo'lib o'zgardi"); onOpenChange(false); + setCommnetOpen(false); + setCommnetText(""); queryClient.refetchQueries({ queryKey: ["my_plans"] }); }, onError: (error: AxiosError) => { @@ -75,74 +88,105 @@ export function PlanDetailsDialog({ - {"Rejani ko'rish"} + {commentOpen ? "Reja qanday bajarildi ma'lumot" : "Rejani ko'rish"}
- {/* Status */} -
+ {!commentOpen && ( + <> + {/* Status */} +
+
+

Xolati

+

+ {task.comment ? "Tugallangan ✓" : "Bajarilmagan"} +

+
+
+ + {/* Title */} +
+

Sarlavha

+

+ {task.title} +

+
+ + {/* Description */} +
+

Tavsifi

+

+ {task.description} +

+
+ + {/* Date */} +
+

Sana

+

+ {format(task.date, "dd.MM.yyyy")} +

+
+ + )} + {commentOpen && (
-

Xolati

-

- {task.is_done ? "Tugallangan ✓" : "Bajarilmagan"} -

+