1- import React , { useState } from "react" ;
1+ import React , { useCallback , useState } from "react" ;
22import {
33 Button ,
4+ ContentSwitcher ,
45 Form ,
6+ Hospital ,
57 Layer ,
68 ModalHeader ,
79 ModalBody ,
810 ModalFooter ,
911 Select ,
1012 SelectItem ,
1113 Stack ,
14+ Switch ,
15+ TaskLocation ,
1216 InlineNotification ,
1317 InlineLoading ,
1418} from "@carbon/react" ;
1519import {
1620 DefaultWorkspaceProps ,
21+ showSnackbar ,
1722 useLayoutType ,
1823 useSession ,
1924} from "@openmrs/esm-framework" ;
20- import { Controller , useForm } from "react-hook-form" ;
25+ import { Controller , SubmitHandler , useForm } from "react-hook-form" ;
2126import styles from "./change-location-link.scss" ;
2227import { useTranslation } from "react-i18next" ;
2328import { zodResolver } from "@hookform/resolvers/zod" ;
2429import z from "zod" ;
25- import { useRoomLocations } from "./change-location.resource" ;
30+ import { Provider , saveProvider , useClinicLocations , useRoomLocations } from "./change-location.resource" ;
2631
2732type ChangeLocationProps = DefaultWorkspaceProps ;
2833
@@ -31,14 +36,18 @@ const ChangeLocationModal: React.FC<ChangeLocationProps> = ({
3136} ) => {
3237 const { t } = useTranslation ( ) ;
3338 const isTablet = useLayoutType ( ) === "tablet" ;
39+ const [ tabType , setTabType ] = useState ( "Change room" ) ;
3440 const session = useSession ( ) ;
35- const currentLocation = session ?. sessionLocation ?. display ;
41+ const currentLocation = session ?. sessionLocation ?. uuid ;
3642 const [ isChangingRoom , setIsChangingRoom ] = useState ( false ) ;
43+ const [ selectedClinicRoom , setselectedClinicRoom ] = useState < string | undefined > ( ) ;
44+ const [ selectedClinic , setSelectedClinic ] = useState < string | undefined > ( ) ;
45+ const { roomLocations, error : errorFetchingRooms } = useRoomLocations ( selectedClinic ) ;
46+ const { clinicsList, error : errorFetchingClinics } = useClinicLocations ( ) ;
3747
38- const { roomLocations, error : errorFetchingRooms } = useRoomLocations (
39- session ?. sessionLocation ?. uuid
40- ) ;
41- const [ selectedClinciRoom , setselectedClinciRoom ] = useState ( ) ;
48+ const handleTabTypeChange = ( { name } ) => {
49+ setTabType ( name ) ;
50+ } ;
4251
4352 const changeLocationSchema = z . object ( {
4453 clinicRoom : z . string ( ) . optional ( ) ,
@@ -51,16 +60,105 @@ const ChangeLocationModal: React.FC<ChangeLocationProps> = ({
5160 } = useForm ( {
5261 resolver : zodResolver ( changeLocationSchema ) ,
5362 } ) ;
63+
64+ const onSubmit : SubmitHandler < any > = useCallback (
65+ ( data ) => {
66+ setIsChangingRoom ( true ) ;
67+
68+ const newLocationUuid = data . clinicRoom ?? data . clinic ;
69+ const providerUuid = session ?. currentProvider ?. uuid ;
70+ const personUuid = session ?. user ?. person ?. uuid ;
71+
72+ const payload : Provider = {
73+ uuid : providerUuid ,
74+ person : { uuid : personUuid } ,
75+ attributes : [
76+ {
77+ attributeType : {
78+ uuid : "13a721e4-68e5-4f7a-8aee-3cbcec127179" ,
79+ display : "Default Location" ,
80+ } ,
81+ value : {
82+ uuid : newLocationUuid ,
83+ display : roomLocations . find ( loc => loc . uuid === newLocationUuid ) ?. display || "Selected Location"
84+ }
85+ }
86+ ] ,
87+ } ;
88+
89+ saveProvider ( payload )
90+ . then ( ( ) => {
91+ closeWorkspace ( ) ;
92+ showSnackbar ( {
93+ title : t ( "locationChanged" , "Default location updated" ) ,
94+ kind : "success" ,
95+ } ) ;
96+ } )
97+ . catch ( ( error ) => {
98+ const errorMessage =
99+ error ?. responseBody ?. message || error ?. message || "An unexpected error occurred" ;
100+ console . error ( "Provider update failed:" , errorMessage ) ;
101+ } )
102+ . finally ( ( ) => {
103+ setIsChangingRoom ( false ) ;
104+ } ) ;
105+ } ,
106+ [ session , closeWorkspace , t , roomLocations ]
107+ ) ;
108+
109+
54110 return (
55- < Form >
111+ < Form onSubmit = { handleSubmit ( onSubmit ) } >
56112 < ModalHeader
57113 closeModal = { close }
58114 title = { t ( "changeLocation" , "Change location" ) }
59115 />
60116 < ModalBody >
117+
118+ < ContentSwitcher onChange = { handleTabTypeChange } >
119+ < Switch name = "Change room" text = { t ( "changeRoom" , "Switch room" ) } />
120+ < Switch name = "Change clinic" text = { t ( "changeClinic" , "Switch only clinic" ) } />
121+ </ ContentSwitcher >
122+
61123 < Stack gap = { 5 } className = { styles . languageOptionsContainer } >
62124 < ResponsiveWrapper isTablet = { isTablet } >
63- < Controller
125+ { tabType === "Change room" && (
126+ < > < Controller
127+ name = "clinicLocation"
128+ control = { control }
129+ defaultValue = ""
130+ render = { ( { field } ) => (
131+ < Select
132+ { ...field }
133+ id = "clinicLocation"
134+ name = "clinicLocation"
135+ labelText = "Select clinic"
136+ disabled = { errorFetchingClinics }
137+ invalidText = { errors . root ?. message }
138+ value = { field . value }
139+ onChange = { ( e ) => {
140+ const selectedValue = e . target . value ;
141+ field . onChange ( selectedValue ) ;
142+ setSelectedClinic ( selectedValue ) ;
143+ } }
144+ >
145+ { ! field . value && (
146+ < SelectItem
147+ value = ""
148+ text = { t (
149+ "selectClinic" ,
150+ "Choose clinic"
151+ ) }
152+ />
153+ ) }
154+
155+ { clinicsList . map ( ( { uuid, display } ) => (
156+ < SelectItem key = { uuid } value = { uuid } text = { display } />
157+ ) ) }
158+ </ Select >
159+ ) }
160+ />
161+ < Controller
64162 name = "clinicRoom"
65163 control = { control }
66164 defaultValue = { currentLocation }
@@ -70,22 +168,21 @@ const ChangeLocationModal: React.FC<ChangeLocationProps> = ({
70168 id = "clinicRoom"
71169 name = "clinicRoom"
72170 labelText = "Select room to change to"
73- disabled = { errorFetchingRooms }
74- invalid = { ! ! errors . locationTo }
171+ disabled = { ! selectedClinic || errorFetchingRooms }
75172 invalidText = { errors . locationTo ?. message }
76173 value = { field . value }
77174 onChange = { ( e ) => {
78175 const selectedValue = e . target . value ;
79176 field . onChange ( selectedValue ) ;
80- setselectedClinciRoom ( selectedValue ) ;
177+ setselectedClinicRoom ( selectedValue ) ;
81178 } }
82179 >
83180 { ! field . value && (
84181 < SelectItem
85182 value = ""
86183 text = { t (
87- "selectNextServicePoint " ,
88- "Choose next service point "
184+ "selectRoom " ,
185+ "Choose room "
89186 ) }
90187 />
91188 ) }
@@ -95,7 +192,44 @@ const ChangeLocationModal: React.FC<ChangeLocationProps> = ({
95192 ) ) }
96193 </ Select >
97194 ) }
98- />
195+ /> </ >
196+ ) }
197+ { tabType === "Change clinic" && (
198+ < Controller
199+ name = "clinic"
200+ control = { control }
201+ defaultValue = { currentLocation }
202+ render = { ( { field } ) => (
203+ < Select
204+ { ...field }
205+ id = "clinic"
206+ name = "clinic"
207+ labelText = "Select clinic to change to"
208+ disabled = { errorFetchingClinics }
209+ invalidText = { errors . root ?. message }
210+ value = { field . value }
211+ onChange = { ( e ) => {
212+ const selectedValue = e . target . value ;
213+ field . onChange ( selectedValue ) ;
214+ setSelectedClinic ( selectedValue ) ;
215+ } }
216+ >
217+ { ! field . value && (
218+ < SelectItem
219+ value = ""
220+ text = { t (
221+ "selectClinic" ,
222+ "Choose clinic"
223+ ) }
224+ />
225+ ) }
226+
227+ { clinicsList . map ( ( { uuid, display } ) => (
228+ < SelectItem key = { uuid } value = { uuid } text = { display } />
229+ ) ) }
230+ </ Select >
231+ ) }
232+ /> ) }
99233
100234 { errorFetchingRooms && (
101235 < InlineNotification
@@ -123,7 +257,7 @@ const ChangeLocationModal: React.FC<ChangeLocationProps> = ({
123257 >
124258 { isChangingRoom ? (
125259 < InlineLoading
126- description = { t ( "changingPassword " , "Changing password " ) + "..." }
260+ description = { t ( "changingLocation " , "Changing location " ) + "..." }
127261 />
128262 ) : (
129263 < span > { t ( "change" , "Change" ) } </ span >
0 commit comments