File size: 4,006 Bytes
98847a8
 
b087e88
503a577
 
 
98847a8
ed37070
 
 
 
503a577
 
ed37070
 
 
503a577
 
 
 
ed37070
 
 
98847a8
ed37070
98847a8
 
 
 
 
 
 
 
 
 
 
ed37070
98847a8
ed37070
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98847a8
 
 
 
 
 
 
 
503a577
 
98847a8
 
 
 
ed37070
 
 
98847a8
ed37070
98847a8
 
 
 
 
 
 
 
 
ed37070
98847a8
ed37070
 
 
98847a8
ed37070
98847a8
 
 
 
 
 
 
 
 
ed37070
 
 
98847a8
 
 
503a577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98847a8
 
 
 
 
 
 
 
 
 
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
import React, { useState, useEffect } from 'react'
import API from '../API'
import LoadingSpinner from './LoadingSpinner'
import ImageGallery from './ImageGallery'
import AudioGallery from './AudioGallery'
import VideoGallery from './VideoGallery'

interface ExamplesProps {
  fileType: 'image' | 'audio' | 'video'
}

// Move ExamplesData type export to allow import in Galleries.tsx
export type ExamplesData = {
  image_url: string
  audio_url?: string
  video_url?: string
  name: string
  metadata: {
    [key: string]: string | boolean
  }
}

const Examples = ({ fileType }: ExamplesProps) => {
  const [examples, setExamples] = useState<{
    [model: string]: { [attack: string]: ExamplesData[] }
  }>({})
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [selectedModel, setSelectedModel] = useState<string | null>(null)
  const [selectedAttack, setSelectedAttack] = useState<string | null>(null)

  useEffect(() => {
    setLoading(true)
    setError(null)
    API.fetchExamplesByType(fileType)
      .then((data) => {
        // data is a dictionary from {[model]: {[attack]: {image_url, audio_url, video_url, description}}}
        setExamples(data)

        // get the first model and attack if available
        const models = Object.keys(data)
        if (models.length > 0) {
          setSelectedModel(models[0])
          const attacks = Object.keys(data[models[0]])
          if (attacks.length > 0) {
            setSelectedAttack(attacks[0]) // Set the first attack of the first model
          } else {
            setSelectedAttack(null) // No attacks available
          }
        } else {
          setSelectedModel(null)
          setSelectedAttack(null) // No models available
        }

        // Reset loading state
        setLoading(false)
      })
      .catch((err) => {
        setError(err.message)
        setLoading(false)
      })
  }, [fileType])

  if (loading) {
    return <LoadingSpinner />
  }

  return (
    <div className="examples-container">
      <div className="selectors-container flex flex-col md:flex-row gap-4 mb-4">
        <fieldset className="fieldset">
          <legend className="fieldset-legend">Model</legend>
          <select
            className="select select-bordered w-full"
            value={selectedModel || ''}
            onChange={(e) => setSelectedModel(e.target.value || null)}
          >
            {Object.keys(examples).map((model) => (
              <option key={model} value={model}>
                {model}
              </option>
            ))}
          </select>
        </fieldset>

        {selectedModel && (
          <fieldset className="fieldset">
            <legend className="fieldset-legend">Attack</legend>
            <select
              className="select select-bordered w-full"
              value={selectedAttack || ''}
              onChange={(e) => setSelectedAttack(e.target.value || null)}
            >
              {Object.keys(examples[selectedModel]).map((attack) => (
                <option key={attack} value={attack}>
                  {attack}
                </option>
              ))}
            </select>
          </fieldset>
        )}
      </div>

      {error && <p className="error">Error: {error}</p>}

      {selectedModel && selectedAttack && fileType === 'image' && (
        <ImageGallery
          selectedModel={selectedModel}
          selectedAttack={selectedAttack}
          examples={examples}
        />
      )}
      {selectedModel && selectedAttack && fileType === 'audio' && (
        <AudioGallery
          selectedModel={selectedModel}
          selectedAttack={selectedAttack}
          examples={examples}
        />
      )}
      {selectedModel && selectedAttack && fileType === 'video' && (
        <VideoGallery
          selectedModel={selectedModel}
          selectedAttack={selectedAttack}
          examples={examples}
        />
      )}
    </div>
  )
}

export default Examples