SCGR commited on
Commit
c69ce84
·
1 Parent(s): a41ced5

fix build error

Browse files
frontend/src/components/ExportModal.tsx CHANGED
@@ -214,7 +214,7 @@ export default function ExportModal({
214
  name="crisis-maps"
215
  label={`Crisis Maps (${crisisMapsCount} images)`}
216
  value={crisisMapsSelected}
217
- onChange={(value, _name) => setCrisisMapsSelected(value)}
218
  disabled={isLoading}
219
  />
220
  </div>
@@ -224,7 +224,7 @@ export default function ExportModal({
224
  name="drone-images"
225
  label={`Drone Images (${droneImagesCount} images)`}
226
  value={droneImagesSelected}
227
- onChange={(value, _name) => setDroneImagesSelected(value)}
228
  disabled={isLoading}
229
  />
230
  </div>
 
214
  name="crisis-maps"
215
  label={`Crisis Maps (${crisisMapsCount} images)`}
216
  value={crisisMapsSelected}
217
+ onChange={(value) => setCrisisMapsSelected(value)}
218
  disabled={isLoading}
219
  />
220
  </div>
 
224
  name="drone-images"
225
  label={`Drone Images (${droneImagesCount} images)`}
226
  value={droneImagesSelected}
227
+ onChange={(value) => setDroneImagesSelected(value)}
228
  disabled={isLoading}
229
  />
230
  </div>
frontend/src/components/FilterBar.tsx CHANGED
@@ -1,7 +1,6 @@
1
  import React from 'react';
2
  import { Container, TextInput, SelectInput, MultiSelectInput, Button } from '@ifrc-go/ui';
3
- import { useFilterContext } from '../contexts/FilterContext';
4
- import styles from './FilterBar.module.css';
5
 
6
  interface FilterBarProps {
7
  sources: {s_code: string, label: string}[];
 
1
  import React from 'react';
2
  import { Container, TextInput, SelectInput, MultiSelectInput, Button } from '@ifrc-go/ui';
3
+ import { useFilterContext } from '../hooks/useFilterContext';
 
4
 
5
  interface FilterBarProps {
6
  sources: {s_code: string, label: string}[];
frontend/src/components/HeaderNav.tsx CHANGED
@@ -8,7 +8,7 @@ import {
8
  GoMainIcon,
9
  SettingsIcon,
10
  } from "@ifrc-go/icons";
11
- import { useAdmin } from "../contexts/AdminContext";
12
 
13
  declare global {
14
  interface Window {
@@ -25,7 +25,6 @@ const navItems = [
25
  export default function HeaderNav() {
26
  const location = useLocation();
27
  const navigate = useNavigate();
28
- const { } = useAdmin();
29
 
30
  return (
31
  <nav className="border-b border-gray-200 bg-white shadow-sm sticky top-0 z-50 backdrop-blur-sm bg-white/95">
 
8
  GoMainIcon,
9
  SettingsIcon,
10
  } from "@ifrc-go/icons";
11
+
12
 
13
  declare global {
14
  interface Window {
 
25
  export default function HeaderNav() {
26
  const location = useLocation();
27
  const navigate = useNavigate();
 
28
 
29
  return (
30
  <nav className="border-b border-gray-200 bg-white shadow-sm sticky top-0 z-50 backdrop-blur-sm bg-white/95">
frontend/src/contexts/AdminContext.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useState, useEffect } from 'react';
2
  import type { ReactNode } from 'react';
3
 
4
  interface AdminContextType {
@@ -9,15 +9,7 @@ interface AdminContextType {
9
  verifyToken: () => Promise<void>;
10
  }
11
 
12
- const AdminContext = createContext<AdminContextType | undefined>(undefined);
13
-
14
- export const useAdmin = () => {
15
- const context = useContext(AdminContext);
16
- if (context === undefined) {
17
- throw new Error('useAdmin must be used within an AdminProvider');
18
- }
19
- return context;
20
- };
21
 
22
  interface AdminProviderProps {
23
  children: ReactNode;
@@ -108,3 +100,5 @@ export const AdminProvider: React.FC<AdminProviderProps> = ({ children }) => {
108
  </AdminContext.Provider>
109
  );
110
  };
 
 
 
1
+ import React, { createContext, useState, useEffect } from 'react';
2
  import type { ReactNode } from 'react';
3
 
4
  interface AdminContextType {
 
9
  verifyToken: () => Promise<void>;
10
  }
11
 
12
+ export const AdminContext = createContext<AdminContextType | undefined>(undefined);
 
 
 
 
 
 
 
 
13
 
14
  interface AdminProviderProps {
15
  children: ReactNode;
 
100
  </AdminContext.Provider>
101
  );
102
  };
103
+
104
+
frontend/src/contexts/FilterContext.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { createContext, useContext, useState } from 'react';
2
  import type { ReactNode } from 'react';
3
 
4
  interface FilterContextType {
@@ -24,15 +24,7 @@ interface FilterContextType {
24
  clearAllFilters: () => void;
25
  }
26
 
27
- const FilterContext = createContext<FilterContextType | undefined>(undefined);
28
-
29
- export const useFilterContext = () => {
30
- const context = useContext(FilterContext);
31
- if (context === undefined) {
32
- throw new Error('useFilterContext must be used within a FilterProvider');
33
- }
34
- return context;
35
- };
36
 
37
  interface FilterProviderProps {
38
  children: ReactNode;
@@ -81,3 +73,5 @@ export const FilterProvider: React.FC<FilterProviderProps> = ({ children }) => {
81
  </FilterContext.Provider>
82
  );
83
  };
 
 
 
1
+ import React, { createContext, useState } from 'react';
2
  import type { ReactNode } from 'react';
3
 
4
  interface FilterContextType {
 
24
  clearAllFilters: () => void;
25
  }
26
 
27
+ export const FilterContext = createContext<FilterContextType | undefined>(undefined);
 
 
 
 
 
 
 
 
28
 
29
  interface FilterProviderProps {
30
  children: ReactNode;
 
73
  </FilterContext.Provider>
74
  );
75
  };
76
+
77
+
frontend/src/hooks/useAdmin.ts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useContext } from 'react';
2
+ import { AdminContext } from '../contexts/AdminContext';
3
+
4
+ export const useAdmin = () => {
5
+ const context = useContext(AdminContext);
6
+ if (context === undefined) {
7
+ throw new Error('useAdmin must be used within an AdminProvider');
8
+ }
9
+ return context;
10
+ };
frontend/src/hooks/useFilterContext.ts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useContext } from 'react';
2
+ import { FilterContext } from '../contexts/FilterContext';
3
+
4
+ export const useFilterContext = () => {
5
+ const context = useContext(FilterContext);
6
+ if (context === undefined) {
7
+ throw new Error('useFilterContext must be used within a FilterProvider');
8
+ }
9
+ return context;
10
+ };
frontend/src/pages/AdminPage/AdminPage.tsx CHANGED
@@ -1,53 +1,59 @@
1
  // Force rebuild - Frontend updated with edit prompt functionality
2
- import React, { useState, useEffect } from 'react';
3
- import { useAdmin } from '../../contexts/AdminContext';
4
  import { PageContainer, Heading, Button, Container, TextInput, SelectInput } from '@ifrc-go/ui';
5
  import styles from './AdminPage.module.css';
6
 
7
  const SELECTED_MODEL_KEY = 'selectedVlmModel';
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  export default function AdminPage() {
10
  const { isAuthenticated, isLoading, login, logout } = useAdmin();
11
  const [password, setPassword] = useState('');
12
  const [error, setError] = useState('');
13
  const [isLoggingIn, setIsLoggingIn] = useState(false);
14
 
15
- const [availableModels, setAvailableModels] = useState<Array<{
16
- m_code: string;
17
- label: string;
18
- model_type: string;
19
- is_available: boolean;
20
- provider?: string;
21
- model_id?: string;
22
- config?: {
23
- provider?: string;
24
- model_id?: string;
25
- model?: string;
26
- stub?: boolean;
27
- };
28
- }>>([]);
29
  const [selectedModel, setSelectedModel] = useState<string>('');
30
 
31
  // Prompts state
32
- const [availablePrompts, setAvailablePrompts] = useState<Array<{
33
- p_code: string;
34
- label: string;
35
- metadata_instructions?: string;
36
- image_type: string;
37
- is_active: boolean;
38
- }>>([]);
39
 
40
- const [imageTypes, setImageTypes] = useState<Array<{
41
- image_type: string;
42
- label: string;
43
- }>>([]);
44
 
45
  // Prompt management state
46
  const [showEditPromptForm, setShowEditPromptForm] = useState(false);
47
  const [showAddPromptForm, setShowAddPromptForm] = useState(false);
48
  const [addingPromptType, setAddingPromptType] = useState<'crisis_map' | 'drone_image' | null>(null);
49
- const [editingPrompt, setEditingPrompt] = useState<any>(null);
50
- const [newPromptData, setNewPromptData] = useState({
51
  p_code: '',
52
  label: '',
53
  metadata_instructions: '',
@@ -58,8 +64,8 @@ export default function AdminPage() {
58
  // Model management state
59
  const [showAddModelForm, setShowAddModelForm] = useState(false);
60
  const [showEditModelForm, setShowEditModelForm] = useState(false);
61
- const [editingModel, setEditingModel] = useState<any>(null);
62
- const [newModelData, setNewModelData] = useState({
63
  m_code: '',
64
  label: '',
65
  model_type: 'custom',
@@ -79,21 +85,7 @@ export default function AdminPage() {
79
  const [testResults, setTestResults] = useState<string>('');
80
  const [testResultsTitle, setTestResultsTitle] = useState<string>('');
81
 
82
- useEffect(() => {
83
- if (isAuthenticated) {
84
- fetchModels();
85
- fetchPrompts();
86
- fetchImageTypes();
87
- }
88
- }, [isAuthenticated]);
89
-
90
- // Debug effect to see when prompts state changes
91
- useEffect(() => {
92
- console.log('=== availablePrompts state changed ===');
93
- console.log('New prompts state:', availablePrompts);
94
- }, [availablePrompts]);
95
-
96
- const fetchModels = () => {
97
  fetch('/api/models')
98
  .then(r => r.json())
99
  .then(modelsData => {
@@ -117,15 +109,14 @@ export default function AdminPage() {
117
  .catch(() => {
118
  // Handle error silently
119
  });
120
- };
121
 
122
- const fetchPrompts = () => {
123
  console.log('=== fetchPrompts called ===');
124
  fetch('/api/prompts')
125
  .then(r => r.json())
126
  .then(promptsData => {
127
  console.log('Prompts data received:', promptsData);
128
- console.log('Current availablePrompts state:', availablePrompts);
129
  setAvailablePrompts(promptsData || []);
130
  console.log('State update triggered with:', promptsData || []);
131
  })
@@ -133,9 +124,9 @@ export default function AdminPage() {
133
  console.error('Error fetching prompts:', error);
134
  // Handle error silently
135
  });
136
- };
137
 
138
- const fetchImageTypes = () => {
139
  fetch('/api/image-types')
140
  .then(r => r.json())
141
  .then(imageTypesData => {
@@ -145,9 +136,19 @@ export default function AdminPage() {
145
  .catch(() => {
146
  // Handle error silently
147
  });
148
- };
 
 
 
 
 
 
 
 
 
149
 
150
- const handleEditPrompt = (prompt: any) => {
 
151
  setEditingPrompt(prompt);
152
  setNewPromptData({
153
  p_code: prompt.p_code,
@@ -161,7 +162,12 @@ export default function AdminPage() {
161
 
162
  const handleSavePrompt = async () => {
163
  try {
164
- const response = await fetch(`/api/prompts/${editingPrompt.p_code}`, {
 
 
 
 
 
165
  method: 'PUT',
166
  headers: {
167
  'Content-Type': 'application/json',
@@ -184,8 +190,8 @@ export default function AdminPage() {
184
  const errorData = await response.json();
185
  alert(`Failed to update prompt: ${errorData.error || 'Unknown error'}`);
186
  }
187
- } catch (error) {
188
- alert(`Error updating prompt: ${error}`);
189
  }
190
  };
191
 
@@ -205,7 +211,7 @@ export default function AdminPage() {
205
  const errorData = await response.json();
206
  alert(`Failed to toggle prompt active status: ${errorData.detail || 'Unknown error'}`);
207
  }
208
- } catch (error) {
209
  alert('Error toggling prompt active status');
210
  }
211
  };
@@ -248,8 +254,8 @@ export default function AdminPage() {
248
  const errorData = await response.json();
249
  alert(`Failed to create prompt: ${errorData.detail || 'Unknown error'}`);
250
  }
251
- } catch (error) {
252
- alert(`Error creating prompt: ${error}`);
253
  }
254
  };
255
 
@@ -277,7 +283,7 @@ export default function AdminPage() {
277
  const errorData = await response.json();
278
  alert(`Failed to toggle model availability: ${errorData.error || 'Unknown error'}`);
279
  }
280
- } catch {
281
  alert('Error toggling model availability');
282
  }
283
  };
@@ -340,7 +346,7 @@ Model "${newModelData.label}" added successfully!
340
  }
341
  };
342
 
343
- const handleEditModel = (model: any) => {
344
  setEditingModel(model);
345
  setNewModelData({
346
  m_code: model.m_code,
@@ -368,6 +374,11 @@ Model "${newModelData.label}" added successfully!
368
 
369
  console.log('Update payload:', updatePayload);
370
 
 
 
 
 
 
371
  const response = await fetch(`/api/admin/models/${editingModel.m_code}`, {
372
  method: 'PUT',
373
  headers: {
@@ -429,7 +440,7 @@ Model "${newModelData.label}" added successfully!
429
  const errorData = await response.json();
430
  alert(`Failed to delete model: ${errorData.detail || 'Unknown error'}`);
431
  }
432
- } catch (error) {
433
  alert('Error deleting model');
434
  }
435
  };
@@ -449,7 +460,7 @@ Model "${newModelData.label}" added successfully!
449
  if (!success) {
450
  setError('Invalid password');
451
  }
452
- } catch (err) {
453
  setError('Login failed. Please try again.');
454
  } finally {
455
  setIsLoggingIn(false);
 
1
  // Force rebuild - Frontend updated with edit prompt functionality
2
+ import React, { useState, useEffect, useCallback } from 'react';
3
+ import { useAdmin } from '../../hooks/useAdmin';
4
  import { PageContainer, Heading, Button, Container, TextInput, SelectInput } from '@ifrc-go/ui';
5
  import styles from './AdminPage.module.css';
6
 
7
  const SELECTED_MODEL_KEY = 'selectedVlmModel';
8
 
9
+ interface PromptData {
10
+ p_code: string;
11
+ label: string;
12
+ metadata_instructions?: string;
13
+ image_type: string;
14
+ is_active: boolean;
15
+ }
16
+
17
+ interface ModelData {
18
+ m_code: string;
19
+ label: string;
20
+ model_type: string;
21
+ provider?: string;
22
+ model_id?: string;
23
+ config?: {
24
+ provider?: string;
25
+ model_id?: string;
26
+ model?: string;
27
+ stub?: boolean;
28
+ };
29
+ is_available: boolean;
30
+ }
31
+
32
+ interface ImageTypeData {
33
+ image_type: string;
34
+ label: string;
35
+ }
36
+
37
  export default function AdminPage() {
38
  const { isAuthenticated, isLoading, login, logout } = useAdmin();
39
  const [password, setPassword] = useState('');
40
  const [error, setError] = useState('');
41
  const [isLoggingIn, setIsLoggingIn] = useState(false);
42
 
43
+ const [availableModels, setAvailableModels] = useState<ModelData[]>([]);
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  const [selectedModel, setSelectedModel] = useState<string>('');
45
 
46
  // Prompts state
47
+ const [availablePrompts, setAvailablePrompts] = useState<PromptData[]>([]);
 
 
 
 
 
 
48
 
49
+ const [imageTypes, setImageTypes] = useState<ImageTypeData[]>([]);
 
 
 
50
 
51
  // Prompt management state
52
  const [showEditPromptForm, setShowEditPromptForm] = useState(false);
53
  const [showAddPromptForm, setShowAddPromptForm] = useState(false);
54
  const [addingPromptType, setAddingPromptType] = useState<'crisis_map' | 'drone_image' | null>(null);
55
+ const [editingPrompt, setEditingPrompt] = useState<PromptData | null>(null);
56
+ const [newPromptData, setNewPromptData] = useState<PromptData>({
57
  p_code: '',
58
  label: '',
59
  metadata_instructions: '',
 
64
  // Model management state
65
  const [showAddModelForm, setShowAddModelForm] = useState(false);
66
  const [showEditModelForm, setShowEditModelForm] = useState(false);
67
+ const [editingModel, setEditingModel] = useState<ModelData | null>(null);
68
+ const [newModelData, setNewModelData] = useState<ModelData>({
69
  m_code: '',
70
  label: '',
71
  model_type: 'custom',
 
85
  const [testResults, setTestResults] = useState<string>('');
86
  const [testResultsTitle, setTestResultsTitle] = useState<string>('');
87
 
88
+ const fetchModels = useCallback(() => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  fetch('/api/models')
90
  .then(r => r.json())
91
  .then(modelsData => {
 
109
  .catch(() => {
110
  // Handle error silently
111
  });
112
+ }, []);
113
 
114
+ const fetchPrompts = useCallback(() => {
115
  console.log('=== fetchPrompts called ===');
116
  fetch('/api/prompts')
117
  .then(r => r.json())
118
  .then(promptsData => {
119
  console.log('Prompts data received:', promptsData);
 
120
  setAvailablePrompts(promptsData || []);
121
  console.log('State update triggered with:', promptsData || []);
122
  })
 
124
  console.error('Error fetching prompts:', error);
125
  // Handle error silently
126
  });
127
+ }, []);
128
 
129
+ const fetchImageTypes = useCallback(() => {
130
  fetch('/api/image-types')
131
  .then(r => r.json())
132
  .then(imageTypesData => {
 
136
  .catch(() => {
137
  // Handle error silently
138
  });
139
+ }, []);
140
+
141
+ useEffect(() => {
142
+ if (isAuthenticated) {
143
+ fetchModels();
144
+ fetchPrompts();
145
+ fetchImageTypes();
146
+ }
147
+ }, [isAuthenticated, fetchModels, fetchPrompts, fetchImageTypes]);
148
+
149
 
150
+
151
+ const handleEditPrompt = (prompt: PromptData) => {
152
  setEditingPrompt(prompt);
153
  setNewPromptData({
154
  p_code: prompt.p_code,
 
162
 
163
  const handleSavePrompt = async () => {
164
  try {
165
+ if (!editingPrompt) {
166
+ alert('No prompt selected for editing');
167
+ return;
168
+ }
169
+
170
+ const response = await fetch(`/api/prompts/${editingPrompt.p_code}`, {
171
  method: 'PUT',
172
  headers: {
173
  'Content-Type': 'application/json',
 
190
  const errorData = await response.json();
191
  alert(`Failed to update prompt: ${errorData.error || 'Unknown error'}`);
192
  }
193
+ } catch {
194
+ alert('Error updating prompt');
195
  }
196
  };
197
 
 
211
  const errorData = await response.json();
212
  alert(`Failed to toggle prompt active status: ${errorData.detail || 'Unknown error'}`);
213
  }
214
+ } catch {
215
  alert('Error toggling prompt active status');
216
  }
217
  };
 
254
  const errorData = await response.json();
255
  alert(`Failed to create prompt: ${errorData.detail || 'Unknown error'}`);
256
  }
257
+ } catch {
258
+ alert('Error creating prompt');
259
  }
260
  };
261
 
 
283
  const errorData = await response.json();
284
  alert(`Failed to toggle model availability: ${errorData.error || 'Unknown error'}`);
285
  }
286
+ } catch (_error) {
287
  alert('Error toggling model availability');
288
  }
289
  };
 
346
  }
347
  };
348
 
349
+ const handleEditModel = (model: ModelData) => {
350
  setEditingModel(model);
351
  setNewModelData({
352
  m_code: model.m_code,
 
374
 
375
  console.log('Update payload:', updatePayload);
376
 
377
+ if (!editingModel) {
378
+ alert('No model selected for editing');
379
+ return;
380
+ }
381
+
382
  const response = await fetch(`/api/admin/models/${editingModel.m_code}`, {
383
  method: 'PUT',
384
  headers: {
 
440
  const errorData = await response.json();
441
  alert(`Failed to delete model: ${errorData.detail || 'Unknown error'}`);
442
  }
443
+ } catch {
444
  alert('Error deleting model');
445
  }
446
  };
 
460
  if (!success) {
461
  setError('Invalid password');
462
  }
463
+ } catch {
464
  setError('Login failed. Please try again.');
465
  } finally {
466
  setIsLoggingIn(false);
frontend/src/pages/AnalyticsPage/AnalyticsPage.tsx CHANGED
@@ -353,7 +353,7 @@ export default function AnalyticsPage() {
353
 
354
  useEffect(() => {
355
  fetchLookupData();
356
- }, []);
357
 
358
  useEffect(() => {
359
  if (sourcesLookup.length > 0 && typesLookup.length > 0 && regionsLookup.length > 0 && modelsLookup.length > 0) {
@@ -590,7 +590,7 @@ export default function AnalyticsPage() {
590
  },
591
  ),
592
 
593
- ], [formatEditTime]);
594
 
595
  const editTimeColumns = useMemo(() => [
596
  createStringColumn<EditTimeData, number>(
@@ -618,7 +618,7 @@ export default function AnalyticsPage() {
618
  'Max Edit Time',
619
  (item) => formatEditTime(item.maxEditTime),
620
  ),
621
- ], [formatEditTime]);
622
 
623
  const percentageModifiedColumns = useMemo(() => [
624
  createStringColumn<PercentageModifiedData, number>(
@@ -1053,7 +1053,7 @@ export default function AnalyticsPage() {
1053
  };
1054
  })
1055
  .sort((a, b) => b.count - a.count);
1056
- }, [data]);
1057
 
1058
  const getImageTypeModelsTableData = useCallback((imageType: string) => {
1059
  if (!data) return [];
 
353
 
354
  useEffect(() => {
355
  fetchLookupData();
356
+ }, [fetchLookupData]);
357
 
358
  useEffect(() => {
359
  if (sourcesLookup.length > 0 && typesLookup.length > 0 && regionsLookup.length > 0 && modelsLookup.length > 0) {
 
590
  },
591
  ),
592
 
593
+ ], []);
594
 
595
  const editTimeColumns = useMemo(() => [
596
  createStringColumn<EditTimeData, number>(
 
618
  'Max Edit Time',
619
  (item) => formatEditTime(item.maxEditTime),
620
  ),
621
+ ], []);
622
 
623
  const percentageModifiedColumns = useMemo(() => [
624
  createStringColumn<PercentageModifiedData, number>(
 
1053
  };
1054
  })
1055
  .sort((a, b) => b.count - a.count);
1056
+ }, [data, getModelLabel]);
1057
 
1058
  const getImageTypeModelsTableData = useCallback((imageType: string) => {
1059
  if (!data) return [];
frontend/src/pages/ExplorePage/ExplorePage.tsx CHANGED
@@ -1,7 +1,7 @@
1
  import { useState, useEffect, useMemo } from 'react';
2
  import { useNavigate, useLocation } from 'react-router-dom';
3
  import { PageContainer, Container, SegmentInput, Spinner, Button } from '@ifrc-go/ui';
4
- import { useFilterContext } from '../../contexts/FilterContext';
5
  import FilterBar from '../../components/FilterBar';
6
  import styles from './ExplorePage.module.css';
7
  import ExportModal from '../../components/ExportModal';
 
1
  import { useState, useEffect, useMemo } from 'react';
2
  import { useNavigate, useLocation } from 'react-router-dom';
3
  import { PageContainer, Container, SegmentInput, Spinner, Button } from '@ifrc-go/ui';
4
+ import { useFilterContext } from '../../hooks/useFilterContext';
5
  import FilterBar from '../../components/FilterBar';
6
  import styles from './ExplorePage.module.css';
7
  import ExportModal from '../../components/ExportModal';
frontend/src/pages/HelpPage.tsx CHANGED
@@ -1,6 +1,6 @@
1
  import { PageContainer, Heading, Button } from '@ifrc-go/ui';
2
  import { useNavigate } from 'react-router-dom';
3
- import { useFilterContext } from '../contexts/FilterContext';
4
  import styles from './HelpPage.module.css';
5
 
6
  export default function HelpPage() {
 
1
  import { PageContainer, Heading, Button } from '@ifrc-go/ui';
2
  import { useNavigate } from 'react-router-dom';
3
+ import { useFilterContext } from '../hooks/useFilterContext';
4
  import styles from './HelpPage.module.css';
5
 
6
  export default function HelpPage() {
frontend/src/pages/MapDetailsPage/MapDetailPage.tsx CHANGED
@@ -3,8 +3,8 @@ import { useParams, useNavigate } from 'react-router-dom';
3
  import { useState, useEffect, useMemo, useCallback } from 'react';
4
  import { ChevronLeftLineIcon, ChevronRightLineIcon, DeleteBinLineIcon } from '@ifrc-go/icons';
5
  import styles from './MapDetailPage.module.css';
6
- import { useFilterContext } from '../../contexts/FilterContext';
7
- import { useAdmin } from '../../contexts/AdminContext';
8
  import ExportModal from '../../components/ExportModal';
9
 
10
  interface MapOut {
 
3
  import { useState, useEffect, useMemo, useCallback } from 'react';
4
  import { ChevronLeftLineIcon, ChevronRightLineIcon, DeleteBinLineIcon } from '@ifrc-go/icons';
5
  import styles from './MapDetailPage.module.css';
6
+ import { useFilterContext } from '../../hooks/useFilterContext';
7
+ import { useAdmin } from '../../hooks/useAdmin';
8
  import ExportModal from '../../components/ExportModal';
9
 
10
  interface MapOut {
frontend/src/pages/UploadPage/UploadPage.tsx CHANGED
@@ -102,7 +102,7 @@ export default function UploadPage() {
102
  setImageType(imageTypesData[0].image_type);
103
  }
104
  });
105
- }, [searchParams]);
106
 
107
  const handleNavigation = useCallback((to: string) => {
108
  if (to === '/upload' || to === '/') {
@@ -201,8 +201,8 @@ export default function UploadPage() {
201
  }
202
 
203
  if (data.generated) {
204
- // Extract the three parts from raw_json.extracted_metadata (same as regular upload flow)
205
- const extractedMetadataForParts = data.raw_json?.extracted_metadata;
206
  if (extractedMetadataForParts) {
207
  if (extractedMetadataForParts.description) {
208
  setDescription(extractedMetadataForParts.description);
@@ -219,8 +219,8 @@ export default function UploadPage() {
219
  setDraft(data.generated);
220
  }
221
 
222
- let extractedMetadata = data.raw_json?.extracted_metadata;
223
- console.log('Raw extracted_metadata:', extractedMetadata);
224
 
225
  if (!extractedMetadata && data.generated) {
226
  try {
@@ -642,7 +642,7 @@ export default function UploadPage() {
642
  setShowFallbackNotification(true);
643
  }
644
 
645
- const extractedMetadata = (capJson.raw_json as Record<string, unknown>)?.extracted_metadata;
646
  if (extractedMetadata) {
647
  const metadata = (extractedMetadata as Record<string, unknown>).metadata || extractedMetadata;
648
  if ((metadata as Record<string, unknown>).title) setTitle((metadata as Record<string, unknown>).title as string);
@@ -668,8 +668,8 @@ export default function UploadPage() {
668
  }
669
  }
670
 
671
- // Extract the three parts from raw_json.extracted_metadata
672
- const extractedMetadataForParts = (capJson.raw_json as Record<string, unknown>)?.extracted_metadata;
673
  if (extractedMetadataForParts) {
674
  if ((extractedMetadataForParts as Record<string, unknown>).description) {
675
  setDescription((extractedMetadataForParts as Record<string, unknown>).description as string);
@@ -761,7 +761,7 @@ export default function UploadPage() {
761
  setShowFallbackNotification(true);
762
  }
763
 
764
- const extractedMetadata = (capJson.raw_json as Record<string, unknown>)?.extracted_metadata;
765
  if (extractedMetadata) {
766
  const metadata = (extractedMetadata as Record<string, unknown>).metadata || extractedMetadata;
767
  if ((metadata as Record<string, unknown>).title) setTitle((metadata as Record<string, unknown>).title as string);
@@ -786,8 +786,8 @@ export default function UploadPage() {
786
  }
787
  }
788
 
789
- // Extract the three parts from raw_json.extracted_metadata
790
- const extractedMetadataForParts = (capJson.raw_json as Record<string, unknown>)?.extracted_metadata;
791
  if (extractedMetadataForParts) {
792
  if ((extractedMetadataForParts as Record<string, unknown>).description) {
793
  setDescription((extractedMetadataForParts as Record<string, unknown>).description as string);
 
102
  setImageType(imageTypesData[0].image_type);
103
  }
104
  });
105
+ }, [searchParams, imageType]);
106
 
107
  const handleNavigation = useCallback((to: string) => {
108
  if (to === '/upload' || to === '/') {
 
201
  }
202
 
203
  if (data.generated) {
204
+ // Extract the three parts from raw_json.metadata (same as regular upload flow)
205
+ const extractedMetadataForParts = data.raw_json?.metadata;
206
  if (extractedMetadataForParts) {
207
  if (extractedMetadataForParts.description) {
208
  setDescription(extractedMetadataForParts.description);
 
219
  setDraft(data.generated);
220
  }
221
 
222
+ let extractedMetadata = data.raw_json?.metadata;
223
+ console.log('Raw metadata:', extractedMetadata);
224
 
225
  if (!extractedMetadata && data.generated) {
226
  try {
 
642
  setShowFallbackNotification(true);
643
  }
644
 
645
+ const extractedMetadata = (capJson.raw_json as Record<string, unknown>)?.metadata;
646
  if (extractedMetadata) {
647
  const metadata = (extractedMetadata as Record<string, unknown>).metadata || extractedMetadata;
648
  if ((metadata as Record<string, unknown>).title) setTitle((metadata as Record<string, unknown>).title as string);
 
668
  }
669
  }
670
 
671
+ // Extract the three parts from raw_json.metadata
672
+ const extractedMetadataForParts = (capJson.raw_json as Record<string, unknown>)?.metadata;
673
  if (extractedMetadataForParts) {
674
  if ((extractedMetadataForParts as Record<string, unknown>).description) {
675
  setDescription((extractedMetadataForParts as Record<string, unknown>).description as string);
 
761
  setShowFallbackNotification(true);
762
  }
763
 
764
+ const extractedMetadata = (capJson.raw_json as Record<string, unknown>)?.metadata;
765
  if (extractedMetadata) {
766
  const metadata = (extractedMetadata as Record<string, unknown>).metadata || extractedMetadata;
767
  if ((metadata as Record<string, unknown>).title) setTitle((metadata as Record<string, unknown>).title as string);
 
786
  }
787
  }
788
 
789
+ // Extract the three parts from raw_json.metadata
790
+ const extractedMetadataForParts = (capJson.raw_json as Record<string, unknown>)?.metadata;
791
  if (extractedMetadataForParts) {
792
  if ((extractedMetadataForParts as Record<string, unknown>).description) {
793
  setDescription((extractedMetadataForParts as Record<string, unknown>).description as string);