File size: 2,724 Bytes
dd4a03a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useCallback, useState } from 'react'
import type { FormEvent } from 'react'
import { scrapeAndIndex } from '../api/client.ts'
import { useSession } from '../context/SessionContext.tsx'
import { useToast } from './shared/Toast.tsx'
import Loading from './shared/Loading.tsx'
import './web.css'

interface WebImportViewProps {
  onIndexed: () => void
}

export default function WebImportView({ onIndexed }: WebImportViewProps) {
  const [url, setUrl] = useState('')
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [result, setResult] = useState<{ message: string; type: 'success' | 'error' } | null>(null)
  const { sessionId } = useSession()
  const { showToast } = useToast()

  const handleSubmit = useCallback(
    async (e: FormEvent<HTMLFormElement>) => {
      e.preventDefault()
      if (!url.trim()) return

      setIsSubmitting(true)
      setResult(null)
      try {
        const res = await scrapeAndIndex({ url: url.trim(), session_id: sessionId })
        setResult({ message: res.message, type: 'success' })
        showToast(res.message, 'success')
        setUrl('')
        onIndexed()
      } catch (err) {
        const message = err instanceof Error ? err.message : 'Scraping failed'
        setResult({ message, type: 'error' })
        showToast(message, 'error')
      } finally {
        setIsSubmitting(false)
      }
    },
    [url, sessionId, showToast, onIndexed],
  )

  return (
    <div className="view-container active">
      <div className="view-header">
        <h2 className="view-title">Import from Web</h2>
        <p className="view-description">Extract and index content from any webpage</p>
      </div>

      <div className="content-card">
        <form className="web-form" onSubmit={handleSubmit}>
          <div className="input-group">
            <span className="input-icon">🔗</span>
            <input
              type="url"
              className="input-field"
              placeholder="https://example.com/article"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
              required
            />
          </div>
          <button type="submit" className="btn-primary btn-large" disabled={isSubmitting}>
            {isSubmitting ? (
              <>
                <Loading />
                <span>Fetching…</span>
              </>
            ) : (
              <>
                <span>Fetch & Index Content</span>
                <span className="btn-arrow">→</span>
              </>
            )}
          </button>
        </form>
        {result && (
          <div className={`result-message show ${result.type}`}>{result.message}</div>
        )}
      </div>
    </div>
  )
}