feat: add "Choose from Server" attachment picker to claim/preauth forms and chatbot

Native file inputs can't be pointed at a default server folder for security
reasons, so instead the Browse buttons on the Claim/PreAuth/Select Procedures
forms and the AI chatbot's attach button now also offer picking from
previously saved Cloud Storage attachments (e.g. Copy Agent screenshots) via
a new server-side picker modal, scoped per-patient on the claim forms and
unscoped (recent across all patients) in the chatbot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 00:36:43 -04:00
co-authored by Claude Sonnet 5
parent 8b245d00c6
commit 34312b62bc
6 changed files with 332 additions and 11 deletions
@@ -11,6 +11,7 @@ import {
Loader2,
RotateCcw,
Paperclip,
Image as ImageIcon,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
@@ -18,6 +19,7 @@ import { useLocation } from "wouter";
import { cn } from "@/lib/utils";
import { apiRequest } from "@/lib/queryClient";
import { setChatbotPendingFiles } from "@/lib/chatbotFileStore";
import { ServerAttachmentsPickerModal } from "@/components/file-upload/server-attachments-picker-modal";
type Step =
| "menu"
@@ -204,6 +206,7 @@ export function ChatbotButton() {
renderingProvider: string | null;
} | null>(null);
const [pendingFiles, setPendingFiles] = useState<File[]>([]);
const [isServerPickerOpen, setIsServerPickerOpen] = useState(false);
const [, setLocation] = useLocation();
const messagesEndRef = useRef<HTMLDivElement>(null);
const pasteRef = useRef<HTMLTextAreaElement>(null);
@@ -1490,6 +1493,16 @@ export function ChatbotButton() {
>
<Paperclip className="h-4 w-4" />
</Button>
<Button
size="sm"
variant="ghost"
className="h-9 w-9 p-0 shrink-0 text-gray-400 hover:text-gray-600"
title="Attach screenshot"
onClick={() => setIsServerPickerOpen(true)}
disabled={step === "ai-loading"}
>
<ImageIcon className="h-4 w-4" />
</Button>
<Button
size="sm"
className="h-9 w-9 p-0 shrink-0"
@@ -1518,6 +1531,13 @@ export function ChatbotButton() {
e.target.value = "";
}}
/>
<ServerAttachmentsPickerModal
open={isServerPickerOpen}
onClose={() => setIsServerPickerOpen(false)}
onFilesSelected={(files) =>
setPendingFiles((prev) => [...prev, ...files].slice(0, 5))
}
/>
</div>
)}
</div>