feat: Update glasses
This commit is contained in:
parent
568458e098
commit
4fb39ab9fa
@ -22,6 +22,12 @@ import DataWrapper from "@/components/customs/DataWrapper";
|
|||||||
import Table from "@/components/customs/custom-table";
|
import Table from "@/components/customs/custom-table";
|
||||||
import CustomButton from "@/components/customs/custom-button";
|
import CustomButton from "@/components/customs/custom-button";
|
||||||
import Pagination from "@/components/customs/custom-pagination";
|
import Pagination from "@/components/customs/custom-pagination";
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipProvider,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from "@radix-ui/react-tooltip";
|
||||||
|
|
||||||
const DetailConsultation = () => {
|
const DetailConsultation = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@ -178,7 +184,7 @@ const DetailConsultation = () => {
|
|||||||
|
|
||||||
<GridColumn col={3}>
|
<GridColumn col={3}>
|
||||||
{/* ID PHIÊN KHÁM */}
|
{/* ID PHIÊN KHÁM */}
|
||||||
<div className="space-y-1">
|
{/* <div className="space-y-1">
|
||||||
<p className="text-[14px] font-medium text-[#697586]">
|
<p className="text-[14px] font-medium text-[#697586]">
|
||||||
ID PHIÊN KHÁM
|
ID PHIÊN KHÁM
|
||||||
</p>
|
</p>
|
||||||
@ -186,7 +192,7 @@ const DetailConsultation = () => {
|
|||||||
<p className="text-[15px] font-medium text-[#202939]">
|
<p className="text-[15px] font-medium text-[#202939]">
|
||||||
{consultation.id}
|
{consultation.id}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div> */}
|
||||||
|
|
||||||
{/* MÃ PHIÊN KHÁM */}
|
{/* MÃ PHIÊN KHÁM */}
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
@ -330,14 +336,36 @@ const DetailConsultation = () => {
|
|||||||
<p className="text-[14px] font-medium text-[#697586]">
|
<p className="text-[14px] font-medium text-[#697586]">
|
||||||
FILE UPLOAD
|
FILE UPLOAD
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{consultation.generalAttachmentUrls?.length > 0 ? (
|
{consultation.generalAttachmentUrls?.length > 0 ? (
|
||||||
<ul className="space-y-2">
|
<TooltipProvider>
|
||||||
{consultation.generalAttachmentUrls.map((item, index) => {
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-600 transition hover:bg-blue-100">
|
||||||
|
<span>📎</span>
|
||||||
|
<span>Chi tiết các file</span>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
|
||||||
|
<TooltipContent
|
||||||
|
side="bottom"
|
||||||
|
align="start"
|
||||||
|
className="w-[350px] rounded-xl border bg-white p-4 shadow-xl"
|
||||||
|
>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h4 className="text-sm font-semibold text-gray-800">
|
||||||
|
Danh sách file đính kèm
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<div className="max-h-[300px] space-y-2 overflow-y-auto">
|
||||||
|
{consultation.generalAttachmentUrls.map(
|
||||||
|
(item, index) => {
|
||||||
const file = getFileInfo(item, index);
|
const file = getFileInfo(item, index);
|
||||||
|
|
||||||
const extension =
|
const extension =
|
||||||
file.fileName.split(".").pop()?.toLowerCase() || "";
|
file.fileName
|
||||||
|
.split(".")
|
||||||
|
.pop()
|
||||||
|
?.toLowerCase() || "";
|
||||||
|
|
||||||
const isImage = [
|
const isImage = [
|
||||||
"jpg",
|
"jpg",
|
||||||
@ -350,33 +378,43 @@ const DetailConsultation = () => {
|
|||||||
].includes(extension);
|
].includes(extension);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={index}>
|
|
||||||
{isImage ? (
|
|
||||||
<a
|
<a
|
||||||
|
key={index}
|
||||||
href={file.path}
|
href={file.path}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-blue-500 hover:underline"
|
className="flex items-center justify-between rounded-lg border border-gray-200 p-3 transition hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
🖼️ {file.fileName}
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
</a>
|
<span className="text-xl">
|
||||||
) : (
|
{isImage ? "🖼️" : "📄"}
|
||||||
<a
|
</span>
|
||||||
href={file.path}
|
|
||||||
download={file.fileName}
|
<div className="min-w-0">
|
||||||
className="text-green-600 hover:underline"
|
<p className="truncate text-sm font-medium text-gray-800">
|
||||||
>
|
{file.fileName}
|
||||||
📄 {file.fileName}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
) : (
|
|
||||||
<p className="text-gray-500">
|
|
||||||
Không có file nào được tải lên.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 uppercase">
|
||||||
|
{extension || "FILE"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="text-xs text-blue-500">
|
||||||
|
Mở
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
) : (
|
||||||
|
<div>Không có file nào được tải lên</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -408,7 +446,7 @@ const DetailConsultation = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
state: TYPE_STATUS.PendingPrescription,
|
state: TYPE_STATUS.PendingPrescription,
|
||||||
text: "Chờ nhận thuốc/kính",
|
text: "Chờ nhận thuốc",
|
||||||
textColor: "#9A3412",
|
textColor: "#9A3412",
|
||||||
backgroundColor: "#FED7AA",
|
backgroundColor: "#FED7AA",
|
||||||
},
|
},
|
||||||
@ -560,17 +598,37 @@ const DetailConsultation = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<p className="text-[14px] font-medium text-[#697586]">
|
<p className="text-sm font-medium uppercase tracking-wide text-[#697586]">
|
||||||
FILE UPLOAD
|
FILE UPLOAD
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{selectedSpecialty.attachmentUrls?.length > 0 ? (
|
{selectedSpecialty.attachmentUrls?.length > 0 ? (
|
||||||
<ul className="space-y-2">
|
<TooltipProvider>
|
||||||
{selectedSpecialty.attachmentUrls.map((item, index) => {
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-600 transition hover:bg-blue-100">
|
||||||
|
<span>📎</span>
|
||||||
|
<span>Chi tiết các file</span>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
|
||||||
|
<TooltipContent
|
||||||
|
side="bottom"
|
||||||
|
align="start"
|
||||||
|
className="w-[350px] rounded-xl border bg-white p-4 shadow-xl"
|
||||||
|
>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h4 className="text-sm font-semibold text-gray-800">
|
||||||
|
Danh sách file đính kèm
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<div className="max-h-[300px] space-y-2 overflow-y-auto">
|
||||||
|
{selectedSpecialty.attachmentUrls.map(
|
||||||
|
(item, index) => {
|
||||||
const file = getFileInfo(item, index);
|
const file = getFileInfo(item, index);
|
||||||
|
|
||||||
const extension =
|
const extension =
|
||||||
file.fileName.split(".").pop()?.toLowerCase() || "";
|
file.fileName.split(".").pop()?.toLowerCase() ||
|
||||||
|
"";
|
||||||
|
|
||||||
const isImage = [
|
const isImage = [
|
||||||
"jpg",
|
"jpg",
|
||||||
@ -583,31 +641,43 @@ const DetailConsultation = () => {
|
|||||||
].includes(extension);
|
].includes(extension);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={index}>
|
|
||||||
{isImage ? (
|
|
||||||
<a
|
<a
|
||||||
|
key={index}
|
||||||
href={file.path}
|
href={file.path}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-blue-500 hover:underline"
|
className="flex items-center justify-between rounded-lg border border-gray-200 p-3 transition hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
🖼️ {file.fileName}
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
|
<span className="text-xl">
|
||||||
|
{isImage ? "🖼️" : "📄"}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div className="min-w-0">
|
||||||
|
<p className="truncate text-sm font-medium text-gray-800">
|
||||||
|
{file.fileName}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="text-xs text-gray-500 uppercase">
|
||||||
|
{extension || "FILE"}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span className="text-xs text-blue-500">
|
||||||
|
Mở
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
) : (
|
|
||||||
<a
|
|
||||||
href={file.path}
|
|
||||||
download={file.fileName}
|
|
||||||
className="text-green-600 hover:underline"
|
|
||||||
>
|
|
||||||
📄 {file.fileName}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
);
|
);
|
||||||
})}
|
},
|
||||||
</ul>
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-gray-500">Không có file nào được tải lên.</p>
|
<div>Không có file nào được tải lên</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -624,6 +694,20 @@ const DetailConsultation = () => {
|
|||||||
|
|
||||||
<p>{selectedSpecialty.glassType || "---"}</p>
|
<p>{selectedSpecialty.glassType || "---"}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-[#697586]">ĐÃ PHÁT KÍNH CHƯA</p>
|
||||||
|
|
||||||
|
{selectedSpecialty.isGlassesDelivered ? (
|
||||||
|
<p className="bg-[#DCFCE7] text-[#166534] p-2 border rounded-full w-fit">
|
||||||
|
Đã phát kính
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<p className="bg-[#fee2e2] text-[#991B1B] p-2 border rounded-full w-fit">
|
||||||
|
Chưa phát kính
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</GridColumn>
|
</GridColumn>
|
||||||
|
|||||||
@ -542,7 +542,7 @@ const MainPageConsultation = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
state: TYPE_STATUS.PendingPrescription,
|
state: TYPE_STATUS.PendingPrescription,
|
||||||
text: "Chờ nhận thuốc/kính",
|
text: "Chờ nhận thuốc",
|
||||||
textColor: "#9A3412",
|
textColor: "#9A3412",
|
||||||
backgroundColor: "#FED7AA",
|
backgroundColor: "#FED7AA",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -36,6 +36,7 @@ const UpdateSpecialtyClinicId = () => {
|
|||||||
procedureNotes: string;
|
procedureNotes: string;
|
||||||
glassRequired: boolean;
|
glassRequired: boolean;
|
||||||
glassType: string;
|
glassType: string;
|
||||||
|
isGlassesDelivered: boolean;
|
||||||
fileUrls: string[];
|
fileUrls: string[];
|
||||||
}>({
|
}>({
|
||||||
specialtyAssignmentId: "",
|
specialtyAssignmentId: "",
|
||||||
@ -44,6 +45,7 @@ const UpdateSpecialtyClinicId = () => {
|
|||||||
procedureNotes: "",
|
procedureNotes: "",
|
||||||
glassRequired: false,
|
glassRequired: false,
|
||||||
glassType: "",
|
glassType: "",
|
||||||
|
isGlassesDelivered: false,
|
||||||
fileUrls: [],
|
fileUrls: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -113,6 +115,7 @@ const UpdateSpecialtyClinicId = () => {
|
|||||||
procedureNotes: specialtyClinic.procedureNotes || "",
|
procedureNotes: specialtyClinic.procedureNotes || "",
|
||||||
glassRequired: specialtyClinic.glassRequired || false,
|
glassRequired: specialtyClinic.glassRequired || false,
|
||||||
glassType: specialtyClinic.glassType || "",
|
glassType: specialtyClinic.glassType || "",
|
||||||
|
isGlassesDelivered: specialtyClinic.isGlassesDelivered || false,
|
||||||
fileUrls: specialtyClinic.attachmentUrls || [],
|
fileUrls: specialtyClinic.attachmentUrls || [],
|
||||||
});
|
});
|
||||||
setImages(
|
setImages(
|
||||||
@ -145,6 +148,7 @@ const UpdateSpecialtyClinicId = () => {
|
|||||||
procedureNotes: form.procedureNotes,
|
procedureNotes: form.procedureNotes,
|
||||||
glassRequired: isEyeClinic ? form.glassRequired : false,
|
glassRequired: isEyeClinic ? form.glassRequired : false,
|
||||||
glassType: isEyeClinic ? form.glassType : "",
|
glassType: isEyeClinic ? form.glassType : "",
|
||||||
|
isGlassesDelivered: isEyeClinic ? form.isGlassesDelivered : false,
|
||||||
fileUrls: body.paths,
|
fileUrls: body.paths,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -360,6 +364,7 @@ const UpdateSpecialtyClinicId = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{form.glassRequired && (
|
{form.glassRequired && (
|
||||||
|
<div>
|
||||||
<div className="mt-2 animate-fadeIn ">
|
<div className="mt-2 animate-fadeIn ">
|
||||||
<TextArea
|
<TextArea
|
||||||
name="glassType"
|
name="glassType"
|
||||||
@ -371,6 +376,45 @@ const UpdateSpecialtyClinicId = () => {
|
|||||||
max={5000}
|
max={5000}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="text-sm font-medium text-gray-700">
|
||||||
|
Đã phát kính chưa
|
||||||
|
</label>
|
||||||
|
<div className="mt-2.5 flex items-center gap-8">
|
||||||
|
<label className="flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-900">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="isGlassesDelivered"
|
||||||
|
className="h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
|
||||||
|
checked={form.isGlassesDelivered === true}
|
||||||
|
onChange={() =>
|
||||||
|
setForm((prev) => ({
|
||||||
|
...prev,
|
||||||
|
isGlassesDelivered: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Đã phát kính
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label className="flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-900">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="isGlassesDelivered"
|
||||||
|
className="h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
|
||||||
|
checked={form.isGlassesDelivered === false}
|
||||||
|
onChange={() =>
|
||||||
|
setForm((prev) => ({
|
||||||
|
...prev,
|
||||||
|
isGlassesDelivered: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
Chưa phát kính
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { Users, Stethoscope, Pill } from "lucide-react";
|
import { Users, Stethoscope, Pill, Glasses } from "lucide-react";
|
||||||
|
|
||||||
import Table from "@/components/customs/custom-table";
|
import Table from "@/components/customs/custom-table";
|
||||||
import DataWrapper from "@/components/customs/DataWrapper";
|
import DataWrapper from "@/components/customs/DataWrapper";
|
||||||
@ -116,6 +116,18 @@ const MainPageStatistical = () => {
|
|||||||
{report?.totalPrescriptionsIssued || 0}
|
{report?.totalPrescriptionsIssued || 0}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-xl bg-white p-5 shadow">
|
||||||
|
<div className="mb-3 flex items-center justify-between">
|
||||||
|
<Glasses size={22} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="text-sm text-gray-500">Số kính đã phát</p>
|
||||||
|
|
||||||
|
<h3 className="mt-2 text-3xl font-bold">
|
||||||
|
{report?.totalGlassesDelivered || 0}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* BẢNG THỐNG KÊ */}
|
{/* BẢNG THỐNG KÊ */}
|
||||||
@ -177,10 +189,10 @@ const MainPageStatistical = () => {
|
|||||||
<strong> {report?.totalPrescriptionsIssued || 0}</strong> đơn.
|
<strong> {report?.totalPrescriptionsIssued || 0}</strong> đơn.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* <p>
|
<p>
|
||||||
Số suất quà được phát:
|
Tổng số kính đã phát:
|
||||||
<strong> {report?.totalGiftPackagesIssued || 0}</strong> suất.
|
<strong> {report?.totalGlassesDelivered || 0}</strong> cái.
|
||||||
</p> */}
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -89,6 +89,7 @@ export interface ConsultationDetail {
|
|||||||
procedureNotes: string | null;
|
procedureNotes: string | null;
|
||||||
glassRequired: boolean | null;
|
glassRequired: boolean | null;
|
||||||
glassType: string | null;
|
glassType: string | null;
|
||||||
|
isGlassesDelivered: boolean;
|
||||||
examinerName: string;
|
examinerName: string;
|
||||||
specialtyStatus: string | number | undefined;
|
specialtyStatus: string | number | undefined;
|
||||||
attachmentUrls: string[];
|
attachmentUrls: string[];
|
||||||
@ -133,6 +134,7 @@ export interface ReportResponse {
|
|||||||
totalCases: number;
|
totalCases: number;
|
||||||
}[];
|
}[];
|
||||||
totalPrescriptionsIssued: number;
|
totalPrescriptionsIssued: number;
|
||||||
|
totalGlassesDelivered: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const consultationServices = {
|
const consultationServices = {
|
||||||
@ -220,6 +222,7 @@ const consultationServices = {
|
|||||||
procedureNotes: string;
|
procedureNotes: string;
|
||||||
glassRequired: boolean;
|
glassRequired: boolean;
|
||||||
glassType: string;
|
glassType: string;
|
||||||
|
isGlassesDelivered: boolean;
|
||||||
fileUrls: string[];
|
fileUrls: string[];
|
||||||
},
|
},
|
||||||
tokenAxios?: any,
|
tokenAxios?: any,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user