From 8bc6089a7f07820f509b393a1ca3aee1e1d58a0d Mon Sep 17 00:00:00 2001 From: Danel Kungla Date: Tue, 28 Oct 2025 16:09:06 +0200 Subject: [PATCH] add doctor feedback --- app/doctor/_components/analysis-fallback.tsx | 27 +++ app/doctor/_components/analysis-feedback.tsx | 41 +++-- app/doctor/_components/analysis-view.tsx | 45 ++++- .../doctor-recommended-analyses.tsx | 53 ++++++ .../new-analysis-recommendations-loader.tsx | 90 ++++++++++ .../_components/prepare-ai-parameters.tsx | 55 ++++++ .../_lib/server/load-doctor-feedback.ts | 98 +++++++++++ app/doctor/analysis/[id]/page.tsx | 24 ++- .../(user)/(dashboard)/life-style/page.tsx | 25 +-- app/home/(user)/_components/ai/ai-blocks.tsx | 5 +- .../(user)/_components/ai/life-style-card.tsx | 22 ++- .../(user)/_components/ai/recommendations.tsx | 13 +- app/home/(user)/_components/ai/types.ts | 1 + .../_components/home-mobile-navigation.tsx | 4 +- app/home/(user)/_lib/server/ai-actions.ts | 162 +++++++++++++++--- .../(user)/_lib/server/load-life-style.ts | 63 +++++-- .../_lib/server/load-recommendations.ts | 54 +++++- lib/utils.ts | 15 ++ .../server/actions/doctor-server-actions.ts | 23 +++ .../doctor-analysis-detail-view.schema.ts | 3 +- .../server/schema/doctor-analysis.schema.ts | 4 + .../services/doctor-analysis.service.ts | 3 +- .../features/user-analyses/src/server/api.ts | 6 +- .../personal-account-navigation.config.tsx | 4 +- packages/supabase/src/database.types.ts | 3 + public/locales/et/common.json | 1 + public/locales/et/doctor.json | 5 +- .../20251024164100_improve_ai_responses.sql | 66 +++++++ 28 files changed, 820 insertions(+), 95 deletions(-) create mode 100644 app/doctor/_components/analysis-fallback.tsx create mode 100644 app/doctor/_components/doctor-recommended-analyses.tsx create mode 100644 app/doctor/_components/new-analysis-recommendations-loader.tsx create mode 100644 app/doctor/_components/prepare-ai-parameters.tsx create mode 100644 app/doctor/_lib/server/load-doctor-feedback.ts create mode 100644 supabase/migrations/20251024164100_improve_ai_responses.sql diff --git a/app/doctor/_components/analysis-fallback.tsx b/app/doctor/_components/analysis-fallback.tsx new file mode 100644 index 0000000..9431ad7 --- /dev/null +++ b/app/doctor/_components/analysis-fallback.tsx @@ -0,0 +1,27 @@ +'use server'; + +import React from 'react'; + +import { Spinner } from '@kit/ui/makerkit/spinner'; +import { Trans } from '@kit/ui/makerkit/trans'; +import { Progress } from '@kit/ui/shadcn/progress'; + +import { withI18n } from '~/lib/i18n/with-i18n'; + +const AnalysisFallback = ({ + progress, + progressTextKey, +}: { + progress: number; + progressTextKey: string; +}) => { + return ( +
+ + + +
+ ); +}; + +export default withI18n(AnalysisFallback); diff --git a/app/doctor/_components/analysis-feedback.tsx b/app/doctor/_components/analysis-feedback.tsx index c1d4c54..df0a234 100644 --- a/app/doctor/_components/analysis-feedback.tsx +++ b/app/doctor/_components/analysis-feedback.tsx @@ -16,6 +16,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { useQueryClient } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; +import { Spinner } from '@kit/ui/makerkit/spinner'; import { Trans } from '@kit/ui/makerkit/trans'; import { Button } from '@kit/ui/shadcn/button'; import { @@ -32,12 +33,21 @@ const AnalysisFeedback = ({ feedback, patient, order, + aiDoctorFeedback, + timestamp, + recommendations, + isRecommendationsEdited, }: { feedback?: DoctorFeedback; patient: Patient; order: Order; + aiDoctorFeedback?: string; + timestamp?: string; + recommendations: string[]; + isRecommendationsEdited: boolean; }) => { const [isDraftSubmitting, setIsDraftSubmitting] = useState(false); + const [isSubmittingFeedback, setIsSubmittingFeedback] = useState(false); const [isConfirmOpen, setIsConfirmOpen] = useState(false); const { data: user } = useUser(); const queryClient = useQueryClient(); @@ -46,7 +56,7 @@ const AnalysisFeedback = ({ resolver: zodResolver(doctorAnalysisFeedbackFormSchema), reValidateMode: 'onChange', defaultValues: { - feedbackValue: feedback?.value ?? '', + feedbackValue: feedback?.value ?? aiDoctorFeedback ?? '', userId: patient.userId, }, }); @@ -71,23 +81,30 @@ const AnalysisFeedback = ({ data: DoctorAnalysisFeedbackForm, status: 'DRAFT' | 'COMPLETED', ) => { + setIsConfirmOpen(false); + setIsSubmittingFeedback(true); + const result = await giveFeedbackAction({ ...data, analysisOrderId: order.analysisOrderId, status, + patientId: patient.userId, + timestamp, + recommendations, + isRecommendationsEdited, }); if (!result.success) { return toast.error(); } + setIsSubmittingFeedback(false); + queryClient.invalidateQueries({ predicate: (query) => query.queryKey.includes('doctor-jobs'), }); - toast.success(); - - return setIsConfirmOpen(false); + return toast.success(); }; const confirmComplete = form.handleSubmit(async (data) => { @@ -96,10 +113,6 @@ const AnalysisFeedback = ({ return ( <> -

- -

-

{feedback?.value ?? '-'}

{!isReadOnly && (
@@ -109,7 +122,11 @@ const AnalysisFeedback = ({ render={({ field }) => ( -