Spaces:
Sleeping
Sleeping
File size: 6,785 Bytes
d8635c9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | import { writable } from 'svelte/store'
import { backendService, type StoredDocument } from '../utils/backendService'
// Interface for reference documents stored in backend
export interface ReferenceDocument extends StoredDocument {
// Inherits: id, name, category, fileType, uploadDate, size
}
// Interface for current RFP (metadata only, not stored in backend)
export interface CurrentRFPDocument {
id: string
name: string
size: number
uploadDate: string
pageCount?: number
quality?: string
keyTopics?: string[]
wordCount?: number
fileType?: string
// RFP specific metadata
rfpName?: string
bidNumber?: string
// Note: No content field - this is metadata only
}
export interface Question {
id: string
text: string
selected: boolean
priority: 'high' | 'medium' | 'low'
source?: string
}
export interface RFPAnswer {
id: string
question: string
previousAnswer?: string
aiGeneratedAnswer?: string
finalAnswer?: string
source?: string
pageNumber?: number
isFinalized: boolean
isFormatted?: boolean
hasAdditionalInfo?: boolean
additionalInfo?: string
citations: string[]
}
export interface RFPData {
currentRFP: CurrentRFPDocument | null // Changed from previousRFPs array
newQuestions: File | null
questions: string[]
answers: RFPAnswer[]
extractedData: any[]
}
export interface AppState {
currentStep: number
isLoading: boolean
error: string | null
}
// App state stores
// LocalStorage keys
const STORAGE_KEYS = {
CURRENT_STEP: 'rfp_current_step',
CURRENT_RFP: 'rfp_current_rfp', // Changed from PREVIOUS_RFPS
QUESTIONS: 'rfp_questions',
ANSWERS: 'rfp_answers',
RFP_DATA: 'rfp_data'
}
// Load data from localStorage
function loadFromStorage<T>(key: string, defaultValue: T): T {
if (typeof window === 'undefined') return defaultValue
try {
const stored = localStorage.getItem(key)
return stored ? JSON.parse(stored) : defaultValue
} catch (error) {
console.warn(`Failed to load ${key} from localStorage:`, error)
return defaultValue
}
}
// Save data to localStorage
function saveToStorage<T>(key: string, value: T): void {
if (typeof window === 'undefined') return
try {
localStorage.setItem(key, JSON.stringify(value))
} catch (error) {
console.warn(`Failed to save ${key} to localStorage:`, error)
}
}
export const currentStep = writable<number>(loadFromStorage(STORAGE_KEYS.CURRENT_STEP, 1))
export const isLoading = writable<boolean>(false)
export const error = writable<string | null>(null)
// Store for reference documents (managed by backend)
export const referenceDocuments = writable<ReferenceDocument[]>([])
// Store for current RFP (metadata only, localStorage)
export const currentRfp = writable<CurrentRFPDocument | null>(loadFromStorage(STORAGE_KEYS.CURRENT_RFP, null))
// Other stores with localStorage persistence
export const questions = writable<Question[]>(loadFromStorage(STORAGE_KEYS.QUESTIONS, []))
export const answers = writable<RFPAnswer[]>(loadFromStorage(STORAGE_KEYS.ANSWERS, []))
// Legacy RFP data store (updated structure)
export const rfpData = writable<RFPData>(loadFromStorage(STORAGE_KEYS.RFP_DATA, {
currentRFP: null,
newQuestions: null,
questions: [],
answers: [],
extractedData: []
}))
// Subscribe to store changes and save to localStorage
currentStep.subscribe(value => saveToStorage(STORAGE_KEYS.CURRENT_STEP, value))
currentRfp.subscribe(value => saveToStorage(STORAGE_KEYS.CURRENT_RFP, value))
questions.subscribe(value => saveToStorage(STORAGE_KEYS.QUESTIONS, value))
answers.subscribe(value => saveToStorage(STORAGE_KEYS.ANSWERS, value))
rfpData.subscribe(value => saveToStorage(STORAGE_KEYS.RFP_DATA, value))
// Helper functions
export function nextStep() {
currentStep.update(step => Math.min(step + 1, 5))
}
export function prevStep() {
currentStep.update(step => Math.max(step - 1, 1))
}
export function resetApp() {
currentStep.set(1)
isLoading.set(false)
error.set(null)
referenceDocuments.set([])
currentRfp.set(null)
questions.set([])
answers.set([])
rfpData.set({
currentRFP: null,
newQuestions: null,
questions: [],
answers: [],
extractedData: []
})
// Clear localStorage
if (typeof window !== 'undefined') {
Object.values(STORAGE_KEYS).forEach(key => {
localStorage.removeItem(key)
})
}
}
// Function to clear current RFP (keeping reference documents in backend)
export function clearCurrentRfp() {
currentRfp.set(null)
if (typeof window !== 'undefined') {
localStorage.removeItem(STORAGE_KEYS.CURRENT_RFP)
}
}
// Backend service functions
export async function loadReferenceDocuments() {
try {
isLoading.set(true)
error.set(null)
// Check backend health first
const isHealthy = await backendService.healthCheck()
if (!isHealthy) {
throw new Error('Backend server is not responding')
}
const documents = await backendService.getPreviousRFPs()
referenceDocuments.set(documents)
console.log(`✅ Loaded ${documents.length} reference documents from backend`)
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to load reference documents'
error.set(errorMessage)
console.warn('❌ Failed to load reference documents:', errorMessage)
// Set empty array if backend fails
referenceDocuments.set([])
} finally {
isLoading.set(false)
}
}
export async function uploadReferenceDocument(file: File, category: string) {
try {
isLoading.set(true)
const document = await backendService.uploadPreviousRFP(file, category)
// Add to current list
referenceDocuments.update(docs => [...docs, document])
return document
} catch (err) {
error.set(err instanceof Error ? err.message : 'Failed to upload document')
throw err
} finally {
isLoading.set(false)
}
}
export async function deleteReferenceDocument(id: string) {
try {
isLoading.set(true)
await backendService.deleteDocument(id)
// Remove from current list
referenceDocuments.update(docs => docs.filter(doc => doc.id !== id))
} catch (err) {
error.set(err instanceof Error ? err.message : 'Failed to delete document')
throw err
} finally {
isLoading.set(false)
}
}
export async function getDocumentContent(id: string) {
try {
return await backendService.getDocumentContent(id)
} catch (err) {
error.set(err instanceof Error ? err.message : 'Failed to get document content')
throw err
}
}
|