Skip to content

Commit

Permalink
Merge branch 'develop' into issue/9660/addDebouncingForAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
i0am0arunava authored Jan 9, 2025
2 parents a22eaa7 + 8bec8bc commit 4bf3f64
Show file tree
Hide file tree
Showing 71 changed files with 2,860 additions and 1,357 deletions.
3 changes: 3 additions & 0 deletions .example.env
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,8 @@ REACT_JWT_TOKEN_REFRESH_INTERVAL=
# Minimum encounter date (default: 2020-01-01)
REACT_MIN_ENCOUNTER_DATE=

# Default Encounter Type (default: "hh" - Home Health)
REACT_DEFAULT_ENCOUNTER_TYPE=

# Available languages to switch between (2 Digit language code seperated by comas. See src->Locale->config.ts for available codes)
REACT_ALLOWED_LOCALES="en,hi,ta,ml,mr,kn"
5 changes: 5 additions & 0 deletions care.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EncounterClass } from "@/types/emr/encounter";

const env = import.meta.env;

interface ILogo {
Expand Down Expand Up @@ -48,6 +50,9 @@ const careConfig = {
.split(",")
.map((l) => l.trim()),

defaultEncounterType: (env.REACT_DEFAULT_ENCOUNTER_TYPE ||
"hh") as EncounterClass,

gmapsApiKey:
env.REACT_GMAPS_API_KEY || "AIzaSyDsBAc3y7deI5ZO3NtK5GuzKwtUzQNJNUk",

Expand Down
5 changes: 2 additions & 3 deletions crowdin.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
files:
- source: /public/locale/{{lang}}.json
translation: /public/locale/%two_letters_code%/%original_file_name%
- source: public/locale/en.json
translation: /public/locale/%two_letters_code%.json
bundles:
- 2

2 changes: 1 addition & 1 deletion cypress/e2e/patient_spec/patient_search.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe("Patient Search", () => {

it("search patient with phone number and verifies details", () => {
patientSearch
.selectFacility("PHC Kakkanad -1")
.selectFacility("Arike")
.clickSearchPatients()
.searchPatient(TEST_PHONE)
.verifySearchResults(PATIENT_DETAILS);
Expand Down
18 changes: 8 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@
"events": "^3.3.0",
"hi-profiles": "^1.1.0",
"html2canvas": "^1.4.1",
"i18next": "^24.2.0",
"i18next": "^24.2.1",
"i18next-browser-languagedetector": "^8.0.2",
"i18next-http-backend": "^3.0.1",
"input-otp": "^1.4.1",
"input-otp": "^1.4.2",
"lodash-es": "^4.17.21",
"lucide-react": "^0.469.0",
"markdown-it": "^14.1.0",
Expand Down
7 changes: 7 additions & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@
"all_changes_have_been_saved": "All changes have been saved",
"all_details": "All Details",
"all_patients": "All Patients",
"allergen": "Allergen",
"allergies": "Allergies",
"allow_transfer": "Allow Transfer",
"allowed_formats_are": "Allowed formats are",
Expand Down Expand Up @@ -652,6 +653,7 @@
"created_by": "Created By",
"created_date": "Created Date",
"created_on": "Created On",
"criticality": "Criticality",
"csv_file_in_the_specified_format": "Select a CSV file in the specified format",
"current_address": "Current Address",
"current_password": "Current Password",
Expand Down Expand Up @@ -738,6 +740,7 @@
"domestic_international_travel": "Domestic/international Travel (within last 28 days)",
"done": "Done",
"dosage": "Dosage",
"dosage_instructions": "Dosage Instructions",
"down": "Down",
"download": "Download",
"download_discharge_summary": "Download discharge summary",
Expand Down Expand Up @@ -830,6 +833,7 @@
"encounter_discharge_disposition__snf": "Skilled nursing facility",
"encounter_duration_confirmation": "The duration of this encounter would be",
"encounter_id": "Encounter ID",
"encounter_marked_as_complete": "Encounter Completed",
"encounter_notes__all_discussions": "All Discussions",
"encounter_notes__be_first_to_send": "Be the first to send a message",
"encounter_notes__choose_template": "Choose a template or enter a custom title",
Expand Down Expand Up @@ -900,6 +904,7 @@
"error_deleting_shifting": "Error while deleting Shifting record",
"error_fetching_slots_data": "Error while fetching slots data",
"error_sending_otp": "Error while sending OTP, Please try again later",
"error_updating_encounter": "Error to Updating Encounter",
"error_verifying_otp": "Error while verifying OTP, Please request a new OTP",
"error_while_deleting_record": "Error while deleting record",
"escape": "Escape",
Expand Down Expand Up @@ -1164,6 +1169,7 @@
"manufacturer": "Manufacturer",
"map_acronym": "M.A.P.",
"mark_all_as_read": "Mark all as Read",
"mark_as_complete": "Mark as Complete",
"mark_as_fulfilled": "Mark as Fullfilled",
"mark_as_noshow": "Mark as no-show",
"mark_as_read": "Mark as Read",
Expand Down Expand Up @@ -1630,6 +1636,7 @@
"select": "Select",
"select_all": "Select All",
"select_date": "Select date",
"select_department": "Select Department",
"select_eligible_policy": "Select an Eligible Insurance Policy",
"select_facility_for_discharged_patients_warning": "Facility needs to be selected to view discharged patients.",
"select_for_administration": "Select for Administration",
Expand Down
50 changes: 30 additions & 20 deletions src/Providers/AuthUserProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import careConfig from "@careConfig";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import dayjs from "dayjs";
import { navigate } from "raviger";
import { useCallback, useEffect, useState } from "react";

Expand All @@ -27,30 +26,22 @@ export default function AuthUserProvider({
otpAuthorized,
}: Props) {
const queryClient = useQueryClient();
const [accessToken, setAccessToken] = useState(
localStorage.getItem(LocalStorageKeys.accessToken),
);
const [patientToken, setPatientToken] = useState<TokenData | null>(
JSON.parse(
localStorage.getItem(LocalStorageKeys.patientTokenKey) || "null",
),
);

const { data: user, isLoading } = useQuery({
queryKey: ["currentUser"],
queryKey: ["currentUser", accessToken],
queryFn: query(routes.currentUser, { silent: true }),
retry: false,
enabled: !!localStorage.getItem(LocalStorageKeys.accessToken),
});

const [isOTPAuthorized, setIsOTPAuthorized] = useState(false);

const tokenData: TokenData = JSON.parse(
localStorage.getItem(LocalStorageKeys.patientTokenKey) || "{}",
);

useEffect(() => {
if (
tokenData.token &&
Object.keys(tokenData).length > 0 &&
dayjs(tokenData.createdAt).isAfter(dayjs().subtract(14, "minutes"))
) {
setIsOTPAuthorized(true);
}
}, [tokenData]);

useEffect(() => {
if (!user) {
return;
Expand All @@ -68,6 +59,7 @@ export default function AuthUserProvider({
const query = await request(routes.login, { body: creds });

if (query.res?.ok && query.data) {
setAccessToken(query.data.access);
localStorage.setItem(LocalStorageKeys.accessToken, query.data.access);
localStorage.setItem(LocalStorageKeys.refreshToken, query.data.refresh);

Expand All @@ -83,10 +75,20 @@ export default function AuthUserProvider({
[queryClient],
);

const patientLogin = (tokenData: TokenData, redirectUrl: string) => {
setPatientToken(tokenData);
localStorage.setItem(
LocalStorageKeys.patientTokenKey,
JSON.stringify(tokenData),
);
navigate(redirectUrl);
};

const signOut = useCallback(async () => {
localStorage.removeItem(LocalStorageKeys.accessToken);
localStorage.removeItem(LocalStorageKeys.refreshToken);
localStorage.removeItem(LocalStorageKeys.patientTokenKey);
setPatientToken(null);

await queryClient.resetQueries({ queryKey: ["currentUser"] });

Expand Down Expand Up @@ -124,15 +126,23 @@ export default function AuthUserProvider({
const SelectedRouter = () => {
if (user) {
return children;
} else if (isOTPAuthorized) {
} else if (patientToken?.token) {
return otpAuthorized;
} else {
return unauthorized;
}
};

return (
<AuthUserContext.Provider value={{ signIn, signOut, user }}>
<AuthUserContext.Provider
value={{
signIn,
signOut,
user,
patientLogin,
patientToken,
}}
>
<SelectedRouter />
</AuthUserContext.Provider>
);
Expand Down
54 changes: 23 additions & 31 deletions src/Providers/PatientUserProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import { useQuery } from "@tanstack/react-query";
import { navigate } from "raviger";
import { createContext, useEffect, useState } from "react";

import { SidebarProvider } from "@/components/ui/sidebar";
import { AppSidebar } from "@/components/ui/sidebar/app-sidebar";

import { CarePatientTokenKey } from "@/common/constants";
import { useAuthContext } from "@/hooks/useAuthUser";

import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import { AppointmentPatient } from "@/pages/Patient/Utils";
import { TokenData } from "@/types/auth/otpToken";

const tokenData: TokenData = JSON.parse(
localStorage.getItem(CarePatientTokenKey) || "{}",
);

export type PatientUserContextType = {
patients?: AppointmentPatient[];
selectedPatient: AppointmentPatient | null;
setSelectedPatient: (patient: AppointmentPatient) => void;
tokenData: TokenData;
};

export const PatientUserContext = createContext<PatientUserContextType>({
patients: undefined,
selectedPatient: null,
setSelectedPatient: () => {},
tokenData: tokenData,
});
export const PatientUserContext = createContext<PatientUserContextType | null>(
null,
);

interface Props {
children: React.ReactNode;
Expand All @@ -38,14 +29,16 @@ export default function PatientUserProvider({ children }: Props) {
const [selectedPatient, setSelectedPatient] =
useState<AppointmentPatient | null>(null);

const { patientToken: tokenData } = useAuthContext();

const { data: userData } = useQuery({
queryKey: ["patients", tokenData.phoneNumber],
queryKey: ["patients", tokenData],
queryFn: query(routes.otp.getPatient, {
headers: {
Authorization: `Bearer ${tokenData.token}`,
Authorization: `Bearer ${tokenData?.token}`,
},
}),
enabled: !!tokenData.token,
enabled: !!tokenData?.token,
});

useEffect(() => {
Expand All @@ -62,22 +55,21 @@ export default function PatientUserProvider({ children }: Props) {
}
}, [userData]);

const patientUserContext: PatientUserContextType = {
patients,
selectedPatient,
setSelectedPatient,
tokenData,
};
if (!tokenData) {
navigate("/");
return null;
}

return (
<PatientUserContext.Provider value={patientUserContext}>
<SidebarProvider>
<AppSidebar
patientUserContext={patientUserContext}
facilitySidebar={false}
/>
{children}
</SidebarProvider>
<PatientUserContext.Provider
value={{
patients,
selectedPatient,
setSelectedPatient,
tokenData: tokenData,
}}
>
{children}
</PatientUserContext.Provider>
);
}
Loading

0 comments on commit 4bf3f64

Please sign in to comment.