File size: 11,849 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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<script lang="ts">

  import { nextStep, currentRfp, type CurrentRFPDocument } from '../stores/appStore'

  import { createEventDispatcher } from 'svelte'

  

  const dispatch = createEventDispatcher()

  

  let uploadedFile: File | null = null

  let dragActive = false

  let extractedContent = ''

  let documentInfo: any = null

  let isProcessing = false

  let showFullContent = false

  

  // RFP metadata fields

  let rfpName = ''

  let bidNumber = ''

  

  async function handleFileUpload(event: Event) {

    const target = event.target as HTMLInputElement

    if (target.files && target.files[0]) {

      uploadedFile = target.files[0]

      await processRfpDocument()

    }

  }

  

  async function handleDrop(event: DragEvent) {

    event.preventDefault()

    dragActive = false

    

    if (event.dataTransfer?.files && event.dataTransfer.files[0]) {

      uploadedFile = event.dataTransfer.files[0]

      await processRfpDocument()

    }

  }

  

  async function processRfpDocument() {

    if (!uploadedFile) return

    

    isProcessing = true

    try {

      // Upload to backend for real content extraction

      const formData = new FormData()

      formData.append('file', uploadedFile)

      

      const response = await fetch('/api/upload-current-rfp', {

        method: 'POST',

        body: formData

      })

      

      if (!response.ok) {

        throw new Error(`Upload failed: ${response.statusText}`)

      }

      

      const result = await response.json()

      

      if (result.success) {

        documentInfo = result.document

        extractedContent = result.content || ''

        

        // Create metadata for app store

        const rfpMetadata: CurrentRFPDocument = {

          id: result.document.id,

          name: result.document.name,

          size: uploadedFile.size,

          uploadDate: result.document.uploadDate,

          fileType: result.document.fileType,

          pageCount: 1, // Will be updated by backend if available

          quality: extractedContent.length > 1000 ? 'Good' : 'Fair',

          keyTopics: ['Document Content'],

          wordCount: extractedContent.split(' ').length,

          rfpName: rfpName.trim() || undefined,

          bidNumber: bidNumber.trim() || undefined

        }

        

        // Store metadata in app store

        currentRfp.set(rfpMetadata)

        

        console.log('βœ… Current RFP uploaded and processed successfully')

      } else {

        throw new Error('Upload failed')

      }

    } catch (error) {

      console.error('Error processing RFP:', error)

      alert('Failed to process RFP document: ' + error.message)

    } finally {

      isProcessing = false

    }

  }

  

  function proceedToQuestions() {

    nextStep()

  }

  

  function removeCurrentRfp() {

    uploadedFile = null

    currentRfp.set(null)

    extractedContent = ''

    documentInfo = null

    showFullContent = 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 Current RFP</h3>
    <p class="text-blue-300/80">Upload the RFP document you are responding to. We'll extract questions automatically (metadata only - content not stored).</p>
  </div>

  <!-- RFP Metadata Fields -->
  <div class="bg-gray-800 rounded-lg border border-gray-600 p-6">
    <h4 class="text-lg font-semibold text-white mb-4">RFP Information</h4>
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
      <div>
        <label for="rfpName" class="block text-sm font-medium text-gray-300 mb-2">
          RFP Name / Title
        </label>
        <input

          id="rfpName"

          type="text"

          bind:value={rfpName}

          placeholder="e.g., IT Staff Augmentation Services"

          class="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 text-white placeholder-gray-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none transition-colors"

        />
      </div>
      <div>
        <label for="bidNumber" class="block text-sm font-medium text-gray-300 mb-2">
          Bid Number / RFP ID
        </label>
        <input

          id="bidNumber"

          type="text"

          bind:value={bidNumber}

          placeholder="e.g., 269EMCPS-25-005"

          class="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 text-white placeholder-gray-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none transition-colors"

        />
      </div>
    </div>
    <p class="text-sm text-gray-400 mt-2">This information will be included in the cover letter of your final document.</p>
  </div>

  <!-- Upload Area -->
  {#if !uploadedFile}
    <div 

      class="bg-gray-800 rounded-lg border-2 border-dashed border-gray-600 hover:border-blue-500/50 transition-colors"

      class:border-blue-500={dragActive}

      on:dragover|preventDefault={() => dragActive = true}
      on:dragleave|preventDefault={() => dragActive = false}
      on:drop={handleDrop}
    >
      <div class="relative p-12 text-center">
        <input

          type="file"

          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-4">
          <div class="w-20 h-20 bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl flex items-center justify-center text-white">
            <svg class="w-8 h-8" fill="currentColor" viewBox="0 0 20 20">
              <path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path>
              <path fill-rule="evenodd" d="M4 5a2 2 0 012-2v1a1 1 0 001 1h6a1 1 0 001-1V3a2 2 0 012 2v6.5a1.5 1.5 0 01-1.5 1.5h-7A1.5 1.5 0 016 11.5V5z" clip-rule="evenodd"></path>
            </svg>
          </div>
          <div>
            <h3 class="text-xl font-semibold text-gray-200 mb-2">Upload Current RFP Document</h3>
            <p class="text-gray-300 mb-2">Click to browse or drag and drop the RFP file</p>
            <p class="text-sm text-gray-400">Supports PDF, DOCX, DOC, and TXT files</p>
          </div>
        </div>
      </div>
    </div>
  {:else}
    <!-- Current RFP Display -->
    <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>
            <h3 class="text-lg font-semibold text-white">Current RFP Document</h3>
            <p class="text-gray-300 text-sm">Metadata extracted (content not stored)</p>
          </div>
          <button

            on:click={removeCurrentRfp}

            class="bg-red-500/20 hover:bg-red-500/30 text-red-400 px-4 py-2 rounded-lg font-medium transition-colors"

          >
            Remove
          </button>
        </div>
      </div>
      
      <div class="p-4">
        {#if $currentRfp}
          <div class="border border-gray-600 bg-gray-700/30 rounded-lg p-4">
            <div class="flex items-start justify-between">
              <div class="flex-1">
                <div class="flex items-center space-x-3 mb-3">
                  <div class="w-8 h-8 bg-blue-500/20 rounded flex items-center justify-center text-blue-300">
                    <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                      <path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path>
                      <path fill-rule="evenodd" d="M4 5a2 2 0 012-2v1a1 1 0 001 1h6a1 1 0 001-1V3a2 2 0 012 2v6.5a1.5 1.5 0 01-1.5 1.5h-7A1.5 1.5 0 016 11.5V5z" clip-rule="evenodd"></path>
                  </svg>
                </div>
                <div>
                  <h4 class="font-medium text-gray-200">{$currentRfp.name}</h4>
                  <p class="text-sm text-gray-400">
                    Size: {($currentRfp.size / 1024 / 1024).toFixed(1)} MB β€’ 
                    {$currentRfp.pageCount} pages (estimated) β€’ 
                    {$currentRfp.quality} quality
                  </p>
                  <p class="text-xs text-blue-400 mt-1">
                    πŸ“Š Metadata Only - Content not stored for privacy
                  </p>
                </div>
              </div>
              </div>
            </div>
          </div>
        {:else}
          <div class="border border-gray-600 bg-gray-700/30 rounded-lg p-4">
            <p class="text-gray-400 text-center">No current RFP uploaded</p>
          </div>
        {/if}
        
        <!-- Processing and Content Section -->
        {#if isProcessing}
          <div class="bg-blue-500/10 border border-blue-500/20 rounded-lg p-3 mt-4">
            <div class="flex items-center space-x-3">
              <div class="animate-spin w-5 h-5 border-2 border-blue-500 border-t-transparent rounded-full"></div>
              <span class="text-blue-300">Processing document and extracting content...</span>
            </div>
          </div>
        {:else if extractedContent}
          <div class="bg-green-500/10 border border-green-500/20 rounded-lg p-4 mt-4">
            <h5 class="font-medium text-green-300 mb-2">βœ“ Document Processed Successfully</h5>
            <p class="text-green-200 text-sm mb-3">Content extracted: {extractedContent.length.toLocaleString()} characters from {documentInfo?.name || 'PDF document'}</p>
            
            <div class="bg-gray-800 rounded p-3 max-h-96 overflow-y-auto">
              <pre class="text-xs text-gray-300 whitespace-pre-wrap">{showFullContent ? extractedContent : extractedContent.substring(0, 5000)}{!showFullContent && extractedContent.length > 5000 ? '...' : ''}</pre>
            </div>
            
            {#if extractedContent.length > 5000}
              <div class="mt-2 flex justify-center">
                <button

                  on:click={() => showFullContent = !showFullContent}
                  class="text-blue-400 hover:text-blue-300 text-sm underline"
                >
                  {showFullContent ? 'Show Preview Only' : `Show Full Content (${Math.round(extractedContent.length / 1000)}k characters)`}
                </button>
              </div>
            {/if}
          </div>
        {/if}
        
        {#if extractedContent}
          <div class="mt-4 flex justify-end">
            <button

              on:click={proceedToQuestions}

              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>
        {/if}
      </div>
    </div>
  {/if}

  <!-- Tips Section -->
  <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">Upload Tips</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 Results:</h4>
        <ul class="space-y-1">
          <li>β€’ Upload the complete RFP document</li>
          <li>β€’ Ensure questions are clearly formatted</li>
          <li>β€’ Include all sections and requirements</li>
          <li>β€’ Use high-quality, readable documents</li>
        </ul>
      </div>
      <div>
        <h4 class="font-medium mb-2 text-gray-200">What We Extract:</h4>
        <ul class="space-y-1">
          <li>β€’ Individual questions and requirements</li>
          <li>β€’ Section headers and structure</li>
          <li>β€’ Evaluation criteria</li>
          <li>β€’ Submission requirements</li>
        </ul>
      </div>
    </div>
  </div>
</div>