From 220caad2ce5ba69f36b0fa487cfb686de05d3625 Mon Sep 17 00:00:00 2001 From: eeseung Date: Tue, 21 Jan 2025 16:30:33 +0900 Subject: [PATCH 1/6] =?UTF-8?q?chore:=20types/react,=20types/react-dom=20d?= =?UTF-8?q?ependencies=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/package.json | 4 ++-- frontend/yarn.lock | 24 ++++++++---------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index a600161..046f9ac 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,8 +33,8 @@ "@eslint/js": "^9.15.0", "@tailwindcss/typography": "^0.5.15", "@types/js-cookie": "^3.0.6", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", + "@types/react": "^19.0.7", + "@types/react-dom": "^19.0.3", "@vitejs/plugin-react": "^4.3.4", "autoprefixer": "^10.4.20", "eslint": "^9.15.0", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index e218a5b..882c372 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1474,24 +1474,16 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== -"@types/prop-types@*": - version "15.7.14" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2" - integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ== +"@types/react-dom@^19.0.3": + version "19.0.3" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.0.3.tgz#0804dfd279a165d5a0ad8b53a5b9e65f338050a4" + integrity sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA== -"@types/react-dom@^18.3.1": - version "18.3.2" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.2.tgz#b58a9520f5f317a00bbda0271502889b71c345f0" - integrity sha512-Fqp+rcvem9wEnGr3RY8dYNvSQ8PoLqjZ9HLgaPUOjJJD120uDyOxOjc/39M4Kddp9JQCxpGQbnhVQF0C0ncYVg== +"@types/react@^19.0.7": + version "19.0.7" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.7.tgz#c451968b999d1cb2d9207dc5ff56496164cf511d" + integrity sha512-MoFsEJKkAtZCrC1r6CM8U22GzhG7u2Wir8ons/aCKH6MBdD1ibV24zOSSkdZVUKqN5i396zG5VKLYZ3yaUZdLA== dependencies: - "@types/react" "^18" - -"@types/react@^18", "@types/react@^18.3.12": - version "18.3.14" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.14.tgz#7ce43bbca0e15e1c4f67ad33ea3f83d75aa6756b" - integrity sha512-NzahNKvjNhVjuPBQ+2G7WlxstQ+47kXZNHlUvFakDViuIEfGY926GqhMueQFZ7woG+sPiQKlF36XfrIUVSUfFg== - dependencies: - "@types/prop-types" "*" csstype "^3.0.2" "@types/unist@*", "@types/unist@^3.0.0": From e5bff3e170ec0752f7e43f9d9ed2cee4efe13f52 Mon Sep 17 00:00:00 2001 From: eeseung Date: Tue, 21 Jan 2025 16:32:10 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20CategoryFilter=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/mock-data.ts | 107 +++++++++++++++ .../shared/category-filter/CategoryFilter.tsx | 126 ++++++++++++++++++ .../category-filter/useCategoryFilter.ts | 63 +++++++++ 3 files changed, 296 insertions(+) create mode 100644 frontend/src/features/m/shared/category-filter/CategoryFilter.tsx create mode 100644 frontend/src/features/m/shared/category-filter/useCategoryFilter.ts diff --git a/frontend/src/constants/mock-data.ts b/frontend/src/constants/mock-data.ts index 2d734c2..55fde93 100644 --- a/frontend/src/constants/mock-data.ts +++ b/frontend/src/constants/mock-data.ts @@ -79,3 +79,110 @@ export const patientMemo = { writer: '의사 선생님', updatedAt: '2025-01-01T12:00:00', }; + +export const mMedicineCategories = [ + { + mainCategory: '해열, 진통, 소염제', + subCategories: [ + { + id: 1, + subCategory: 'NSAIDs', + }, + { + id: 2, + subCategory: 'AAP', + }, + { + id: 3, + subCategory: '중추성진통제', + }, + ], + }, + { + mainCategory: '골격근 이완제', + subCategories: [ + { + id: 4, + subCategory: '골격근 이완제', + }, + ], + }, + { + mainCategory: '비타민', + subCategories: [ + { + id: 5, + subCategory: '비타민', + }, + ], + }, + { + mainCategory: '중추신경용약', + subCategories: [ + { + id: 6, + subCategory: '신경통약', + }, + ], + }, + { + mainCategory: '항고지혈증제', + subCategories: [ + { + id: 7, + subCategory: 'HMG-CoA Reductase Inhibitor', + }, + ], + }, + { + mainCategory: '혈당조절제', + subCategories: [ + { + id: 8, + subCategory: '인슐린분비촉진제', + }, + { + id: 9, + subCategory: '인슐린작용증강제', + }, + { + id: 10, + subCategory: 'SGLT2 저해제', + }, + { + id: 11, + subCategory: '복합제', + }, + ], + }, + { + mainCategory: '항고지혈증제+혈당조절제', + subCategories: [ + { + id: 12, + subCategory: 'HMG-CoA Reductase Inhibitor + 인슐린작용증강제', + }, + ], + }, + { + mainCategory: '항히스타민제, 호흡기질환제제', + subCategories: [ + { + id: 13, + subCategory: '항히스타민제', + }, + { + id: 14, + subCategory: '복합제제', + }, + { + id: 15, + subCategory: '진해제', + }, + { + id: 16, + subCategory: '거담제', + }, + ], + }, +]; diff --git a/frontend/src/features/m/shared/category-filter/CategoryFilter.tsx b/frontend/src/features/m/shared/category-filter/CategoryFilter.tsx new file mode 100644 index 0000000..150dc8b --- /dev/null +++ b/frontend/src/features/m/shared/category-filter/CategoryFilter.tsx @@ -0,0 +1,126 @@ +import { + Popover, + PopoverTrigger, + Button, + PopoverContent, + Command, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, +} from '@freemed-kit/ui'; +import { ChevronDown, Check } from 'lucide-react'; +import { cn } from '@/utils/cn'; +import useCategoryFilter from '@/features/m/shared/category-filter/useCategoryFilter'; + +export interface CategoryFilterProps { + categoryId: number | undefined; + onSelect: (categoryId: number) => void; +} + +const CategoryFilter = ({ categoryId, onSelect }: CategoryFilterProps) => { + const { + categories, + selectedCategory, + isMainCategoryOpen, + isSubCategoryOpen, + setIsMainCategoryOpen, + setIsSubCategoryOpen, + handleMainCategorySelect, + handleSubCategorySelect, + } = useCategoryFilter({ categoryId, onSelect }); + + return ( +
+ + + + + + + + + No category found. + + {categories.map((category) => ( + + handleMainCategorySelect(category.subCategories[0].id) + } + > + + {category.mainCategory} + + ))} + + + + + + + + + + + + + + No category found. + + {selectedCategory.subCategories.map((category) => ( + handleSubCategorySelect(category.id)} + > + + {category.subCategory} + + ))} + + + + + +
+ ); +}; + +export default CategoryFilter; diff --git a/frontend/src/features/m/shared/category-filter/useCategoryFilter.ts b/frontend/src/features/m/shared/category-filter/useCategoryFilter.ts new file mode 100644 index 0000000..bfbfb06 --- /dev/null +++ b/frontend/src/features/m/shared/category-filter/useCategoryFilter.ts @@ -0,0 +1,63 @@ +import { useEffect, useState } from 'react'; +import { CategoryFilterProps } from '@/features/m/shared/category-filter/CategoryFilter'; +import { mMedicineCategories } from '@/constants/mock-data'; + +interface SelectedCategory { + mainCategory: string; + subCategories: { id: number; subCategory: string }[]; + subCategory: string; + categoryId: number | undefined; +} + +const useCategoryFilter = ({ categoryId, onSelect }: CategoryFilterProps) => { + const categories = mMedicineCategories; + const [selectedCategory, setSelectedCategory] = useState({ + mainCategory: '', + subCategories: [], + subCategory: '', + categoryId: categoryId, + }); + const [isMainCategoryOpen, setIsMainCategoryOpen] = useState(false); + const [isSubCategoryOpen, setIsSubCategoryOpen] = useState(false); + + useEffect(() => { + const selectedMainCategory = categories.find((category) => + category.subCategories.find( + (subCategory) => subCategory.id === categoryId, + ), + ); + + setSelectedCategory({ + mainCategory: selectedMainCategory?.mainCategory || '', + subCategories: selectedMainCategory?.subCategories || [], + subCategory: + selectedMainCategory?.subCategories.find( + (subCategory) => subCategory.id === categoryId, + )?.subCategory || '', + categoryId: categoryId, + }); + }, [categories, categoryId]); + + const handleMainCategorySelect = (categoryId: number) => { + onSelect(categoryId); + setIsMainCategoryOpen(false); + }; + + const handleSubCategorySelect = (categoryId: number) => { + onSelect(categoryId); + setIsSubCategoryOpen(false); + }; + + return { + categories, + selectedCategory, + isMainCategoryOpen, + isSubCategoryOpen, + setIsMainCategoryOpen, + setIsSubCategoryOpen, + handleMainCategorySelect, + handleSubCategorySelect, + }; +}; + +export default useCategoryFilter; From 63ff236532a4e0ad0e609c1a7c4c651408457266 Mon Sep 17 00:00:00 2001 From: eeseung Date: Tue, 21 Jan 2025 23:14:12 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20SearchFilter=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/filter/search/SearchFilter.tsx | 89 +++++++++++++++++++ .../shared/filter/search/useSearchFilter.tsx | 37 ++++++++ 2 files changed, 126 insertions(+) create mode 100644 frontend/src/features/shared/filter/search/SearchFilter.tsx create mode 100644 frontend/src/features/shared/filter/search/useSearchFilter.tsx diff --git a/frontend/src/features/shared/filter/search/SearchFilter.tsx b/frontend/src/features/shared/filter/search/SearchFilter.tsx new file mode 100644 index 0000000..09b0c24 --- /dev/null +++ b/frontend/src/features/shared/filter/search/SearchFilter.tsx @@ -0,0 +1,89 @@ +import { + Button, + Form, + FormControl, + FormField, + FormItem, + Input, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@freemed-kit/ui'; +import useSearchFilter, { + SearchFilterValues, +} from '@/features/shared/filter/search/useSearchFilter'; + +interface SearchFilterProps { + options: { + label: string; + value: string; + }[]; + selectedOption: string; + searchValue: string; + placeholder: string; + onSubmit: (data: SearchFilterValues) => void; +} + +const SearchFilter = ({ + options, + selectedOption, + searchValue, + placeholder, + onSubmit, +}: SearchFilterProps) => { + const { form } = useSearchFilter({ + selectedOption, + searchValue, + }); + + return ( +
+ { + event.stopPropagation(); + form.handleSubmit(onSubmit)(event); + }} + className="flex space-x-2" + > + ( + + + + + + )} + /> + ( + + + + + + )} + /> + + + + ); +}; + +export default SearchFilter; diff --git a/frontend/src/features/shared/filter/search/useSearchFilter.tsx b/frontend/src/features/shared/filter/search/useSearchFilter.tsx new file mode 100644 index 0000000..abf9f85 --- /dev/null +++ b/frontend/src/features/shared/filter/search/useSearchFilter.tsx @@ -0,0 +1,37 @@ +import { useEffect } from 'react'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; + +interface useSearchFilterProps { + selectedOption: string; + searchValue: string; +} + +const searchFilterSchema = z.object({ + type: z.string().min(1), + value: z.string().min(1).max(160), +}); + +export type SearchFilterValues = z.infer; + +const useSearchFilter = ({ + selectedOption, + searchValue, +}: useSearchFilterProps) => { + const form = useForm({ + resolver: zodResolver(searchFilterSchema), + defaultValues: { type: selectedOption, value: searchValue }, + }); + const { reset } = form; + + useEffect(() => { + reset({ type: selectedOption, value: searchValue }); + }, [reset, selectedOption, searchValue]); + + return { + form, + }; +}; + +export default useSearchFilter; From cd0d38e57859030d5a89ca01f8cfa4c18bf2d534 Mon Sep 17 00:00:00 2001 From: eeseung Date: Tue, 21 Jan 2025 23:16:22 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20medicine-search-option=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/constants/medicine-search-option.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 frontend/src/constants/medicine-search-option.ts diff --git a/frontend/src/constants/medicine-search-option.ts b/frontend/src/constants/medicine-search-option.ts new file mode 100644 index 0000000..f77e80f --- /dev/null +++ b/frontend/src/constants/medicine-search-option.ts @@ -0,0 +1,17 @@ +export const M_MEDICINE_SEARCH_OPTION = { + NAME: { label: '약품명', value: 'name' }, + INGREDIENT: { label: '성분명', value: 'ingredient' }, +} as const; + +export const M_MEDICINE_SEARCH_OPTIONS = Object.values( + M_MEDICINE_SEARCH_OPTION, +); + +export const KM_MEDICINE_SEARCH_OPTION = { + NAME: { label: '약품명', value: 'name' }, + INDICATION: { label: '적응증', value: 'indication' }, +} as const; + +export const KM_MEDICINE_SEARCH_OPTIONS = Object.values( + KM_MEDICINE_SEARCH_OPTION, +); From 2981ea22813dc73db0e8be4357b4ba0de925c5c1 Mon Sep 17 00:00:00 2001 From: eeseung Date: Tue, 21 Jan 2025 23:17:16 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20ExpandableTableRow=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/ui/ExpandableTableRow.tsx | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 frontend/src/components/ui/ExpandableTableRow.tsx diff --git a/frontend/src/components/ui/ExpandableTableRow.tsx b/frontend/src/components/ui/ExpandableTableRow.tsx new file mode 100644 index 0000000..ef8970e --- /dev/null +++ b/frontend/src/components/ui/ExpandableTableRow.tsx @@ -0,0 +1,79 @@ +import { Button, TableCell, TableRow } from '@freemed-kit/ui'; +import React, { useState, useRef, useEffect } from 'react'; +import { ChevronsDownUp, ChevronsUpDown } from 'lucide-react'; + +interface ExpandableTableCellProps { + content: React.ReactNode; + isExpanded: boolean; +} + +interface ExpandableTableRowProps { + contents: string[]; + onRowClick: () => void; +} + +const ExpandableTableCell = React.forwardRef< + HTMLDivElement, + ExpandableTableCellProps +>(({ content, isExpanded }, ref) => { + return ( + +
+ {content} +
+
+ ); +}); + +ExpandableTableCell.displayName = 'ExpandableTableCell'; + +const ExpandableTableRow = ({ + contents, + onRowClick, +}: ExpandableTableRowProps) => { + const [isExpanded, setIsExpanded] = useState(false); + const [hasTextOverflow, setHasTextOverflow] = useState(false); + const cellElementRefs = useRef<(HTMLDivElement | null)[]>([]); + + useEffect(() => { + cellElementRefs.current.forEach((element) => { + if (!element) return; + const { scrollHeight, clientHeight } = element; + if (scrollHeight > clientHeight) { + setHasTextOverflow(true); + } + }); + }, [contents]); + + return ( + + {contents.map((content, index) => ( + { + cellElementRefs.current[index] = el; + }} + isExpanded={isExpanded} + content={content} + /> + ))} + + {hasTextOverflow && ( + + )} + + + ); +}; + +export default ExpandableTableRow; From 6a39d2ea82882d6663c9a7e0e287e7c0f98b49fb Mon Sep 17 00:00:00 2001 From: eeseung Date: Tue, 21 Jan 2025 23:32:44 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20PharmacopoeiaDialog=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/constants/mock-data.ts | 39 ++++++ .../pharmacopoeia/PharmacopoeiaDialog.tsx | 112 ++++++++++++++++++ .../pharmacopoeia/usePharmacopoeiaDialog.ts | 60 ++++++++++ 3 files changed, 211 insertions(+) create mode 100644 frontend/src/features/m/shared/pharmacopoeia/PharmacopoeiaDialog.tsx create mode 100644 frontend/src/features/m/shared/pharmacopoeia/usePharmacopoeiaDialog.ts diff --git a/frontend/src/constants/mock-data.ts b/frontend/src/constants/mock-data.ts index 55fde93..871f7d7 100644 --- a/frontend/src/constants/mock-data.ts +++ b/frontend/src/constants/mock-data.ts @@ -186,3 +186,42 @@ export const mMedicineCategories = [ ], }, ]; + +export const mMedicines = [ + { + id: 1, + name: '에스부펜정', + ingredient: 'Dexibuprofen 300mg', + dosage: + '성인 : 1회 300 mg을 1일 2~4회 경구투여.\r\n단, 1일 1200mg을 초과하지 않는다.', + efficacy: + '1. 만성 다발성 관절염, 류마티스관절염\r\n2. 관절증\r\n3. 강직척추염\r\n4. 외상 및 수술 후 통증성 부종 또는 염증\r\n5. 염증, 통증 및 발열을 수반하는 감염증의 치료보조', + mainCategory: '해열, 진통, 소염제', + subCategory: 'NSAIDs', + isExcluded: false, + }, + { + id: 2, + name: '누코미트캡슐200mg', + ingredient: 'Acetylcysteine 200mg', + dosage: + '식전에 소량의 물과 함께 복용한다.\r\n1. 급성질환\r\n성인 : 1회 200 mg 1일 3회\r\n소아 : 6~14세 1회 200 mg 1일 1회\r\n2. 만성질환\r\n성인 : 1회 200 mg 1일 2회\r\n소아 : 6~14세 1회 100 mg 1일 3회\r\n3. 낭성섬유증\r\n소아 : 6세 이상 1회 200 mg 1일 3회', + efficacy: + '다음 질환에서의 객담배출곤란 : 급.만성기관지염, 기관지천식, 후두염, 부비동염, 낭성섬유증', + mainCategory: '항히스타민제&호흡기질환제제', + subCategory: '거담제', + isExcluded: false, + }, + { + id: 3, + name: '유한뎬탈케어 가글 프로 마일드', + ingredient: 'Allantoin 0.2g Sodium Fluoride', + dosage: + '성인 : 1회 300 mg을 1일 2~4회 경구투여. 단, 1일 1200mg을 초과하지 않는다.', + efficacy: + '1. 만성 다발성 관절염, 류마티스관절염\n4. 외상 및 수술 후 통증성 부종 또는 염증\n5. 염증, 통증 및 발열을 수반하는 감염증의 치료보조', + mainCategory: '해열, 진통, 소염제', + subCategory: 'NSAIDs', + isExcluded: true, + }, +]; diff --git a/frontend/src/features/m/shared/pharmacopoeia/PharmacopoeiaDialog.tsx b/frontend/src/features/m/shared/pharmacopoeia/PharmacopoeiaDialog.tsx new file mode 100644 index 0000000..b6dae40 --- /dev/null +++ b/frontend/src/features/m/shared/pharmacopoeia/PharmacopoeiaDialog.tsx @@ -0,0 +1,112 @@ +import { + Button, + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, + ScrollArea, + Table, + TableBody, + TableHead, + TableHeader, + TableRow, +} from '@freemed-kit/ui'; +import { SquarePlus } from 'lucide-react'; +import ExpandableTableRow from '@/components/ui/ExpandableTableRow'; +import { M_MEDICINE_SEARCH_OPTIONS } from '@/constants/medicine-search-option'; +import CategoryFilter from '@/features/m/shared/category-filter/CategoryFilter'; +import usePharmacopoeiaDialog from '@/features/m/shared/pharmacopoeia/usePharmacopoeiaDialog'; +import SearchFilter from '@/features/shared/filter/search/SearchFilter'; + +export interface PharmacopoeiaDialogProps { + append: (value: { + name: string; + ingredient: string; + medicineId: number; + doses: number | ''; + dosesCountByDay: string; + dosesDay: number; + bundle: string; + memo: string; + isExcluded: boolean; + }) => void; +} + +const PharmacopoeiaDialog = ({ append }: PharmacopoeiaDialogProps) => { + const { + medicines, + categoryId, + searchOption, + searchValue, + handleCategorySelect, + handleSearch, + handleRowClick, + } = usePharmacopoeiaDialog({ append }); + + return ( + + + + + + + 약전 + + + +
+ + +
+
+ + + + 대분류 + 소분류 + 약품명 + 성분명/함량 + 용량/용법 + 약효 + + + + + {medicines.map((medicine) => ( + handleRowClick(medicine)} + /> + ))} + +
+
+
+
+
+ ); +}; + +export default PharmacopoeiaDialog; diff --git a/frontend/src/features/m/shared/pharmacopoeia/usePharmacopoeiaDialog.ts b/frontend/src/features/m/shared/pharmacopoeia/usePharmacopoeiaDialog.ts new file mode 100644 index 0000000..ddc16ed --- /dev/null +++ b/frontend/src/features/m/shared/pharmacopoeia/usePharmacopoeiaDialog.ts @@ -0,0 +1,60 @@ +import { useState } from 'react'; +import { mMedicines } from '@/constants/mock-data'; +import { SearchFilterValues } from '@/features/shared/filter/search/useSearchFilter'; +import { PharmacopoeiaDialogProps } from '@/features/m/shared/pharmacopoeia/PharmacopoeiaDialog'; +import { useToast } from '@freemed-kit/ui'; + +const usePharmacopoeiaDialog = ({ append }: PharmacopoeiaDialogProps) => { + const medicines = mMedicines; + const [categoryId, setCategoryId] = useState(); + const [searchOption, setSearchOption] = useState(); + const [searchValue, setSearchValue] = useState(); + const { toast } = useToast(); + + const handleCategorySelect = (categoryId: number) => { + setCategoryId(categoryId); + setSearchOption(''); + setSearchValue(''); + }; + + const handleSearch = (data: SearchFilterValues) => { + setSearchOption(data.type); + setSearchValue(data.value); + setCategoryId(undefined); + }; + + const handleRowClick = (medicine: { + id: number; + name: string; + ingredient: string; + isExcluded: boolean; + }) => { + append({ + medicineId: medicine.id, + name: medicine.name, + ingredient: medicine.ingredient, + doses: 0, + dosesCountByDay: '0', + dosesDay: 0, + bundle: '', + memo: '', + isExcluded: medicine.isExcluded, + }); + toast({ + title: '➕ 약품 처방 추가', + description: `[${medicine.name}] 약품이 처방에 추가되었습니다.`, + }); + }; + + return { + medicines, + categoryId, + searchOption, + searchValue, + handleCategorySelect, + handleSearch, + handleRowClick, + }; +}; + +export default usePharmacopoeiaDialog;