import { toast } from 'react-toastify'; import ReactModal from 'react-modal'; import { useState, useEffect } from 'react'; import { workbenchStore } from '~/lib/stores/workbench'; import { submitProblem, BoltProblemStatus } from '~/lib/replay/Problems'; import type { BoltProblemInput, BoltProblemSolution } from '~/lib/replay/Problems'; import { shouldUseSupabase, getCurrentUser } from '~/lib/supabase/client'; import { authModalStore } from '~/lib/stores/authModal'; import { authStatusStore } from '~/lib/stores/auth'; import { useStore } from '@nanostores/react'; import { getLastUserSimulationData, getLastSimulationChatMessages, isSimulatingOrHasFinished, getLastSimulationChatReferences, } from '~/lib/replay/SimulationPrompt'; ReactModal.setAppElement('#root'); // External functions for problem storage async function saveProblem( title: string, description: string, username: string, reproData: any, ): Promise { if (!title) { toast.error('Please fill in title field'); return null; } if (!shouldUseSupabase() && !username) { toast.error('Please enter a username'); return null; } toast.info('Submitting problem...'); const repositoryId = workbenchStore.repositoryId.get(); if (!repositoryId) { toast.error('No repository ID found'); return null; } const solution: BoltProblemSolution = { evaluator: undefined, ...reproData, }; const problem: BoltProblemInput = { version: 2, title, description, username: shouldUseSupabase() ? (undefined as any) : username, user_id: shouldUseSupabase() ? (await getCurrentUser())?.id || '' : undefined, repositoryId, status: BoltProblemStatus.Pending, solution, }; const problemId = await submitProblem(problem); if (problemId) { localStorage.setItem('loadedProblemId', problemId); } return problemId; } function getReproductionData(): any | null { if (!isSimulatingOrHasFinished()) { toast.error('No simulation data found (neither in progress nor finished)'); return null; } try { const simulationData = getLastUserSimulationData(); if (!simulationData) { toast.error('No simulation data found'); return null; } const messages = getLastSimulationChatMessages(); const references = getLastSimulationChatReferences(); if (!messages) { toast.error('No user prompt found'); return null; } return { simulationData, messages, references }; } catch (error: any) { console.error('Error getting reproduction data', error?.stack || error); toast.error(`Error getting reproduction data: ${error?.message}`); return null; } } // Component for saving the current chat as a new problem. export function SaveProblem() { const [isModalOpen, setIsModalOpen] = useState(false); const [formData, setFormData] = useState({ title: '', description: '', username: '', }); const [problemId, setProblemId] = useState(null); const [reproData, setReproData] = useState(null); const isLoggedIn = useStore(authStatusStore.isLoggedIn); const username = useStore(authStatusStore.username); // Update the username from the store when component mounts useEffect(() => { if (username) { setFormData((prev) => ({ ...prev, username })); } }, [username]); const handleSaveProblem = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); const currentReproData = getReproductionData(); if (!currentReproData) { return; } setReproData(currentReproData); setIsModalOpen(true); setProblemId(null); }; const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value, })); // Update username in the store if it's the username field if (name === 'username') { authStatusStore.updateUsername(value); } }; const handleSubmitProblem = async () => { if (!reproData) { return; } const newProblemId = await saveProblem(formData.title, formData.description, formData.username, reproData); if (newProblemId) { setProblemId(newProblemId); } }; return ( <> setIsModalOpen(false)} shouldCloseOnOverlayClick={true} shouldCloseOnEsc={true} style={{ overlay: { backgroundColor: 'rgba(0, 0, 0, 0.5)', zIndex: 1000, }, content: { top: '50%', left: '50%', right: 'auto', bottom: 'auto', marginRight: '-50%', transform: 'translate(-50%, -50%)', backgroundColor: 'white', padding: '20px', borderRadius: '8px', maxWidth: '500px', width: '100%', }, }} > {shouldUseSupabase() && !isLoggedIn && (
Please log in to save a problem
)} {(!shouldUseSupabase() || isLoggedIn) && problemId && ( <>
Problem Submitted: {problemId}
)} {(!shouldUseSupabase() || isLoggedIn) && !problemId && ( <>
Save prompts as new problems when AI results are unsatisfactory. Problems are publicly visible and are used to improve AI performance.
{!shouldUseSupabase() && ( <>
Username:
)}
Title:
Description:
)}
); }