From de52e863bd29db758a56cdb3aba714e5ee5cc1cb Mon Sep 17 00:00:00 2001 From: Mike Fortman Date: Wed, 22 Oct 2025 15:00:40 -0500 Subject: [PATCH] upload component --- .../components/onboarding-content.tsx | 128 +++--------------- .../components/onboarding-step.tsx | 20 ++- .../components/onboarding-upload.tsx | 81 +++++++++++ 3 files changed, 116 insertions(+), 113 deletions(-) create mode 100644 frontend/src/app/new-onboarding/components/onboarding-upload.tsx diff --git a/frontend/src/app/new-onboarding/components/onboarding-content.tsx b/frontend/src/app/new-onboarding/components/onboarding-content.tsx index a6c28069..f44e9d5a 100644 --- a/frontend/src/app/new-onboarding/components/onboarding-content.tsx +++ b/frontend/src/app/new-onboarding/components/onboarding-content.tsx @@ -1,6 +1,6 @@ "use client"; -import { type ChangeEvent, useRef, useState } from "react"; +import { useState } from "react"; import { StickToBottom } from "use-stick-to-bottom"; import { AssistantMessage } from "@/app/chat/components/assistant-message"; import { UserMessage } from "@/app/chat/components/user-message"; @@ -8,10 +8,9 @@ import Nudges from "@/app/chat/nudges"; import type { Message } from "@/app/chat/types"; import OnboardingCard from "@/app/onboarding/components/onboarding-card"; import { useChatStreaming } from "@/hooks/useChatStreaming"; -import { DuplicateHandlingDialog } from "@/components/duplicate-handling-dialog"; -import { duplicateCheck, uploadFile as uploadFileUtil } from "@/lib/upload-utils"; -import { toast } from "sonner"; + import { OnboardingStep } from "./onboarding-step"; +import OnboardingUpload from "./onboarding-upload"; export function OnboardingContent({ handleStepComplete, @@ -25,10 +24,6 @@ export function OnboardingContent({ const [assistantMessage, setAssistantMessage] = useState( null, ); - const fileInputRef = useRef(null); - const [pendingFile, setPendingFile] = useState(null); - const [showDuplicateDialog, setShowDuplicateDialog] = useState(false); - const [isUploading, setIsUploading] = useState(false); const { streamingMessage, isLoading, sendMessage } = useChatStreaming({ onComplete: (message, newResponseId) => { @@ -61,76 +56,6 @@ export function OnboardingContent({ }, 1500); }; - const resetFileInput = () => { - if (fileInputRef.current) { - fileInputRef.current.value = ""; - } - }; - - const handleUploadClick = () => { - fileInputRef.current?.click(); - }; - - const handleDuplicateDialogChange = (open: boolean) => { - if (!open) { - setPendingFile(null); - } - setShowDuplicateDialog(open); - }; - - const performUpload = async (file: File, replace = false) => { - setIsUploading(true); - try { - await uploadFileUtil(file, replace); - toast.success("Document uploaded successfully"); - } catch (error) { - toast.error("Upload failed", { - description: error instanceof Error ? error.message : "Unknown error", - }); - } finally { - setIsUploading(false); - } - }; - - const handleFileChange = async (event: ChangeEvent) => { - const selectedFile = event.target.files?.[0]; - if (!selectedFile) { - resetFileInput(); - return; - } - - try { - const duplicateInfo = await duplicateCheck(selectedFile); - if (duplicateInfo.exists) { - setPendingFile(selectedFile); - setShowDuplicateDialog(true); - return; - } - - await performUpload(selectedFile, false); - } catch (error) { - toast.error("Unable to prepare file for upload", { - description: error instanceof Error ? error.message : "Unknown error", - }); - } finally { - resetFileInput(); - } - }; - - const handleOverwriteFile = async () => { - if (!pendingFile) { - return; - } - - const fileToUpload = pendingFile; - setPendingFile(null); - try { - await performUpload(fileToUpload, true); - } finally { - resetFileInput(); - } - }; - // Determine which message to show (streaming takes precedence) const displayMessage = streamingMessage || assistantMessage; @@ -177,29 +102,26 @@ export function OnboardingContent({ {currentStep >= 1 && !!selectedNudge && (displayMessage || isLoading) && ( - <> - {}} - isStreaming={!!streamingMessage} - isCompleted={currentStep > 1} - /> - {!isLoading && displayMessage && currentStep === 1 && ( -
- -
- )} - + {}} + isStreaming={!!streamingMessage} + isCompleted={currentStep > 1} + /> )} + + {/* Still kind of part of step 2 */} + 2} + text="Now, let's add your data." + hideIcon={true} + > + + = 2} @@ -257,12 +179,6 @@ export function OnboardingContent({ - ); diff --git a/frontend/src/app/new-onboarding/components/onboarding-step.tsx b/frontend/src/app/new-onboarding/components/onboarding-step.tsx index 613f08a9..84cfd6f2 100644 --- a/frontend/src/app/new-onboarding/components/onboarding-step.tsx +++ b/frontend/src/app/new-onboarding/components/onboarding-step.tsx @@ -12,6 +12,7 @@ interface OnboardingStepProps { isCompleted?: boolean; icon?: ReactNode; isMarkdown?: boolean; + hideIcon?: boolean; } export function OnboardingStep({ @@ -21,6 +22,7 @@ export function OnboardingStep({ isCompleted = false, icon, isMarkdown = false, + hideIcon = false, }: OnboardingStepProps) { const [displayedText, setDisplayedText] = useState(""); const [showChildren, setShowChildren] = useState(false); @@ -66,13 +68,17 @@ export function OnboardingStep({ > - - + hideIcon ? ( +
+ ) : ( + icon || ( +
+ +
+ ) ) } > diff --git a/frontend/src/app/new-onboarding/components/onboarding-upload.tsx b/frontend/src/app/new-onboarding/components/onboarding-upload.tsx new file mode 100644 index 00000000..0c4a1fc9 --- /dev/null +++ b/frontend/src/app/new-onboarding/components/onboarding-upload.tsx @@ -0,0 +1,81 @@ +import { ChangeEvent, useRef, useState } from "react"; +import { Button } from "@/components/ui/button"; +import { duplicateCheck, uploadFile } from "@/lib/upload-utils"; + +interface OnboardingUploadProps { + onComplete: () => void; +} + +const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => { + const fileInputRef = useRef(null); + const [isUploading, setIsUploading] = useState(false); + + const resetFileInput = () => { + if (fileInputRef.current) { + fileInputRef.current.value = ""; + } + }; + + const handleUploadClick = () => { + fileInputRef.current?.click(); + }; + + + const performUpload = async (file: File, replace = false) => { + setIsUploading(true); + try { + await uploadFile(file, replace); + console.log("Document uploaded successfully"); + } catch (error) { + console.error("Upload failed", (error as Error).message); + } finally { + setIsUploading(false); + onComplete(); + } + }; + + const handleFileChange = async (event: ChangeEvent) => { + const selectedFile = event.target.files?.[0]; + if (!selectedFile) { + resetFileInput(); + return; + } + + try { + const duplicateInfo = await duplicateCheck(selectedFile); + if (duplicateInfo.exists) { + console.log("Duplicate file detected"); + return; + } + + await performUpload(selectedFile, false); + } catch (error) { + console.error("Unable to prepare file for upload", (error as Error).message); + } finally { + resetFileInput(); + } + }; + + + return ( +
+ + +
+ ) +} + +export default OnboardingUpload;