11import { HamburgerSvg } from "./SVGs.jsx" ;
22import { PlusSvg } from "./SVGs.jsx"
3+ import { useState } from "react" ;
34
45export function ClearAllHistoryButton ( ) {
56 return (
@@ -111,4 +112,159 @@ export function TabPromptConfigButton({ setSelectedTab, className }) {
111112 Prompt Configs
112113 </ button >
113114 )
115+ }
116+
117+ export function ModelConfigDoneButton ( { selectedTab, setIsModelConfigOpen, setReloadModel } ) {
118+ /* modelConfigTab, promptConfigTab */
119+ function handleClick ( ) {
120+ if ( selectedTab === 'promptConfigTab' ) { setIsModelConfigOpen ( false ) }
121+ if ( selectedTab === 'modelConfigTab' ) { setReloadModel ( prev => prev + 1 ) ; setIsModelConfigOpen ( false ) }
122+ }
123+ return (
124+ < button
125+ onClick = { handleClick }
126+ className = { `w-full mt-6 text-white py-2 rounded-lg font-semibold transition-colors
127+ ${ selectedTab === 'promptConfigTab'
128+ ? 'bg-blue-600 hover:bg-blue-500'
129+ : 'bg-red-600 hover:bg-red-400'
130+ } `}
131+ >
132+ { selectedTab === 'promptConfigTab'
133+ ? "Done"
134+ : "Reload Model"
135+ }
136+ </ button >
137+ )
138+ }
139+
140+ export function ModelConfigCloseButton ( { setIsModelConfigOpen } ) {
141+ return (
142+ < button
143+ onClick = { ( ) => setIsModelConfigOpen ( false ) }
144+ className = "absolute top-4 right-4 text-gray-400 hover:text-white"
145+ >
146+ X
147+ </ button >
148+ )
149+ }
150+
151+ export function ModelConfigMenuButton ( { setIsModelConfigOpen } ) {
152+ return (
153+ < button className = "active:scale-95 h-full w-full" onClick = { ( ) => setIsModelConfigOpen ( true ) } >
154+ Configure Model
155+ </ button >
156+ )
157+ }
158+
159+ export function CopyCodeBlockButton ( { value } ) {
160+ const [ copied , setCopied ] = useState ( false )
161+
162+ const handleCopy = ( ) => {
163+ navigator . clipboard . writeText ( value )
164+ console . log ( 'code block copied' )
165+ setCopied ( true )
166+ setTimeout ( ( ) => setCopied ( false ) , 2000 )
167+ }
168+ return (
169+ < button
170+ onClick = { handleCopy }
171+ className = "hover:text-white transition-colors flex items-center gap-1"
172+ >
173+ { copied ? (
174+ < span className = "text-green-400" > Copied!</ span >
175+ ) : (
176+ < span > Copy</ span >
177+ ) }
178+ </ button >
179+ )
180+ }
181+
182+ export function ShowThinkingButton ( { setIsThinkingBlockOpen, isThinkingBlockOpen } ) {
183+ return (
184+ < button
185+ className = "text-xs font-semibold text-gray-400 hover:text-white flex items-center gap-1 mb-1"
186+ onClick = { ( ) => setIsThinkingBlockOpen ( ! isThinkingBlockOpen ) }
187+ >
188+ { isThinkingBlockOpen
189+ ? '▼ Hide thinking'
190+ : '▶ Show thinking'
191+ }
192+ </ button >
193+ )
194+ }
195+
196+ export function RenderHistoryButton ( { session, setChatMessages } ) {
197+ return (
198+ < button key = { session . sessionId }
199+ className = "w-full text-left p-2.5 rounded-lg border transition-all group relative mb-1 bg-gray-700/30 border-gray-700/50 hover:bg-gray-700"
200+ onClick = { ( ) => ( setChatMessages ( session . history ) ) }
201+ >
202+ < div className = "flex justify-between items-center" >
203+ < span className = "font-medium text-xs text-gray-300 group-hover:text-white truncate" > { session . title } </ span >
204+ </ div >
205+ </ button >
206+ )
207+ }
208+
209+ export function UploadedModelFilesButton ( { index, setUploadedModel, file } ) {
210+ return (
211+ < button key = { index }
212+ className = 'w-full text-left p-2.5 rounded-lg border transition-all group relative mb-1 bg-green-900/20 border-green-800 hover:bg-green-900/40'
213+ onClick = { ( ) => ( setUploadedModel ( file ) ) }
214+ >
215+ < div className = "flex justify-between items-center" >
216+ < div className = "flex flex-col min-w-0 flex-1" >
217+ < span className = "font-medium text-xs text-gray-300 group-hover:text-white truncate" > { file . name } </ span >
218+ </ div >
219+ </ div >
220+ </ button >
221+ )
222+ }
223+
224+ export function UploadedModelUrlsButton ( { index, url, setSelectedModelUrl } ) {
225+ return (
226+ < button key = { index }
227+ className = 'w-full text-left p-2.5 rounded-lg border transition-all group relative mb-1 bg-green-900/20 border-green-800 hover:bg-green-900/40'
228+ onClick = { ( ) => ( setSelectedModelUrl ( url ) ) }
229+ >
230+ < div className = "flex justify-between items-center" >
231+ < div className = "flex flex-col min-w-0 flex-1" >
232+ < span className = "font-medium text-xs text-gray-300 group-hover:text-white truncate" > { url . split ( '/' ) . pop ( ) } </ span >
233+ </ div >
234+ </ div >
235+ </ button >
236+ )
237+ }
238+
239+ export function RenderCsvModelsButton ( { index, model, setSelectedModelUrl } ) {
240+ const getModelName = ( url ) => {
241+ return url . split ( '/' ) . pop ( )
242+ }
243+ const downloadedModelList = localStorage . getItem ( 'downloadedModels' ) || '[]'
244+
245+ function checkIfDownloaded ( url ) {
246+ if ( downloadedModelList . includes ( url ) ) return true
247+ else return false
248+ }
249+ return (
250+ < button key = { index }
251+ className = { `w-full text-left p-2.5 rounded-lg border transition-all group relative mb-1
252+ ${ checkIfDownloaded ( model [ 0 ] )
253+ ? 'bg-green-900/20 border-green-800 hover:bg-green-900/40'
254+ : 'bg-gray-700/30 border-gray-700/50 hover:bg-gray-700' } `}
255+ onClick = { ( ) => ( setSelectedModelUrl ( model [ 0 ] ) ) }
256+ >
257+ < div className = "flex justify-between items-center" >
258+ < div className = "flex flex-col min-w-0 flex-1" >
259+ < span className = "font-medium text-xs text-gray-300 group-hover:text-white truncate" > { getModelName ( model [ 0 ] ) } </ span >
260+ { checkIfDownloaded ( model [ 0 ] ) &&
261+ < span className = "text-[9px] text-green-400" >
262+ Available offline
263+ </ span >
264+ }
265+ </ div >
266+ < span className = "text-[10px] text-gray-500 bg-black/20 px-1.5 py-0.5 rounded whitespace-nowrap" > { model [ 1 ] } MB</ span >
267+ </ div >
268+ </ button >
269+ )
114270}
0 commit comments