Files
meridyn-admin/src/features/specifications/ui/SpecificationDetail .tsx
Samandar Turgunboyev f7dbb665a0 apilar ulandi
2025-12-02 19:31:37 +05:00

199 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import type { OrderListDataRes } from "@/features/specifications/lib/data";
import formatPrice from "@/shared/lib/formatPrice";
import { Button } from "@/shared/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/shared/ui/dialog";
import { HardDriveDownloadIcon } from "lucide-react";
import type { Dispatch, SetStateAction } from "react";
interface Props {
specification: OrderListDataRes | null;
open: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
}
export const SpecificationDetail = ({
specification,
open,
setOpen,
}: Props) => {
const downloadFile = async (fileUrl: string, fileName: string) => {
try {
const response = await fetch(fileUrl, {
method: "GET",
headers: {
// Agar token kerak bo'lsa qo'shing
// Authorization: `Bearer ${yourToken}`,
},
});
if (!response.ok) {
throw new Error("Fayl yuklab olishda xatolik yuz berdi");
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName || "file.pdf"; // fayl nomi
document.body.appendChild(a);
a.click();
// Tozalash
a.remove();
window.URL.revokeObjectURL(url);
} catch (err) {
console.error(err);
}
};
if (!specification) return null;
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
<DialogHeader className="border-b pb-4">
<DialogTitle className="text-2xl font-bold text-gray-800">
Spetsifikatsiya tafsilotlari
</DialogTitle>
</DialogHeader>
<div className="space-y-6 mt-6">
{/* Asosiy ma'lumotlar - Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* Xaridor */}
<div className="bg-gradient-to-br from-blue-50 to-blue-100 rounded-lg p-4 border border-blue-200">
<p className="text-sm text-blue-600 font-medium mb-1">Xaridor</p>
<p className="text-lg font-semibold text-gray-800">
{specification.employee_name}
</p>
</div>
{/* Farmasevtika */}
<div className="bg-gradient-to-br from-green-50 to-green-100 rounded-lg p-4 border border-green-200">
<p className="text-sm text-green-600 font-medium mb-1">
Farmasevtika
</p>
<p className="text-lg font-semibold text-gray-800">
{specification.factory.name}
</p>
</div>
{/* Foydalanuvchi */}
<div className="bg-gradient-to-br from-purple-50 to-purple-100 rounded-lg p-4 border border-purple-200 md:col-span-2">
<p className="text-sm text-purple-600 font-medium mb-1">
Mas'ul xodim
</p>
<p className="text-lg font-semibold text-gray-800">
{specification.user.first_name} {specification.user.last_name}
</p>
</div>
</div>
{/* Dorilar ro'yxati */}
<div className="bg-gray-50 rounded-lg p-5 border border-gray-200">
<h3 className="text-lg font-bold text-gray-800 mb-4 flex items-center">
<span className="bg-indigo-600 text-white rounded-full w-8 h-8 flex items-center justify-center text-sm mr-3">
{specification.order_items.length}
</span>
Dorilar ro'yxati
</h3>
<div className="space-y-3">
{specification.order_items.map((med, index) => (
<div
key={med.id}
className="bg-white rounded-lg p-4 border border-gray-200 hover:border-indigo-300 transition-colors"
>
<div className="flex items-start justify-between">
<div className="flex-1">
<div className="flex items-center gap-2 mb-2">
<span className="bg-indigo-100 text-indigo-700 text-xs font-semibold px-2 py-1 rounded">
#{index + 1}
</span>
<p className="font-semibold text-gray-800">
{med.product}
</p>
</div>
<div className="flex items-center gap-4 text-sm text-gray-600">
<span>
Miqdor: <strong>{med.quantity} ta</strong>
</span>
<span>×</span>
<span>
Narx:{" "}
<strong>
{formatPrice(
Number(med.total_price) / med.quantity,
)}
</strong>
</span>
</div>
</div>
<div className="text-right ml-4">
<p className="text-xs text-gray-500 mb-1">Jami</p>
<p className="text-lg font-bold text-indigo-600">
{formatPrice(med.total_price)}
</p>
</div>
</div>
</div>
))}
</div>
</div>
{/* To'lov ma'lumotlari */}
<div className="bg-gradient-to-br from-slate-50 to-slate-100 rounded-lg p-5 border-2 border-slate-300">
<h3 className="text-lg font-bold text-gray-800 mb-4">
To'lov ma'lumotlari
</h3>
<div className="space-y-3">
<div className="flex justify-between items-center pb-3 border-b border-slate-300">
<span className="text-gray-600 font-medium">Jami narx:</span>
<span className="text-xl font-bold text-gray-800">
{formatPrice(specification.total_price)}
</span>
</div>
<div className="flex justify-between items-center pb-3 border-b border-slate-300">
<span className="text-gray-600 font-medium">
To'langan foizi:
</span>
<span className="text-lg font-semibold text-orange-600">
{specification.advance}%
</span>
</div>
<div className="flex justify-between items-center pt-2">
<span className="text-gray-700 font-bold text-lg">
To'langan:
</span>
<span className="text-2xl font-bold text-green-600">
{formatPrice(specification.paid_price)}
</span>
</div>
</div>
</div>
<Button
className="w-full h-12 bg-blue-600 text-md hover:bg-blue-700 cursor-pointer"
onClick={() =>
downloadFile(specification.file, `order-${specification.id}`)
}
>
<HardDriveDownloadIcon className="size-5" />
PDF faylda yuklab olish
</Button>
</div>
</DialogContent>
</Dialog>
);
};