-
-
-
-
-
-
-
-
-
-
props.setFullscreen(!props.isFullscreen)}
- shortcutsDisabled={shortcutsDisabled}
- >
-
-
+ if (props.inlineView) {
+ return (
+
+
+
+
+ {controls.zoom}
+ {controls.reset}
+ {controls.fullscreen}
+
+ );
+ }
+
+ return (
+
+
{controls.zoom}
+
{controls.position}
+
+ {controls.reset}
+ {controls.fullscreen}
+
);
}
diff --git a/src/Components/CameraFeed/useOperateCamera.ts b/src/Components/CameraFeed/useOperateCamera.ts
index 259e45fcc89..c0e35f90bf2 100644
--- a/src/Components/CameraFeed/useOperateCamera.ts
+++ b/src/Components/CameraFeed/useOperateCamera.ts
@@ -1,3 +1,4 @@
+import { useState } from "react";
import request from "../../Utils/request/request";
import { FeedRoutes } from "./routes";
@@ -32,23 +33,47 @@ interface RelativeMoveOperation {
data: PTZPayload;
}
+interface ResetFeedOperation {
+ type: "reset";
+}
+
export type OperationAction =
| GetStatusOperation
| GetPresetsOperation
| GoToPresetOperation
| AbsoluteMoveOperation
- | RelativeMoveOperation;
+ | RelativeMoveOperation
+ | ResetFeedOperation;
/**
* This hook is used to control the PTZ of a camera asset and retrieve other related information.
* @param id The external id of the camera asset
*/
export default function useOperateCamera(id: string, silent = false) {
- return (action: OperationAction) => {
- return request(FeedRoutes.operateAsset, {
- pathParams: { id },
- body: { action },
- silent,
- });
+ const [key, setKey] = useState(0);
+
+ return {
+ key,
+ operate: (action: OperationAction) => {
+ if (action.type === "reset") {
+ setKey((prev) => prev + 1);
+
+ return request(FeedRoutes.operateAsset, {
+ pathParams: { id },
+ body: {
+ action: {
+ type: "get_status",
+ },
+ },
+ silent,
+ });
+ }
+
+ return request(FeedRoutes.operateAsset, {
+ pathParams: { id },
+ body: { action },
+ silent,
+ });
+ },
};
}
diff --git a/src/Components/Common/components/ButtonV2.tsx b/src/Components/Common/components/ButtonV2.tsx
index 2c9579873b1..014a182ba94 100644
--- a/src/Components/Common/components/ButtonV2.tsx
+++ b/src/Components/Common/components/ButtonV2.tsx
@@ -100,6 +100,8 @@ const ButtonV2 = ({
tooltipClassName,
...props
}: ButtonProps) => {
+ shadow ??= !ghost;
+
const className = classNames(
props.className,
"inline-flex h-min cursor-pointer items-center justify-center gap-2 whitespace-pre font-medium outline-offset-1 transition-all duration-200 ease-in-out disabled:cursor-not-allowed disabled:bg-secondary-200 disabled:text-secondary-500",
@@ -107,7 +109,7 @@ const ButtonV2 = ({
`button-shape-${circle ? "circle" : "square"}`,
ghost ? `button-${variant}-ghost` : `button-${variant}-default`,
border && `button-${variant}-border`,
- shadow && "shadow enabled:hover:shadow-lg",
+ shadow && "shadow enabled:hover:shadow-md",
tooltip && "tooltip",
);
diff --git a/src/Components/Diagnosis/DiagnosesListAccordion.tsx b/src/Components/Diagnosis/DiagnosesListAccordion.tsx
index 88222da0570..adae1d8bb7c 100644
--- a/src/Components/Diagnosis/DiagnosesListAccordion.tsx
+++ b/src/Components/Diagnosis/DiagnosesListAccordion.tsx
@@ -75,6 +75,7 @@ export default function DiagnosesListAccordion(props: Props) {
onClick={() => {
setIsVisible(false);
}}
+ shadow={false}
>
Hide Diagnoses
diff --git a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx
index 5d447b79687..34931b303f8 100644
--- a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx
+++ b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx
@@ -8,7 +8,6 @@ import Loading from "../../Common/Loading";
import AssetBedSelect from "../../CameraFeed/AssetBedSelect";
import { triggerGoal } from "../../../Integrations/Plausible";
import useAuthUser from "../../../Common/hooks/useAuthUser";
-import PageTitle from "../../Common/PageTitle";
import useSlug from "../../../Common/hooks/useSlug";
import CareIcon from "../../../CAREUI/icons/CareIcon";
import ButtonV2 from "../../Common/components/ButtonV2";
@@ -18,8 +17,12 @@ import useOperateCamera, {
import request from "../../../Utils/request/request";
import { classNames, isIOS } from "../../../Utils/utils";
import ConfirmDialog from "../../Common/ConfirmDialog";
+import useBreakpoints from "../../../Common/hooks/useBreakpoints";
+import { Warn } from "../../../Utils/Notifications";
+import { useTranslation } from "react-i18next";
export const ConsultationFeedTab = (props: ConsultationTabProps) => {
+ const { t } = useTranslation();
const authUser = useAuthUser();
const facility = useSlug("facility");
const bed = props.consultationData.current_bed?.bed_object;
@@ -30,10 +33,23 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => {
useState(false);
const [isUpdatingPreset, setIsUpdatingPreset] = useState(false);
const [hasMoved, setHasMoved] = useState(false);
- const [key, setKey] = useState(0);
const divRef = useRef
();
- const operate = useOperateCamera(asset?.id ?? "", true);
+ const suggestOptimalExperience = useBreakpoints({ default: true, sm: false });
+
+ useEffect(() => {
+ if (suggestOptimalExperience) {
+ Warn({
+ msg: t(
+ isIOS
+ ? "feed_optimal_experience_for_apple_phones"
+ : "feed_optimal_experience_for_phones",
+ ),
+ });
+ }
+ }, []);
+
+ const { key, operate } = useOperateCamera(asset?.id ?? "", true);
const { data, loading, refetch } = useQuery(routes.listAssetBeds, {
query: { limit: 100, facility, bed: bed?.id, asset: asset?.id },
@@ -108,99 +124,83 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => {
onConfirm={handleUpdatePreset}
/>
-
-
-
-
- For better experience, rotate your device.
-
-
-
setHasMoved(true)}
- onReset={() => {
- if (isIOS) {
- setKey(key + 1);
- }
- }}
- onStreamError={() => {
- triggerGoal("Camera Feed Viewed", {
- consultationId: props.consultationId,
- userId: authUser.id,
- result: "error",
- });
- }}
- onStreamSuccess={() => {
- triggerGoal("Camera Feed Viewed", {
- consultationId: props.consultationId,
- userId: authUser.id,
- result: "success",
- });
- }}
- >
-
- {presets ? (
- <>
-
obj.meta.preset_name}
- value={preset}
- onChange={(value) => {
- triggerGoal("Camera Preset Clicked", {
- presetName: preset?.meta?.preset_name,
- consultationId: props.consultationId,
- userId: authUser.id,
- result: "success",
- });
- setHasMoved(false);
- setPreset(value);
- }}
+
+
setHasMoved(true)}
+ operate={operate}
+ onStreamError={() => {
+ triggerGoal("Camera Feed Viewed", {
+ consultationId: props.consultationId,
+ userId: authUser.id,
+ result: "error",
+ });
+ }}
+ onStreamSuccess={() => {
+ triggerGoal("Camera Feed Viewed", {
+ consultationId: props.consultationId,
+ userId: authUser.id,
+ result: "success",
+ });
+ }}
+ >
+
+ {presets ? (
+ <>
+
obj.meta.preset_name}
+ value={preset}
+ onChange={(value) => {
+ triggerGoal("Camera Preset Clicked", {
+ presetName: preset?.meta?.preset_name,
+ consultationId: props.consultationId,
+ userId: authUser.id,
+ result: "success",
+ });
+ setHasMoved(false);
+ setPreset(value);
+ }}
+ />
+ {isUpdatingPreset ? (
+
- {isUpdatingPreset ? (
-
- ) : (
- setShowPresetSaveConfirmation(true)}
- >
-
-
- )}
- >
- ) : (
- loading presets...
- )}
-
-
-
+ ) : (
+ setShowPresetSaveConfirmation(true)}
+ >
+
+
+ )}
+ >
+ ) : (
+ loading presets...
+ )}
+
+
>
);
diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx
index 0b0d2c01a50..52996a3e769 100644
--- a/src/Components/Facility/ConsultationDetails/index.tsx
+++ b/src/Components/Facility/ConsultationDetails/index.tsx
@@ -205,13 +205,15 @@ export const ConsultationDetails = (props: any) => {
}
const tabButtonClasses = (selected: boolean) =>
- `capitalize min-w-max-content cursor-pointer border-transparent text-secondary-700 hover:text-secondary-700 hover:border-secondary-300 font-bold whitespace-nowrap ${
- selected === true ? "border-primary-500 text-primary-600 border-b-2" : ""
+ `capitalize min-w-max-content cursor-pointer font-bold whitespace-nowrap ${
+ selected === true
+ ? "border-primary-500 hover:border-secondary-300 text-primary-600 border-b-2"
+ : "text-secondary-700 hover:text-secondary-700"
}`;
return (
-
+
+
+ Active in last...
+ o.text}
+ optionValue={(o) => o.id}
+ value={filterState.last_active_days}
+ onChange={(v) =>
+ setFilterState({ ...filterState, last_active_days: v })
+ }
+ />
+
+