diff --git a/public/shablon.jpg b/public/shablon.jpg new file mode 100644 index 0000000..d7586d9 Binary files /dev/null and b/public/shablon.jpg differ diff --git a/src/features/order/lib/type.ts b/src/features/order/lib/type.ts index 5fae92c..cb9c62d 100644 --- a/src/features/order/lib/type.ts +++ b/src/features/order/lib/type.ts @@ -1,5 +1,5 @@ export interface User { - id: string; + id: number; first_name: string; last_name: string; username: string; @@ -15,28 +15,30 @@ export interface Product { } export interface Item { - id: string; + id: number; quantity: number; price: number; - product: Product; + product: { + id: number; + name_uz: string; + name_ru: string; + price: number; + code: string; + unity: string; + }; } export interface Order { - id: string; - order_number: number; + id: number; status: string; total_price: number; - user: User; - payment_type: string; - delivery_type: string; delivery_price: number; - contact_number: string; comment: string; - name: string; + user: User; items: Item[]; created_at: string; - long: number | null; - lat: number | null; + long: number; + lat: number; } export interface OrdersResponse { diff --git a/src/features/order/ui/OrderDelete.tsx b/src/features/order/ui/OrderDelete.tsx index 1470e04..0aa13e2 100644 --- a/src/features/order/ui/OrderDelete.tsx +++ b/src/features/order/ui/OrderDelete.tsx @@ -55,8 +55,7 @@ const OrderDelete = ({ Buyurtmani o'chirish - Siz rostan ham {orderDelete?.order_number} sonli buyurtmani - o'chirmoqchimisiz? + Siz rostan ham {orderDelete?.id} sonli buyurtmani o'chirmoqchimisiz? diff --git a/src/features/order/ui/OrderDetail.tsx b/src/features/order/ui/OrderDetail.tsx index 42faaa6..8ce5fcf 100644 --- a/src/features/order/ui/OrderDetail.tsx +++ b/src/features/order/ui/OrderDetail.tsx @@ -1,25 +1,17 @@ import type { Order } from "@/features/order/lib/type"; -import formatPhone from "@/shared/lib/formatPhone"; +import formatDate from "@/shared/lib/formatDate"; +import formatPrice from "@/shared/lib/formatPrice"; import { Map, Placemark, YMaps } from "@pbe/react-yandex-maps"; import { Calendar, - CreditCard, MapIcon, MessageSquare, Package, - Phone, - Truck, User, X, } from "lucide-react"; import { type Dispatch, type SetStateAction } from "react"; -const deliveryTypeLabel: Record = { - YANDEX_GO: "Yandex Go", - DELIVERY_COURIES: "Kuryer orqali yetkazish", - PICKUP: "O‘zi olib ketish", -}; - interface Props { detail: boolean; setDetail: Dispatch>; @@ -29,20 +21,6 @@ interface Props { const OrderDetail = ({ detail, setDetail, order }: Props) => { if (!detail || !order) return null; - const formatDate = (dateString: string) => { - return new Date(dateString).toLocaleString("uz-UZ", { - year: "numeric", - month: "long", - day: "numeric", - hour: "2-digit", - minute: "2-digit", - }); - }; - - const formatPrice = (price: number) => { - return new Intl.NumberFormat("uz-UZ").format(price) + " so'm"; - }; - const getStatusColor = (status: string) => { const colors: Record = { pending: "bg-yellow-100 text-yellow-800", @@ -65,9 +43,6 @@ const OrderDetail = ({ detail, setDetail, order }: Props) => {
-

- Buyurtma #{order.order_number} -

ID: {order.id}

@@ -99,12 +74,6 @@ const OrderDetail = ({ detail, setDetail, order }: Props) => { {formatPrice(order.total_price)}

-
-

Yetkazish narxi

-

- {formatPrice(order.delivery_price)} -

-
@@ -116,36 +85,11 @@ const OrderDetail = ({ detail, setDetail, order }: Props) => {
Ism: - {order.name} -
-
- Telefon: - - - {formatPhone(order.contact_number)} - + {order.user.username}
-
-

- - Yetkazish ma'lumotlari -

-
-
- Turi: - - {deliveryTypeLabel[order.delivery_type] ?? - order.delivery_type} - -
-
-
{order.lat && order.long && (
@@ -172,16 +116,6 @@ const OrderDetail = ({ detail, setDetail, order }: Props) => { )}
-
-

- - To'lov turi -

-

- {order.payment_type === "CASH" ? "Naxt" : "Karta orqali"} -

-
- {order.comment && (

diff --git a/src/features/order/ui/OrderTable.tsx b/src/features/order/ui/OrderTable.tsx index 54fe1fc..219b423 100644 --- a/src/features/order/ui/OrderTable.tsx +++ b/src/features/order/ui/OrderTable.tsx @@ -2,7 +2,6 @@ import { order_api } from "@/features/order/lib/api"; import type { Order } from "@/features/order/lib/type"; -import formatPhone from "@/shared/lib/formatPhone"; import formatPrice from "@/shared/lib/formatPrice"; import { Button } from "@/shared/ui/button"; import { @@ -35,12 +34,6 @@ interface Props { setOrderDetail: Dispatch>; } -const deliveryTypeLabel: Record = { - YANDEX_GO: "Yandex Go", - DELIVERY_COURIES: "Kuryer orqali yetkazish", - PICKUP: "O‘zi olib ketish", -}; - type OrderStatus = | "NEW" // "PROCESSING" | @@ -113,11 +106,7 @@ const OrderTable = ({ # - Order № Foydalanuvchi - Kontakt - Toʻlov turi - Yetkazib berish Umumiy narx Izoh Holat @@ -129,18 +118,7 @@ const OrderTable = ({ {orders.map((order, index) => ( {index + 1} - {order.order_number} - - {order.user.first_name} {order.user.last_name} ( - {order.user.username}) - - {formatPhone(order.contact_number)} - - {order.payment_type === "CASH" ? "Naxt" : "Karta orqali"} - - - {deliveryTypeLabel[order.delivery_type] ?? order.delivery_type} - + {order.user.username} {formatPrice(order.total_price, true)} {order.comment || "-"} diff --git a/src/features/plans/lib/form.ts b/src/features/plans/lib/form.ts index 85d50bd..713c33f 100644 --- a/src/features/plans/lib/form.ts +++ b/src/features/plans/lib/form.ts @@ -5,8 +5,8 @@ export const createPlanFormData = z.object({ name_ru: z.string().min(1, "Majburiy maydon"), description_uz: z.string().min(1, "Majburiy maydon"), description_ru: z.string().min(1, "Majburiy maydon"), - category_id: z.string().uuid("Kategoriya noto‘g‘ri"), - unity_id: z.string().uuid("Birlik noto‘g‘ri"), + category_id: z.string(), + unity_id: z.string(), price: z.number().positive("Narx noto‘g‘ri"), quantity_left: z.number().min(0), min_quantity: z.number().min(0), diff --git a/src/features/plans/ui/ExcelUpload.tsx b/src/features/plans/ui/ExcelUpload.tsx new file mode 100644 index 0000000..34c6cf5 --- /dev/null +++ b/src/features/plans/ui/ExcelUpload.tsx @@ -0,0 +1,51 @@ +"use client"; + +import { Button } from "@/shared/ui/button"; +import { useRef } from "react"; + +export default function ExcelUpload() { + const fileInputRef = useRef(null); + + const handleButtonClick = () => { + fileInputRef.current?.click(); + }; + + const handleFileChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + // Excel format tekshiruvi + const allowedTypes = [ + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ]; + + if (!allowedTypes.includes(file.type)) { + alert("Iltimos, faqat Excel (.xls, .xlsx) fayl yuklang"); + return; + } + + // 👉 shu yerda backendga yuborasiz + // uploadExcel(file) + }; + + return ( + <> + + + + + ); +} diff --git a/src/features/plans/ui/FilterPlans.tsx b/src/features/plans/ui/FilterPlans.tsx index 458c7d3..381516c 100644 --- a/src/features/plans/ui/FilterPlans.tsx +++ b/src/features/plans/ui/FilterPlans.tsx @@ -1,5 +1,6 @@ import type { Product } from "@/features/plans/lib/data"; import AddedPlan from "@/features/plans/ui/AddedPlan"; +import ExcelUpload from "@/features/plans/ui/ExcelUpload"; import { Button } from "@/shared/ui/button"; import { Dialog, @@ -9,7 +10,7 @@ import { DialogTrigger, } from "@/shared/ui/dialog"; import { Input } from "@/shared/ui/input"; -import { Plus } from "lucide-react"; +import { AlertCircle, Plus } from "lucide-react"; import type { Dispatch, SetStateAction } from "react"; interface Props { @@ -38,6 +39,30 @@ const FilterPlans = ({ value={searchUser} onChange={(e) => setSearchUser(e.target.value)} /> + + + + + + + Excel uchun kerakli shablon + + +
+ +

+ Excel shu ko'rinishda bo'lishi kerak aks holda mahsulot qo'shishda + xatolik yuz berishi mumkin. +

+
+
+
+