перенес компоненты для страницы с выдачей линзы

This commit is contained in:
Андрей Дувакин 2025-04-05 23:08:14 +05:00
parent a5a6d1d7fa
commit bd1ba09b08
7 changed files with 490 additions and 346 deletions

View File

@ -0,0 +1,245 @@
import {
Modal, Input, Button, Typography, Collapse, Steps, Row, Alert, Col, DatePicker, Spin
} from "antd";
import PropTypes from "prop-types";
import useLensIssueFormModal from "./useLensIssueFormModal.js";
import useLensIssueFormModalUI from "./useLensIssueFormModalUI.js";
const LensIssueFormModal = ({visible, onCancel, onSubmit}) => {
const lensIssueFormModalData = useLensIssueFormModal();
const lensIssueFormModalUI = useLensIssueFormModalUI(visible, onCancel, onSubmit, lensIssueFormModalData.patients, lensIssueFormModalData.lenses);
const patientsItems = lensIssueFormModalUI.filteredPatients.map((patient) => ({
key: patient.id,
label: `${patient.last_name} ${patient.first_name} (${lensIssueFormModalUI.getDateString(patient.birthday)})`,
children: <div>
<p><b>Пациент:</b> {patient.last_name} {patient.first_name}</p>
<p><b>Дата рождения:</b> {lensIssueFormModalUI.getDateString(patient.birthday)}</p>
<p><b>Диагноз:</b> {patient.diagnosis}</p>
<p><b>Email:</b> {patient.email}</p>
<p><b>Телефон:</b> {patient.phone}</p>
<Button type="primary" onClick={() => lensIssueFormModalUI.setSelectedPatient(patient)}>Выбрать</Button>
</div>,
}));
const lensesItems = lensIssueFormModalUI.filteredLenses.map((lens) => ({
key: lens.id, label: `Линза ${lens.side} ${lens.diameter} мм`, children: <div>
<p><b>Диаметр:</b> {lens.diameter}</p>
<p><b>Тор:</b> {lens.tor}</p>
<p><b>Пресетная рефракция:</b> {lens.preset_refraction}</p>
<p><b>Диаметр:</b> {lens.diameter}</p>
<p><b>FVC:</b> {lens.fvc}</p>
<p><b>Острота зрения (Trial):</b> {lens.trial}</p>
<p><b>Периферийная торичность:</b> {lens.periphery_toricity}</p>
<p><b>Сторона:</b> {lens.side}</p>
<p><b>Esa:</b> {lens.esa}</p>
<Button type="primary" onClick={() => lensIssueFormModalUI.setSelectedLens(lens)}>Выбрать</Button>
</div>,
}));
const SelectPatientStep = () => {
return lensIssueFormModalUI.selectedPatient ? (
<div style={lensIssueFormModalUI.blockStepStyle}>
<Typography.Text strong>
{lensIssueFormModalUI.selectedPatient.last_name} {lensIssueFormModalUI.selectedPatient.first_name}
</Typography.Text>
<p><b>Дата
рождения:</b> {lensIssueFormModalUI.getSelectedPatientBirthdayString()}
</p>
<p><b>Email:</b> {lensIssueFormModalUI.selectedPatient.email}</p>
<p><b>Телефон:</b> {lensIssueFormModalUI.selectedPatient.phone}</p>
<Button
type="primary"
onClick={lensIssueFormModalUI.resetPatient}
danger
>
Выбрать другого пациента
</Button>
</div>
) : (
<>
<Input
placeholder="Поиск пациента"
value={lensIssueFormModalUI.searchPatientString}
onChange={lensIssueFormModalUI.handleSetSearchPatientString}
style={lensIssueFormModalUI.searchInputStyle}
allowClear
/>
<div style={lensIssueFormModalUI.chooseContainerStyle}>
<Collapse
items={patientsItems}
/>
</div>
</>
);
};
const SelectLensStep = () => {
return lensIssueFormModalUI.selectedLens ? (
<div style={lensIssueFormModalUI.blockStepStyle}>
<Typography.Text strong>
{lensIssueFormModalUI.selectedLens.diameter} {lensIssueFormModalUI.selectedLens.tor} {lensIssueFormModalUI.selectedLens.preset_refraction}
</Typography.Text>
<p><b>Диаметр:</b> {lensIssueFormModalUI.selectedLens.diameter}</p>
<p><b>Тор:</b> {lensIssueFormModalUI.selectedLens.tor}</p>
<p><b>Пресетная рефракция:</b> {lensIssueFormModalUI.selectedLens.preset_refraction}</p>
<p><b>Диаметр:</b> {lensIssueFormModalUI.selectedLens.diameter}</p>
<p><b>FVC:</b> {lensIssueFormModalUI.selectedLens.fvc}</p>
<p><b>Острота зрения (Trial):</b> {lensIssueFormModalUI.selectedLens.trial}</p>
<p><b>Периферийная торичность:</b> {lensIssueFormModalUI.selectedLens.periphery_toricity}</p>
<p><b>Сторона:</b> {lensIssueFormModalUI.selectedLens.side}</p>
<p><b>Esa:</b> {lensIssueFormModalUI.selectedLens.esa}</p>
<Button
type="primary"
onClick={lensIssueFormModalUI.resetLens}
danger
>
Выбрать другую линзу
</Button>
</div>) : (<>
<Input
placeholder="Поиск линз"
value={lensIssueFormModalUI.searchLensString}
onChange={lensIssueFormModalUI.handleSetSearchLensString}
style={lensIssueFormModalUI.searchInputStyle}
allowClear
/>
<div style={lensIssueFormModalUI.chooseContainerStyle}>
<Collapse
items={lensesItems}
/>
</div>
</>
);
};
const ConfirmStep = () => {
return (
<>
<Alert
type="warning"
message="Внимание! После подтверждения линза будет считаться выданной, данное действие нельзя будет отменить."
style={lensIssueFormModalUI.alertStyle}
/>
<Row style={lensIssueFormModalUI.blockStepStyle}
gutter={[16, 16]}>
<Col xs={24} md={16} style={lensIssueFormModalUI.issueDateContainerStyle}>
<Typography.Text strong>
Дата выдачи: {lensIssueFormModalUI.issueDate?.toDate().toLocaleDateString("ru-RU")}
</Typography.Text>
</Col>
<Col xs={24} md={8}>
<DatePicker
placeholder={"Дата выдачи"}
value={lensIssueFormModalUI.issueDate}
onChange={(date) => lensIssueFormModalUI.setIssueDate(date)}
format="DD.MM.YYYY"
style={lensIssueFormModalUI.datePickerStyle}
/>
</Col>
</Row>
<div style={lensIssueFormModalUI.blockStepStyle}>
<Typography.Text strong>
{lensIssueFormModalUI.selectedPatient.last_name} {lensIssueFormModalUI.selectedPatient.first_name}
</Typography.Text>
<p><b>Дата
рождения:</b> {lensIssueFormModalUI.getSelectedPatientBirthdayString()}
</p>
<p><b>Email:</b> {lensIssueFormModalUI.selectedPatient.email}</p>
<p><b>Телефон:</b> {lensIssueFormModalUI.selectedPatient.phone}</p>
<p>
<b>Линза:</b> {lensIssueFormModalUI.selectedLens.diameter} {lensIssueFormModalUI.selectedLens.tor} {lensIssueFormModalUI.selectedLens.preset_refraction}
</p>
</div>
<div style={lensIssueFormModalUI.blockStepStyle}>
<Typography.Text strong>
{lensIssueFormModalUI.selectedLens.diameter} {lensIssueFormModalUI.selectedLens.tor} {lensIssueFormModalUI.selectedLens.preset_refraction}
</Typography.Text>
<p><b>Диаметр:</b> {lensIssueFormModalUI.selectedLens.diameter}</p>
<p><b>Тор:</b> {lensIssueFormModalUI.selectedLens.tor}</p>
<p><b>Пресетная рефракция:</b> {lensIssueFormModalUI.selectedLens.preset_refraction}</p>
<p><b>Диаметр:</b> {lensIssueFormModalUI.selectedLens.diameter}</p>
<p><b>FVC:</b> {lensIssueFormModalUI.selectedLens.fvc}</p>
<p><b>Острота зрения (Trial):</b> {lensIssueFormModalUI.selectedLens.trial}</p>
<p><b>Периферийная торичность:</b> {lensIssueFormModalUI.selectedLens.periphery_toricity}</p>
<p><b>Сторона:</b> {lensIssueFormModalUI.selectedLens.side}</p>
<p><b>Esa:</b> {lensIssueFormModalUI.selectedLens.esa}</p>
</div>
</>
);
};
const steps = [{
title: 'Выбор пациента', content: <SelectPatientStep/>,
}, {
title: 'Выбор линзы', content: <SelectLensStep/>,
}, {
title: 'Подтверждение', content: <ConfirmStep/>,
}];
return (
<Modal
title="Выдача линзы пациенту"
open={visible}
onCancel={lensIssueFormModalUI.cancelModal}
footer={null}
maskClosable={false}
width={lensIssueFormModalUI.modalWidth}
centered
>
{lensIssueFormModalData.loading ? (
<div style={lensIssueFormModalUI.loadingContainerStyle}>
<Spin size="large"/>
</div>
) : (
<div style={lensIssueFormModalUI.stepsContentStyle}>
{steps[lensIssueFormModalUI.currentStep].content}
</div>
)}
{lensIssueFormModalUI.screenXS && (
<Steps
current={lensIssueFormModalUI.currentStep}
items={steps}
style={lensIssueFormModalUI.stepsIndicatorStyle}
direction={lensIssueFormModalUI.direction}
/>
)}
<Row
justify="end"
style={lensIssueFormModalUI.footerRowStyle}
gutter={[8, 8]}
>
<Button
style={lensIssueFormModalUI.footerButtonStyle}
onClick={lensIssueFormModalUI.handleClickBackButton}
disabled={lensIssueFormModalUI.disableBackButton}
>
Назад
</Button>
<Button
type="primary"
onClick={lensIssueFormModalUI.handleClickNextButton}
disabled={lensIssueFormModalUI.disableNextButton}
>
{lensIssueFormModalUI.nextButtonText}
</Button>
</Row>
</Modal>
);
};
LensIssueFormModal.propTypes = {
visible: PropTypes.bool.isRequired,
onCancel: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
export default LensIssueFormModal;

View File

@ -0,0 +1,17 @@
import {useGetPatientsQuery} from "../../../../../Api/patientsApi.js";
import {useGetLensesQuery} from "../../../../../Api/lensesApi.js";
const useLensIssueFormModal = () => {
const {data: patients = [], isLoading: isLoadingPatients, isError: isErrorPatients} = useGetPatientsQuery(undefined);
const {data: lenses = [], isLoading: isLoadingLenses, isError: isErrorLenses} = useGetLensesQuery(undefined);
return {
patients,
lenses,
isLoading: isLoadingPatients || isLoadingLenses,
isError: isErrorPatients || isErrorLenses,
};
};
export default useLensIssueFormModal;

View File

@ -0,0 +1,198 @@
import {useMemo, useState} from "react";
import dayjs from "dayjs";
import {Grid, notification} from "antd";
const {useBreakpoint} = Grid;
const useLensIssueFormModalUI = (visible, onCancel, onSubmit, patients, lenses) => {
const screens = useBreakpoint();
const [searchPatientString, setSearchPatientString] = useState("");
const [searchLensString, setSearchLensString] = useState("");
const [issueDate, setIssueDate] = useState(dayjs(new Date()));
const [selectedPatient, setSelectedPatient] = useState(null);
const [selectedLens, setSelectedLens] = useState(null);
const [currentStep, setCurrentStep] = useState(0);
const blockStepStyle = {padding: "10px", background: "#f5f5f5", borderRadius: 5, marginBottom: 15};
const searchInputStyle = {marginBottom: 16};
const chooseContainerStyle = {maxHeight: 300, overflowY: "auto", border: "1px solid #d9d9d9", padding: 8};
const alertStyle = {marginBottom: 15};
const issueDateContainerStyle = {display: "flex", alignItems: "center"};
const datePickerStyle = {width: "100%"};
const loadingContainerStyle = {display: "flex", justifyContent: "center", alignItems: "center", height: "70vh"};
const stepsContentStyle = {maxHeight: "70vh", overflowY: "auto", padding: "10px"};
const stepsIndicatorStyle = {marginTop: 16};
const footerRowStyle = {marginTop: 20};
const footerButtonStyle = {marginRight: 8};
const filteredPatients = useMemo(() => patients.filter((patient) => {
const searchLower = searchPatientString.toLowerCase();
return Object.values(patient)
.filter(value => typeof value === "string")
.some(value => value.toLowerCase().includes(searchLower));
}), [patients, searchPatientString]);
const filteredLenses = useMemo(() => lenses.filter((lens) => {
const searchLower = searchLensString.toLowerCase();
return Object.values(lens)
.some(value => value.toString().toLowerCase().includes(searchLower));
}), [lenses, searchLensString]);
const resetPatient = () => setSelectedPatient(null);
const resetLens = () => setSelectedLens(null);
const screenXS = useMemo(() => screens.xs, [screens]);
const direction = useMemo(() => screenXS ? "horizontal" : "vertical", [screenXS]);
const modalWidth = useMemo(() => screenXS ? 700 : "90%", [screenXS]);
const nextButtonText = useMemo(() => {
if (currentStep === 2) {
return "Создать";
} else {
return "Далее";
}
}, [currentStep]);
const handleSetSearchPatientString = (e) => setSearchPatientString(e.target.value);
const handleSetSearchLensString = (e) => setSearchLensString(e.target.value);
const handleOk = async () => {
try {
setCurrentStep(0);
onSubmit(issueDate.format("YYYY-MM-DD"), selectedPatient.id, selectedLens.id);
setSelectedPatient(null);
setSelectedLens(null);
setIssueDate(dayjs(new Date()));
} catch (errorInfo) {
console.error("Validation Failed:", errorInfo);
notification.error({
message: "Ошибка валидации",
description: "Проверьте правильность заполнения полей.",
placement: "topRight",
});
}
};
const isActiveNextButton = useMemo(() => {
if (currentStep === 0 && !selectedPatient) {
return false;
}
return !(currentStep === 1 && !selectedLens);
}, [currentStep, selectedPatient, selectedLens]);
const isActivePrevButton = useMemo(() => {
return currentStep > 0;
}, [currentStep]);
const cancelModal = () => {
setSelectedPatient(null);
setSelectedLens(null);
setCurrentStep(0);
setIssueDate(dayjs(new Date()));
onCancel();
};
const handleClickBackButton = () => {
setCurrentStep(currentStep - 1);
};
const isActiveFinishButton = useMemo(() => {
return currentStep === 2;
}, [currentStep]);
const handleClickNextButton = async () => {
if (isActiveFinishButton) {
if (!validateIssue()) {
notification.error({
message: "Ошибка валидации",
description: "Проверьте правильность заполнения полей.",
placement: "topRight",
});
return;
}
await handleOk().then(reset);
} else {
setCurrentStep(currentStep + 1);
}
};
const validateIssue = () => {
return issueDate && selectedPatient && selectedLens;
};
const getDateString = (date) => {
return new Date(date).toLocaleDateString('ru-RU');
};
const getSelectedPatientBirthdayString = () => {
if (!selectedPatient) {
return "";
}
return getDateString(selectedPatient.birthday);
};
const reset = () => {
setSelectedPatient(null);
setSelectedLens(null);
setCurrentStep(0);
setIssueDate(dayjs(new Date()));
};
const disableBackButton = useMemo(() => !isActivePrevButton, [isActivePrevButton]);
const disableNextButton = useMemo(() => !isActiveNextButton && !isActiveFinishButton, [isActiveFinishButton, isActiveNextButton]);
return {
filteredPatients,
filteredLenses,
searchPatientString,
setSearchPatientString,
searchLensString,
setSearchLensString,
issueDate,
setIssueDate,
selectedPatient,
setSelectedPatient,
selectedLens,
setSelectedLens,
currentStep,
setCurrentStep,
disableBackButton,
disableNextButton,
nextButtonText,
blockStepStyle,
searchInputStyle,
chooseContainerStyle,
alertStyle,
issueDateContainerStyle,
datePickerStyle,
loadingContainerStyle,
stepsContentStyle,
stepsIndicatorStyle,
footerRowStyle,
footerButtonStyle,
screenXS,
direction,
modalWidth,
handleOk,
cancelModal,
handleClickBackButton,
handleClickNextButton,
resetPatient,
resetLens,
getDateString,
handleSetSearchPatientString,
handleSetSearchLensString,
getSelectedPatientBirthdayString,
};
};
export default useLensIssueFormModalUI;

View File

@ -1,6 +1,6 @@
import {Collapse, Modal} from "antd";
import PropTypes from "prop-types";
import {LensIssuePropType} from "../../Types/lensIssuePropType.js";
import {LensIssuePropType} from "../../../../../Types/lensIssuePropType.js";
const LensIssueViewModal = ({visible, onCancel, lensIssue}) => {

View File

@ -13,9 +13,9 @@ import {
Pagination, Result
} from "antd";
import {DatabaseOutlined, PlusOutlined, UnorderedListOutlined} from "@ant-design/icons";
import LensIssueViewModal from "../../Widgets/LensIssueViewModal.jsx";
import LensIssueViewModal from "./Components/LensIssueViewModal/LensIssueViewModal.jsx";
import dayjs from "dayjs";
import LensIssueFormModal from "../../Widgets/LensIssueFormModal.jsx";
import LensIssueFormModal from "./Components/LensIssueFormModal/LensIssueFormModal.jsx";
import SelectViewMode from "../../Widgets/SelectViewMode.jsx";
import LoadingIndicator from "../../Widgets/LoadingIndicator.jsx";
import useIssues from "./useIssues.js";

View File

@ -1,4 +1,4 @@
import {useEffect} from "react";
import {useEffect, useMemo} from "react";
import {getCachedInfo} from "../../../Utils/cachedInfoUtils.js";
import {
closeModal,
@ -30,10 +30,10 @@ const useLensesUI = (lenses) => {
if (cachedViewMode) dispatch(setViewMode(cachedViewMode));
}, [dispatch]);
const containerStyle = { padding: 20 };
const filterBarStyle = { marginBottom: 20 };
const formItemStyle = { width: "100%" };
const viewModIconStyle = { marginRight: 8 };
const containerStyle = {padding: 20};
const filterBarStyle = {marginBottom: 20};
const formItemStyle = {width: "100%"};
const viewModIconStyle = {marginRight: 8};
const tableActionButtonsStyle = {display: "flex", gap: "8px"};
const handleSetSearchText = (value) => dispatch(setSearchText(value));
@ -65,7 +65,8 @@ const useLensesUI = (lenses) => {
handleSetPageSize(pageSize);
};
const filteredLenses = lenses.filter((lens) => {
const filteredLenses = useMemo(() => {
return lenses.filter((lens) => {
const textMatch = Object.values(lens).some((value) =>
value?.toString().toLowerCase().includes(searchText.toLowerCase())
);
@ -86,6 +87,7 @@ const useLensesUI = (lenses) => {
}).sort((a, b) => {
return a.preset_refraction - b.preset_refraction;
});
}, [lenses, searchText, searchParams]);
const pagination = {
currentPage: currentPage,

View File

@ -1,318 +0,0 @@
import {useEffect, useState} from "react";
import {
Modal, Input, Button, notification, Typography, Collapse, Steps, Row, Alert, Col, DatePicker, Spin, Grid
} from "antd";
import PropTypes from "prop-types";
import getAllPatients from "../../old_api/patients/getAllPatients.js";
import {useAuth} from "../../Hooks/AuthContext.jsx";
import dayjs from "dayjs";
import getNotIssuedLenses from "../../old_api/lenses/getNotIssuedLenses.js";
const {useBreakpoint} = Grid;
const LensIssueFormModal = ({visible, onCancel, onSubmit}) => {
const {api} = useAuth();
const screens = useBreakpoint();
const [patients, setPatients] = useState([]);
const [lenses, setLenses] = useState([]);
const [searchPatientString, setSearchPatientString] = useState("");
const [searchLensString, setSearchLensString] = useState("");
const [issueDate, setIssueDate] = useState(dayjs(new Date()));
const [selectedPatient, setSelectedPatient] = useState(null);
const [selectedLens, setSelectedLens] = useState(null);
const [loading, setLoading] = useState(false);
const [currentStep, setCurrentStep] = useState(0);
useEffect(() => {
if (visible) {
fetchPatients();
fetchLenses();
}
}, [visible]);
const fetchPatients = async () => {
const data = await getAllPatients(api);
setPatients(data);
};
const fetchLenses = async () => {
const data = await getNotIssuedLenses(api);
setLenses(data);
};
const handleOk = async () => {
try {
setLoading(true);
setCurrentStep(0);
onSubmit(issueDate.format("YYYY-MM-DD"), selectedPatient.id, selectedLens.id);
setSelectedPatient(null);
setSelectedLens(null);
setIssueDate(dayjs(new Date()));
setLoading(false);
} catch (errorInfo) {
console.error("Validation Failed:", errorInfo);
}
};
const filteredPatients = patients
.filter((patient) => {
const searchLower = searchPatientString.toLowerCase();
return Object.values(patient)
.filter(value => typeof value === "string")
.some(value => value.toLowerCase().includes(searchLower));
});
const patientsItems = filteredPatients.map((patient) => ({
key: patient.id,
label: `${patient.last_name} ${patient.first_name} (${new Date(patient.birthday).toLocaleDateString("ru-RU")})`,
children: <div>
<p><b>Пациент:</b> {patient.last_name} {patient.first_name}</p>
<p><b>Дата рождения:</b> {new Date(patient.birthday).toLocaleDateString("ru-RU")}</p>
<p><b>Диагноз:</b> {patient.diagnosis}</p>
<p><b>Email:</b> {patient.email}</p>
<p><b>Телефон:</b> {patient.phone}</p>
<Button type="primary" onClick={() => setSelectedPatient(patient)}>Выбрать</Button>
</div>,
}));
const filteredLenses = lenses.filter((lens) => {
const searchLower = searchLensString.toLowerCase();
return Object.values(lens)
.filter(value => typeof value === "string")
.some(value => value.toLowerCase().includes(searchLower));
})
const lensesItems = filteredLenses.map((lens) => ({
key: lens.id, label: `Линза ${lens.side} ${lens.diameter} мм`, children: <div>
<p><b>Диаметр:</b> {lens.diameter}</p>
<p><b>Тор:</b> {lens.tor}</p>
<p><b>Пресетная рефракция:</b> {lens.preset_refraction}</p>
<p><b>Диаметр:</b> {lens.diameter}</p>
<p><b>FVC:</b> {lens.fvc}</p>
<p><b>Острота зрения (Trial):</b> {lens.trial}</p>
<p><b>Периферийная торичность:</b> {lens.periphery_toricity}</p>
<p><b>Сторона:</b> {lens.side}</p>
<p><b>Esa:</b> {lens.esa}</p>
<Button type="primary" onClick={() => setSelectedLens(lens)}>Выбрать</Button>
</div>,
}));
const SelectPatientStep = () => {
return selectedPatient ? (
<div style={{padding: "10px", background: "#f5f5f5", borderRadius: 5, marginBottom: 15}}>
<Typography.Text strong>
{selectedPatient.last_name} {selectedPatient.first_name}
</Typography.Text>
<p><b>Дата рождения:</b> {new Date(selectedPatient.birthday).toLocaleDateString("ru-RU")}</p>
<p><b>Email:</b> {selectedPatient.email}</p>
<p><b>Телефон:</b> {selectedPatient.phone}</p>
<Button
type="primary"
onClick={() => setSelectedPatient(null)}
danger
>
Выбрать другого пациента
</Button>
</div>) : (<>
<Input
placeholder="Поиск пациента"
value={searchPatientString}
onChange={(e) => setSearchPatientString(e.target.value)}
style={{marginBottom: 16}}
allowClear
/>
<div style={{maxHeight: 300, overflowY: "auto", border: "1px solid #d9d9d9", padding: 8}}>
<Collapse
items={patientsItems}
/>
</div>
</>)
};
const SelectLensStep = () => {
return selectedLens ? (<div style={{padding: "10px", background: "#f5f5f5", borderRadius: 5, marginBottom: 15}}>
<Typography.Text strong>
{selectedLens.diameter} {selectedLens.tor} {selectedLens.preset_refraction}
</Typography.Text>
<p><b>Диаметр:</b> {selectedLens.diameter}</p>
<p><b>Тор:</b> {selectedLens.tor}</p>
<p><b>Пресетная рефракция:</b> {selectedLens.preset_refraction}</p>
<p><b>Диаметр:</b> {selectedLens.diameter}</p>
<p><b>FVC:</b> {selectedLens.fvc}</p>
<p><b>Острота зрения (Trial):</b> {selectedLens.trial}</p>
<p><b>Периферийная торичность:</b> {selectedLens.periphery_toricity}</p>
<p><b>Сторона:</b> {selectedLens.side}</p>
<p><b>Esa:</b> {selectedLens.esa}</p>
<Button
type="primary"
onClick={() => setSelectedLens(null)}
danger
>
Выбрать другую линзу
</Button>
</div>) : (<>
<Input
placeholder="Поиск линз"
value={searchLensString}
onChange={(e) => setSearchLensString(e.target.value)}
style={{marginBottom: 16}}
allowClear
/>
<div style={{maxHeight: 300, overflowY: "auto", border: "1px solid #d9d9d9", padding: 8}}>
<Collapse
items={lensesItems}
/>
</div>
</>)
};
const ConfirmStep = () => {
return (<>
<Alert
type="warning"
message="Внимание! После подтверждения линза будет считаться выданной, данное действие нельзя будет отменить."
style={{marginBottom: 15}}
/>
<Row style={{padding: "10px", background: "#f5f5f5", borderRadius: 5, marginBottom: 15}}
gutter={[16, 16]}>
<Col xs={24} md={16} style={{display: "flex", alignItems: "center"}}>
<Typography.Text strong>
Дата выдачи: {issueDate?.toDate().toLocaleDateString("ru-RU")}
</Typography.Text>
</Col>
<Col xs={24} md={8}>
<DatePicker
value={issueDate}
onChange={(date) => setIssueDate(date)}
format="DD.MM.YYYY"
style={{width: "100%"}}
/>
</Col>
</Row>
<div style={{padding: "10px", background: "#f5f5f5", borderRadius: 5, marginBottom: 15}}>
<Typography.Text strong>
{selectedPatient.last_name} {selectedPatient.first_name}
</Typography.Text>
<p><b>Дата рождения:</b> {new Date(selectedPatient.birthday).toLocaleDateString("ru-RU")}</p>
<p><b>Email:</b> {selectedPatient.email}</p>
<p><b>Телефон:</b> {selectedPatient.phone}</p>
<p><b>Линза:</b> {selectedLens.diameter} {selectedLens.tor} {selectedLens.preset_refraction}</p>
</div>
<div style={{padding: "10px", background: "#f5f5f5", borderRadius: 5, marginBottom: 15}}>
<Typography.Text strong>
{selectedLens.diameter} {selectedLens.tor} {selectedLens.preset_refraction}
</Typography.Text>
<p><b>Диаметр:</b> {selectedLens.diameter}</p>
<p><b>Тор:</b> {selectedLens.tor}</p>
<p><b>Пресетная рефракция:</b> {selectedLens.preset_refraction}</p>
<p><b>Диаметр:</b> {selectedLens.diameter}</p>
<p><b>FVC:</b> {selectedLens.fvc}</p>
<p><b>Острота зрения (Trial):</b> {selectedLens.trial}</p>
<p><b>Периферийная торичность:</b> {selectedLens.periphery_toricity}</p>
<p><b>Сторона:</b> {selectedLens.side}</p>
<p><b>Esa:</b> {selectedLens.esa}</p>
</div>
</>);
};
const steps = [{
title: 'Выбор пациента', content: <SelectPatientStep/>,
}, {
title: 'Выбор линзы', content: <SelectLensStep/>,
}, {
title: 'Подтверждение', content: <ConfirmStep/>,
},];
const isActiveNextButton = () => {
if (currentStep === 0 && !selectedPatient) {
return false;
}
return !(currentStep === 1 && !selectedLens);
};
const isActivePrevButton = () => {
return currentStep > 0;
};
const isActiveFinishButton = () => {
return currentStep === steps.length - 1;
};
return (<Modal
title="Выдача линзы пациенту"
open={visible}
onCancel={() => {
setSelectedPatient(null);
setSelectedLens(null);
setCurrentStep(0);
setIssueDate(dayjs(new Date()));
onCancel();
}}
footer={null}
maskClosable={false}
width={!screens.xs ? 700 : "90%"}
centered
>
{loading ? (<div style={{display: "flex", justifyContent: "center", alignItems: "center", height: "70vh"}}>
<Spin size="large"/>
</div>) : (<div style={{maxHeight: "70vh", overflowY: "auto", padding: "10px"}}>
{steps[currentStep].content}
</div>)}
{!screens.xs && (<Steps
current={currentStep}
items={steps}
style={{marginTop: 16}}
direction={!screens.xs ? "horizontal" : "vertical"}
/>)}
<Row
justify="end"
style={{marginTop: 20}}
gutter={[8, 8]}
>
<Button
style={{marginRight: 8}}
onClick={() => setCurrentStep(currentStep - 1)}
disabled={!isActivePrevButton()}
>
Назад
</Button>
<Button
type="primary"
onClick={async () => {
if (isActiveFinishButton()) {
await handleOk();
} else {
setCurrentStep(currentStep + 1);
}
}}
disabled={!isActiveNextButton() && !isActiveFinishButton()}
>
{isActiveFinishButton() ? "Завершить" : "Далее"}
</Button>
</Row>
</Modal>);
};
LensIssueFormModal.propTypes = {
visible: PropTypes.bool.isRequired,
onCancel: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
};
export default LensIssueFormModal;