File size: 7,964 Bytes
c492c3f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
const TASKS = [
  { id: 'easy_harassment',    label: 'Easy โ€” Clear Harassment',        diff: 'EASY',   color: '#4ade80' },
  { id: 'medium_ambiguous',   label: 'Medium โ€” Ambiguous Review',      diff: 'MED',    color: '#f0a500' },
  { id: 'hard_misinformation',label: 'Hard โ€” Health Misinformation',   diff: 'HARD',   color: '#f87171' },
]

const GEO_LABELS = { US: '๐Ÿ‡บ๐Ÿ‡ธ US', EU: '๐Ÿ‡ช๐Ÿ‡บ EU', IN: '๐Ÿ‡ฎ๐Ÿ‡ณ IN' }

function MetaBadge({ label, value, accent }) {
  return (
    <div className="flex flex-col gap-1 p-3 bg-[#0f0f1a] border border-[#1f1f35] rounded">
      <span className="text-[9px] text-[#3a3f5a] tracking-[0.15em] uppercase">{label}</span>
      <span className="text-sm font-medium" style={{ color: accent || '#dde1f0' }}>{value}</span>
    </div>
  )
}

function Section({ title, children }) {
  return (
    <div className="border border-[#1f1f35] rounded overflow-hidden">
      <div className="px-3 py-1.5 bg-[#0f0f1a] border-b border-[#1f1f35]">
        <span className="text-[9px] text-[#3a3f5a] tracking-[0.2em] uppercase">{title}</span>
      </div>
      <div className="p-3">{children}</div>
    </div>
  )
}

export default function PostPanel({ selectedTask, onTaskChange, observation, loading, onRun, hideSelector }) {
  const task = TASKS.find(t => t.id === selectedTask) || TASKS[0]

  return (
    <div className="flex flex-col h-full border-r border-[#1f1f35] overflow-y-auto">

      {/* Panel header */}
      <div className="px-5 py-3 border-b border-[#1f1f35] bg-[#0a0a14]">
        <div className="text-[9px] text-[#3a3f5a] tracking-[0.2em] uppercase mb-0.5">Input</div>
        <div className="font-display text-base font-semibold text-[#dde1f0]">Content Review</div>
      </div>

      <div className="flex-1 p-5 space-y-4">

        {/* Task selector โ€” hidden when coming from scenario explorer */}
        {!hideSelector && (
          <div className="space-y-2">
            <label className="text-[9px] text-[#3a3f5a] tracking-[0.18em] uppercase block">
              Task Scenario
            </label>
            <div className="relative">
              <select
                value={selectedTask}
                onChange={e => onTaskChange(e.target.value)}
                disabled={loading}
                className="w-full appearance-none bg-[#0f0f1a] border border-[#1f1f35] text-[#dde1f0] text-xs px-3 py-2.5 rounded focus:outline-none focus:border-[#f0a500] cursor-pointer disabled:opacity-50 transition-colors pr-8"
              >
                {TASKS.map(t => (
                  <option key={t.id} value={t.id}>{t.label}</option>
                ))}
              </select>
              <div className="absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none text-[#3a3f5a]">
                โ–พ
              </div>
            </div>
            {/* Difficulty badge */}
            <div className="flex items-center gap-2">
              <div
                className="text-[9px] px-2 py-0.5 rounded tracking-widest font-medium"
                style={{ color: task.color, background: `${task.color}18`, border: `1px solid ${task.color}40` }}
              >
                {task.diff}
              </div>
              <span className="text-[10px] text-[#3a3f5a]">difficulty</span>
            </div>
          </div>
        )}

        {/* Run button */}
        <button
          onClick={onRun}
          disabled={loading}
          className="w-full py-3 px-4 rounded border transition-all duration-200 font-medium text-xs tracking-widest uppercase disabled:opacity-60 disabled:cursor-not-allowed"
          style={
            loading
              ? { color: '#f0a500', borderColor: 'rgba(240,165,0,0.3)', background: 'rgba(240,165,0,0.04)' }
              : {
                  color: '#080810',
                  background: '#f0a500',
                  borderColor: '#f0a500',
                  boxShadow: '0 0 20px rgba(240,165,0,0.25)',
                }
          }
        >
          {loading ? (
            <span className="flex items-center justify-center gap-2">
              <span className="animate-scanPulse">โ—Ž</span>
              <span>ANALYZING...</span>
            </span>
          ) : (
            'โ–ถ  RUN AI AGENT'
          )}
        </button>

        {/* Divider */}
        <div className="border-t border-[#1f1f35]" />

        {/* Post content */}
        {!observation && !loading && (
          <div
            className="border border-dashed border-[#1f1f35] rounded p-5 text-center"
          >
            <div className="text-[#3a3f5a] text-xs mb-1">โ—Œ</div>
            <div className="text-[11px] text-[#3a3f5a]">
              Post content will appear after the agent runs
            </div>
          </div>
        )}

        {loading && (
          <div className="space-y-2">
            {[0.9, 0.7, 0.85, 0.6].map((w, i) => (
              <div
                key={i}
                className="h-3 bg-[#0f0f1a] rounded animate-pulse border border-[#1f1f35]"
                style={{ width: `${w * 100}%`, animationDelay: `${i * 0.1}s` }}
              />
            ))}
          </div>
        )}

        {observation && !loading && (
          <>
            {/* Post content card */}
            <Section title="Post Content">
              <p className="text-sm leading-relaxed text-[#dde1f0] italic">
                &ldquo;{observation.content}&rdquo;
              </p>
            </Section>

            {/* Metadata grid */}
            <div className="grid grid-cols-3 gap-2">
              <MetaBadge label="Geo"     value={GEO_LABELS[observation.geo] || observation.geo} accent="#60a5fa" />
              <MetaBadge label="Reports" value={observation.reports} accent="#f87171" />
              <MetaBadge
                label="Engagement"
                value={`${(observation.engagement?.likes || 0) + (observation.engagement?.shares || 0) + (observation.engagement?.comments || 0)}`}
                accent="#f0a500"
              />
            </div>

            {/* Engagement breakdown */}
            <div className="grid grid-cols-3 gap-2">
              <MetaBadge label="Likes"    value={observation.engagement?.likes    ?? 'โ€“'} />
              <MetaBadge label="Shares"   value={observation.engagement?.shares   ?? 'โ€“'} />
              <MetaBadge label="Comments" value={observation.engagement?.comments ?? 'โ€“'} />
            </div>

            {/* User history */}
            {observation.user_history && (
              <Section title="User History">
                <ul className="space-y-1.5">
                  {observation.user_history.map((h, i) => (
                    <li key={i} className="flex items-start gap-2 text-[11px]">
                      <span className="text-[#f87171] flex-shrink-0 mt-px">โ—</span>
                      <span className="text-[#5a5f7a] leading-relaxed">{h}</span>
                    </li>
                  ))}
                </ul>
              </Section>
            )}

            {/* Thread context */}
            {observation.thread_context && (
              <Section title="Thread Context">
                <ul className="space-y-1.5">
                  {observation.thread_context.map((t, i) => (
                    <li key={i} className="flex items-start gap-2 text-[11px]">
                      <span className="text-[#60a5fa] flex-shrink-0 mt-px">โ€บ</span>
                      <span className="text-[#5a5f7a] leading-relaxed">{t}</span>
                    </li>
                  ))}
                </ul>
              </Section>
            )}

            {/* Policy clause */}
            {observation.policy_clause && (
              <Section title="Policy Clause">
                <p className="text-[11px] text-[#5a5f7a] leading-relaxed">
                  {observation.policy_clause}
                </p>
              </Section>
            )}
          </>
        )}
      </div>
    </div>
  )
}