Spaces:
Sleeping
Sleeping
| <script lang="ts"> | |
| import { previousRfps, nextStep, clearUploadedRfps } from '../stores/appStore' | |
| import { onMount } from 'svelte' | |
| let dragActive = false | |
| let uploadedFiles: File[] = [] | |
| let hasStoredData = false | |
| onMount(() => { | |
| // Check if we have stored data on component mount | |
| hasStoredData = $previousRfps.length > 0 | |
| }) | |
| async function handleFileUpload(event: Event) { | |
| const target = event.target as HTMLInputElement | |
| if (target.files) { | |
| uploadedFiles = Array.from(target.files) | |
| previousRfps.update(current => [ | |
| ...current, | |
| ...uploadedFiles.map(file => ({ | |
| id: `rfp-${Date.now()}-${Math.random()}`, | |
| name: file.name, | |
| content: '', | |
| size: file.size, | |
| uploadDate: new Date().toISOString(), | |
| pageCount: 1, | |
| quality: 'Good', | |
| keyTopics: [], | |
| wordCount: 1000 | |
| })) | |
| ]) | |
| } | |
| } | |
| async function loadSampleRfps() { | |
| const sampleRfps = [ | |
| { | |
| id: 'sample-1', | |
| name: 'IT Services Project Response.md', | |
| content: '', | |
| size: 4500, | |
| uploadDate: new Date().toISOString(), | |
| pageCount: 3, | |
| quality: 'Excellent', | |
| keyTopics: ['Technical Approach', 'Security', 'Timeline', 'Team'], | |
| wordCount: 850 | |
| }, | |
| { | |
| id: 'sample-2', | |
| name: 'Cloud Migration Project Response.md', | |
| content: '', | |
| size: 5200, | |
| uploadDate: new Date().toISOString(), | |
| pageCount: 4, | |
| quality: 'Excellent', | |
| keyTopics: ['Cloud Strategy', 'Migration', 'Security', 'Compliance'], | |
| wordCount: 950 | |
| } | |
| ] | |
| previousRfps.update(current => [...current, ...sampleRfps]) | |
| } | |
| function proceedToNextStep() { | |
| if ($previousRfps.length > 0) { | |
| nextStep() | |
| } | |
| } | |
| function removeDocument(id: string) { | |
| previousRfps.update(current => current.filter(doc => doc.id !== id)) | |
| } | |
| function clearAllDocuments() { | |
| if (confirm('Are you sure you want to clear all uploaded documents? This will also remove them from storage.')) { | |
| clearUploadedRfps() | |
| hasStoredData = false | |
| } | |
| } | |
| </script> | |
| <div class="space-y-6"> | |
| <div class="bg-blue-500/10 border border-blue-500/20 rounded-lg p-6"> | |
| <h3 class="text-lg font-semibold text-blue-300 mb-2">Upload Previous RFPs</h3> | |
| <p class="text-blue-300/80">Upload your previous RFP documents for reference and maximum accuracy.</p> | |
| </div> | |
| <div class="bg-gray-800 rounded-lg border-2 border-dashed border-gray-600 hover:border-blue-500/50 transition-colors"> | |
| <div class="relative p-8 text-center"> | |
| <input | |
| type="file" | |
| multiple | |
| accept=".pdf,.docx,.doc,.txt" | |
| on:change={handleFileUpload} | |
| class="absolute inset-0 opacity-0 cursor-pointer" | |
| /> | |
| <div class="flex flex-col items-center space-y-3"> | |
| <div class="w-16 h-16 bg-gradient-to-r from-blue-500 to-blue-600 rounded-lg flex items-center justify-center text-white"> | |
| <svg class="w-8 h-8" fill="currentColor" viewBox="0 0 20 20"> | |
| <path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"></path> | |
| </svg> | |
| </div> | |
| <div> | |
| <h3 class="text-lg font-semibold text-gray-200 mb-2">Upload Previous RFPs</h3> | |
| <p class="text-gray-300 mb-2">Click to browse or drag and drop files</p> | |
| <p class="text-sm text-gray-400">Supports PDF, DOCX, DOC, and TXT files</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| {#if $previousRfps.length > 0} | |
| <div class="bg-gray-800 rounded-lg border border-gray-600"> | |
| <div class="bg-gray-700 p-4"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <div class="flex items-center space-x-3"> | |
| <h3 class="text-lg font-semibold text-white">Uploaded Documents</h3> | |
| {#if hasStoredData} | |
| <span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium text-blue-300 bg-blue-600/20"> | |
| Restored from storage | |
| </span> | |
| {/if} | |
| </div> | |
| <p class="text-gray-300 text-sm">{$previousRfps.length} documents ready for AI processing</p> | |
| </div> | |
| <div class="flex items-center space-x-3"> | |
| <button | |
| on:click={clearAllDocuments} | |
| class="bg-gray-600 hover:bg-gray-700 text-gray-300 px-4 py-2 rounded-lg font-medium transition-colors text-sm" | |
| title="Clear all documents and storage" | |
| > | |
| Clear All | |
| </button> | |
| <button | |
| on:click={proceedToNextStep} | |
| class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg font-medium transition-colors" | |
| > | |
| Continue to Questions → | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="p-4 space-y-3"> | |
| {#each $previousRfps as doc, index} | |
| <div class="border border-gray-600 bg-gray-700/30 rounded-lg p-3"> | |
| <div class="flex items-start justify-between"> | |
| <div class="flex-1"> | |
| <div class="flex items-center space-x-3 mb-2"> | |
| <div class="w-6 h-6 bg-blue-500/20 rounded flex items-center justify-center text-blue-300 text-sm font-medium"> | |
| {index + 1} | |
| </div> | |
| <h4 class="font-medium text-gray-200">{doc.name}</h4> | |
| <span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium text-green-300 bg-green-600/20"> | |
| {doc.quality} | |
| </span> | |
| </div> | |
| <div class="grid grid-cols-3 gap-4 text-sm"> | |
| <div> | |
| <span class="text-gray-400">Size:</span> | |
| <span class="font-semibold text-gray-200">{(doc.size / 1024 / 1024).toFixed(1)} MB</span> | |
| </div> | |
| <div> | |
| <span class="text-gray-400">Pages:</span> | |
| <span class="font-semibold text-gray-200">{doc.pageCount}</span> | |
| </div> | |
| <div> | |
| <span class="text-gray-400">Words:</span> | |
| <span class="font-semibold text-gray-200">{doc.wordCount?.toLocaleString()}</span> | |
| </div> | |
| </div> | |
| </div> | |
| <button | |
| on:click={() => removeDocument(doc.id)} | |
| class="ml-4 w-8 h-8 bg-red-500/20 hover:bg-red-500/30 rounded-lg flex items-center justify-center text-red-400 transition-colors" | |
| title="Remove document" | |
| > | |
| × | |
| </button> | |
| </div> | |
| </div> | |
| {/each} | |
| </div> | |
| </div> | |
| {/if} | |
| <div class="bg-gray-700/50 rounded-lg p-4 border border-gray-600"> | |
| <h3 class="text-base font-medium text-gray-200 mb-3">Tips for Best Results</h3> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm text-gray-300"> | |
| <div> | |
| <h4 class="font-medium mb-2 text-gray-200">Best Documents Include:</h4> | |
| <ul class="space-y-1"> | |
| <li>• Complete question-answer pairs</li> | |
| <li>• Technical specifications</li> | |
| <li>• Company methodologies</li> | |
| <li>• Previous winning proposals</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-medium mb-2 text-gray-200">For Optimal Results:</h4> | |
| <ul class="space-y-1"> | |
| <li>• Upload 3-5 comprehensive RFPs</li> | |
| <li>• Include recent proposals (last 2 years)</li> | |
| <li>• Ensure documents are well-formatted</li> | |
| <li>• Mix different industry sectors</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |