improvement: QRcode and shared link added to cases inorder to make it possible for staff users to share a case info with other staffs or other clinics.
This commit is contained in:
75
frontend/src/lib/api/lab-case-access.ts
Normal file
75
frontend/src/lib/api/lab-case-access.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { apiClient } from './client';
|
||||
import type { LabCaseComment, LabTaskListItem } from '@/types/cases';
|
||||
|
||||
export interface LabCaseAccessProsthesisGroup {
|
||||
prosthesisTypeCode: string;
|
||||
prosthesisTypeLabel: string;
|
||||
teeth: string[];
|
||||
}
|
||||
|
||||
export interface LabCaseAccessSession {
|
||||
labCaseId: string;
|
||||
accessMode: 'lab' | 'clinic';
|
||||
canEditTaskStatus: boolean;
|
||||
canPostComments: boolean;
|
||||
canToggleCommentVisibility: boolean;
|
||||
shareUrl: string;
|
||||
sentAt: string | null;
|
||||
dueDate: string | null;
|
||||
isOverdue: boolean;
|
||||
isImportant: boolean;
|
||||
clinic: { id: string; name: string };
|
||||
lab: { id: string; name: string } | null;
|
||||
patient: { id: string; firstName: string; lastName: string };
|
||||
prosthesisGroups: LabCaseAccessProsthesisGroup[];
|
||||
}
|
||||
|
||||
export const labCaseAccessApi = {
|
||||
resolve: async (
|
||||
token: string,
|
||||
): Promise<{ success: boolean; data: LabCaseAccessSession }> => {
|
||||
const response = await apiClient.get(`/lab-cases/access/${encodeURIComponent(token)}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
listTasks: async (
|
||||
token: string,
|
||||
): Promise<{ success: boolean; data: { items: LabTaskListItem[] } }> => {
|
||||
const response = await apiClient.get(
|
||||
`/lab-cases/access/${encodeURIComponent(token)}/tasks`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
listComments: async (
|
||||
token: string,
|
||||
): Promise<{ success: boolean; data: LabCaseComment[] }> => {
|
||||
const response = await apiClient.get(
|
||||
`/lab-cases/access/${encodeURIComponent(token)}/comments`,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
addComment: async (
|
||||
token: string,
|
||||
payload: { body: string; visibleToClinic?: boolean },
|
||||
): Promise<{ success: boolean; data: LabCaseComment }> => {
|
||||
const response = await apiClient.post(
|
||||
`/lab-cases/access/${encodeURIComponent(token)}/comments`,
|
||||
payload,
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
setCommentVisibility: async (
|
||||
token: string,
|
||||
commentId: string,
|
||||
visibleToClinic: boolean,
|
||||
): Promise<{ success: boolean; data: LabCaseComment }> => {
|
||||
const response = await apiClient.patch(
|
||||
`/lab-cases/access/${encodeURIComponent(token)}/comments/${commentId}/visibility`,
|
||||
{ visibleToClinic },
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
17
frontend/src/lib/auth/postAuthRedirect.ts
Normal file
17
frontend/src/lib/auth/postAuthRedirect.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { stripLocaleFromPathname } from '@/i18n/routing';
|
||||
|
||||
const AUTH_REDIRECT_KEY = 'authRedirect';
|
||||
|
||||
export function storeAuthRedirectFromPath(pathWithOptionalLocale: string) {
|
||||
if (typeof window === 'undefined') return;
|
||||
const path = stripLocaleFromPathname(pathWithOptionalLocale);
|
||||
if (!path || path === '/login' || path === '/register') return;
|
||||
sessionStorage.setItem(AUTH_REDIRECT_KEY, path);
|
||||
}
|
||||
|
||||
export function consumeAuthRedirect(): string | null {
|
||||
if (typeof window === 'undefined') return null;
|
||||
const path = sessionStorage.getItem(AUTH_REDIRECT_KEY);
|
||||
if (path) sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
||||
return path;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
startProactiveSessionRefresh,
|
||||
} from '@/lib/auth/proactiveRefresh';
|
||||
import { asApiError, legacyStatusCode, type ApiError } from '@/types/api';
|
||||
import { consumeAuthRedirect } from '@/lib/auth/postAuthRedirect';
|
||||
|
||||
function toApiError(err: unknown): ApiError {
|
||||
return (
|
||||
@@ -288,10 +289,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
await authApi.selectOrganization(org.id);
|
||||
setCurrentOrganization(org);
|
||||
localStorage.setItem('currentOrganizationId', org.id);
|
||||
router.push('/today');
|
||||
} else {
|
||||
router.push('/select-organization');
|
||||
|
||||
}
|
||||
|
||||
} catch (err: any) {
|
||||
@@ -332,7 +331,6 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
await authApi.selectOrganization(org.id);
|
||||
setCurrentOrganization(org);
|
||||
localStorage.setItem('currentOrganizationId', org.id);
|
||||
router.push('/today');
|
||||
} else {
|
||||
router.push('/select-organization');
|
||||
}
|
||||
@@ -388,12 +386,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
plan: (organization as { plan?: Organization['plan'] }).plan,
|
||||
});
|
||||
|
||||
const redirectPath =
|
||||
typeof window !== 'undefined'
|
||||
? sessionStorage.getItem('authRedirect')
|
||||
: null;
|
||||
const redirectPath = consumeAuthRedirect();
|
||||
if (redirectPath) {
|
||||
sessionStorage.removeItem('authRedirect');
|
||||
router.push(redirectPath);
|
||||
} else {
|
||||
router.push('/today');
|
||||
|
||||
Reference in New Issue
Block a user