Spaces:
Running
Running
router
Browse files- frontend/public/sw.js +2 -2
- frontend/src/App.tsx +45 -10
- frontend/vite.config.ts +6 -0
- py_backend/static/assets/AdminPage-Dz89QBtX.js +45 -0
- py_backend/static/assets/ExportModal-BtNOxnGZ.js +1 -0
- py_backend/static/assets/index-CwG_dxMe.js +2 -0
- py_backend/static/assets/index-Uy48qW96.js +17 -0
- py_backend/static/assets/index-jo0G9peP.js +3 -0
- py_backend/static/assets/useAdmin-B_k2Fdj-.js +1 -0
- py_backend/static/index.html +1 -1
- py_backend/static/sw.js +2 -2
frontend/public/sw.js
CHANGED
|
@@ -40,8 +40,8 @@ self.addEventListener('fetch', (event) => {
|
|
| 40 |
const { request } = event;
|
| 41 |
const url = new URL(request.url);
|
| 42 |
|
| 43 |
-
// Skip non-GET requests
|
| 44 |
-
if (request.method !== 'GET') {
|
| 45 |
return;
|
| 46 |
}
|
| 47 |
|
|
|
|
| 40 |
const { request } = event;
|
| 41 |
const url = new URL(request.url);
|
| 42 |
|
| 43 |
+
// Skip non-GET requests and non-HTTP(S) requests
|
| 44 |
+
if (request.method !== 'GET' || (url.protocol !== 'http:' && url.protocol !== 'https:')) {
|
| 45 |
return;
|
| 46 |
}
|
| 47 |
|
frontend/src/App.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
| 2 |
import { AlertContext, type AlertContextProps, type AlertParams, LanguageContext, type LanguageContextProps } from '@ifrc-go/ui/contexts';
|
| 3 |
-
import { useCallback, useMemo, useState, lazy, Suspense, useEffect } from 'react';
|
|
|
|
| 4 |
import { unique } from '@togglecorp/fujs';
|
| 5 |
import RootLayout from './layouts/RootLayout';
|
| 6 |
import UploadPage from './pages/UploadPage';
|
|
@@ -15,6 +16,38 @@ const MapDetailPage = lazy(() => import('./pages/MapDetailsPage'));
|
|
| 15 |
import { FilterProvider } from './contexts/FilterContext';
|
| 16 |
import { AdminProvider } from './contexts/AdminContext';
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
// Prefetch function for better performance
|
| 19 |
const prefetchPage = (importFn: () => Promise<any>) => {
|
| 20 |
// Start prefetching immediately
|
|
@@ -164,15 +197,17 @@ function Application() {
|
|
| 164 |
);
|
| 165 |
|
| 166 |
return (
|
| 167 |
-
<
|
| 168 |
-
<
|
| 169 |
-
<
|
| 170 |
-
<
|
| 171 |
-
<
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
|
|
|
|
|
|
| 176 |
);
|
| 177 |
}
|
| 178 |
|
|
|
|
| 1 |
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
| 2 |
import { AlertContext, type AlertContextProps, type AlertParams, LanguageContext, type LanguageContextProps } from '@ifrc-go/ui/contexts';
|
| 3 |
+
import { useCallback, useMemo, useState, lazy, Suspense, useEffect, Component } from 'react';
|
| 4 |
+
import type { ReactNode } from 'react';
|
| 5 |
import { unique } from '@togglecorp/fujs';
|
| 6 |
import RootLayout from './layouts/RootLayout';
|
| 7 |
import UploadPage from './pages/UploadPage';
|
|
|
|
| 16 |
import { FilterProvider } from './contexts/FilterContext';
|
| 17 |
import { AdminProvider } from './contexts/AdminContext';
|
| 18 |
|
| 19 |
+
// Simple Error Boundary Component
|
| 20 |
+
class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean }> {
|
| 21 |
+
constructor(props: { children: ReactNode }) {
|
| 22 |
+
super(props);
|
| 23 |
+
this.state = { hasError: false };
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
static getDerivedStateFromError() {
|
| 27 |
+
return { hasError: true };
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
componentDidCatch(error: Error, errorInfo: any) {
|
| 31 |
+
console.error('Error caught by boundary:', error, errorInfo);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
render() {
|
| 35 |
+
if (this.state.hasError) {
|
| 36 |
+
return (
|
| 37 |
+
<div style={{ padding: '20px', textAlign: 'center' }}>
|
| 38 |
+
<h2>Something went wrong</h2>
|
| 39 |
+
<p>Please refresh the page to try again.</p>
|
| 40 |
+
<button onClick={() => window.location.reload()}>
|
| 41 |
+
Refresh Page
|
| 42 |
+
</button>
|
| 43 |
+
</div>
|
| 44 |
+
);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
return this.props.children;
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
// Prefetch function for better performance
|
| 52 |
const prefetchPage = (importFn: () => Promise<any>) => {
|
| 53 |
// Start prefetching immediately
|
|
|
|
| 197 |
);
|
| 198 |
|
| 199 |
return (
|
| 200 |
+
<ErrorBoundary>
|
| 201 |
+
<AlertContext.Provider value={alertContextValue}>
|
| 202 |
+
<LanguageContext.Provider value={languageContextValue}>
|
| 203 |
+
<AdminProvider>
|
| 204 |
+
<FilterProvider>
|
| 205 |
+
<RouterProvider router={router} />
|
| 206 |
+
</FilterProvider>
|
| 207 |
+
</AdminProvider>
|
| 208 |
+
</LanguageContext.Provider>
|
| 209 |
+
</AlertContext.Provider>
|
| 210 |
+
</ErrorBoundary>
|
| 211 |
);
|
| 212 |
}
|
| 213 |
|
frontend/vite.config.ts
CHANGED
|
@@ -5,6 +5,12 @@ import react from '@vitejs/plugin-react'
|
|
| 5 |
export default defineConfig({
|
| 6 |
base: '/',
|
| 7 |
plugins: [react()],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
server: {
|
| 9 |
proxy: {
|
| 10 |
'/api': {
|
|
|
|
| 5 |
export default defineConfig({
|
| 6 |
base: '/',
|
| 7 |
plugins: [react()],
|
| 8 |
+
resolve: {
|
| 9 |
+
dedupe: ['react', 'react-dom']
|
| 10 |
+
},
|
| 11 |
+
optimizeDeps: {
|
| 12 |
+
include: ['react', 'react-dom']
|
| 13 |
+
},
|
| 14 |
server: {
|
| 15 |
proxy: {
|
| 16 |
'/api': {
|
py_backend/static/assets/AdminPage-Dz89QBtX.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{r as d,j as a}from"./vendor-react-BxsGb6Ph.js";import{u as we}from"./useAdmin-B_k2Fdj-.js";import{N as B,R as Fe,O as h,z as f,n as t,f as S}from"./vendor-ui-l_DttnRj.js";import"./vendor-DxpCibxB.js";import"./index-Uy48qW96.js";const ke="_adminContainer_j11pf_5",Te="_adminHeader_j11pf_13",Ae="_adminSection_j11pf_20",Pe="_modelSelectionArea_j11pf_29",Ie="_modelSelectionRow_j11pf_36",$e="_modelsTable_j11pf_89",Le="_promptSubsection_j11pf_97",Ee="_promptSubsectionTitle_j11pf_109",Be="_modelCode_j11pf_152",Oe="_modelId_j11pf_157",Re="_modelActions_j11pf_163",De="_addModelButtonContainer_j11pf_169",Ue="_addModelForm_j11pf_177",ze="_addModelFormTitle_j11pf_185",He="_addModelFormGrid_j11pf_193",Ge="_addModelFormField_j11pf_206",Ve="_addModelFormCheckbox_j11pf_250",Je="_addModelFormActions_j11pf_268",Ke="_modalOverlay_j11pf_277",We="_modalContent_j11pf_291",qe="_modalBody_j11pf_302",Ye="_modalTitle_j11pf_312",Qe="_modalText_j11pf_320",Xe="_modalTextLeft_j11pf_332",Ze="_modalButtons_j11pf_355",ea="_modalForm_j11pf_363",aa="_formField_j11pf_372",la="_formLabel_j11pf_376",sa="_formInput_j11pf_385",oa="_textarea_j11pf_407",l={adminContainer:ke,adminHeader:Te,adminSection:Ae,modelSelectionArea:Pe,modelSelectionRow:Ie,modelsTable:$e,promptSubsection:Le,promptSubsectionTitle:Ee,modelCode:Be,modelId:Oe,modelActions:Re,addModelButtonContainer:De,addModelForm:Ue,addModelFormTitle:ze,addModelFormGrid:He,addModelFormField:Ge,addModelFormCheckbox:Ve,addModelFormActions:Je,modalOverlay:Ke,modalContent:We,modalBody:qe,modalTitle:Ye,modalText:Qe,modalTextLeft:Xe,modalButtons:Ze,modalForm:ea,formField:aa,formLabel:la,formInput:sa,textarea:oa},w="selectedVlmModel";function ca(){const{isAuthenticated:F,isLoading:X,login:Z,logout:ee}=we(),[k,O]=d.useState(""),[R,u]=d.useState(""),[D,U]=d.useState(!1),[z,H]=d.useState([]),[ae,b]=d.useState(""),[G,le]=d.useState([]),[se,oe]=d.useState([]),[te,y]=d.useState(!1),[de,N]=d.useState(!1),[ie,T]=d.useState(null),[C,A]=d.useState(null),[n,r]=d.useState({p_code:"",label:"",metadata_instructions:"",image_type:"crisis_map",is_active:!1}),[V,P]=d.useState(!1),[ne,I]=d.useState(!1),[$,L]=d.useState(null),[o,c]=d.useState({m_code:"",label:"",model_type:"custom",provider:"huggingface",model_id:"",is_available:!1}),[re,M]=d.useState(!1),[ce,E]=d.useState(!1),[me,p]=d.useState(!1),[J,K]=d.useState(""),[he,pe]=d.useState(""),[_e,_]=d.useState(""),[ue,j]=d.useState(""),x=d.useCallback(()=>{fetch("/api/models").then(e=>e.json()).then(e=>{console.log("Models data received:",e),H(e.models||[]);const s=localStorage.getItem(w);if(e.models&&e.models.length>0)if(s==="random")b("random");else if(s&&e.models.find(i=>i.m_code===s&&i.is_available))b(s);else{const i=e.models.find(m=>m.is_available)||e.models[0];b(i.m_code),localStorage.setItem(w,i.m_code)}}).catch(()=>{})},[]),v=d.useCallback(()=>{console.log("=== fetchPrompts called ==="),fetch("/api/prompts").then(e=>e.json()).then(e=>{console.log("Prompts data received:",e),le(e||[]),console.log("State update triggered with:",e||[])}).catch(e=>{console.error("Error fetching prompts:",e)})},[]),W=d.useCallback(()=>{fetch("/api/image-types").then(e=>e.json()).then(e=>{console.log("Image types data received:",e),oe(e||[])}).catch(()=>{})},[]);d.useEffect(()=>{F&&(x(),v(),W())},[F,x,v,W]);const q=e=>{A(e),r({p_code:e.p_code,label:e.label||"",metadata_instructions:e.metadata_instructions||"",image_type:e.image_type||"crisis_map",is_active:e.is_active||!1}),y(!0)},je=async()=>{try{if(!C){alert("No prompt selected for editing");return}const e=await fetch(`/api/prompts/${C.p_code}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({label:n.label,metadata_instructions:n.metadata_instructions,image_type:n.image_type,is_active:n.is_active})});if(e.ok)v(),y(!1),A(null),r({p_code:"",label:"",metadata_instructions:"",image_type:"crisis_map",is_active:!1});else{const s=await e.json();alert(`Failed to update prompt: ${s.error||"Unknown error"}`)}}catch{alert("Error updating prompt")}},Y=async(e,s)=>{try{const i=await fetch(`/api/prompts/${e}/toggle-active?image_type=${s}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(i.ok)v();else{const m=await i.json();alert(`Failed to toggle prompt active status: ${m.detail||"Unknown error"}`)}}catch{alert("Error toggling prompt active status")}},Q=e=>{T(e),r({p_code:"",label:"",metadata_instructions:"",image_type:e,is_active:!1}),N(!0)},xe=async()=>{try{const e=await fetch("/api/prompts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(e.ok)v(),N(!1),T(null),r({p_code:"",label:"",metadata_instructions:"",image_type:"crisis_map",is_active:!1});else{const s=await e.json();alert(`Failed to create prompt: ${s.detail||"Unknown error"}`)}}catch{alert("Error creating prompt")}},ve=async(e,s)=>{try{const i=await fetch(`/api/models/${e}/toggle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({is_available:!s})});if(i.ok)H(m=>m.map(g=>g.m_code===e?{...g,is_available:!s}:g));else{const m=await i.json();alert(`Failed to toggle model availability: ${m.error||"Unknown error"}`)}}catch{alert("Error toggling model availability")}},ge=e=>{b(e),e==="random"?localStorage.setItem(w,"random"):localStorage.setItem(w,e)},fe=async()=>{try{const e=await fetch("/api/admin/models",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${localStorage.getItem("adminToken")}`},body:JSON.stringify(o)});if(e.ok){const s=`
|
| 2 |
+
Model "${o.label}" added successfully!
|
| 3 |
+
|
| 4 |
+
β οΈ IMPORTANT: Model will NOT work until you complete these steps:
|
| 5 |
+
|
| 6 |
+
1. π Ensure API key is set and valid.
|
| 7 |
+
|
| 8 |
+
2. π Verify model_id format.
|
| 9 |
+
|
| 10 |
+
3. π Check model specific documentation for details.
|
| 11 |
+
`;pe(s),E(!0),P(!1),c({m_code:"",label:"",model_type:"custom",provider:"huggingface",model_id:"",is_available:!1}),x()}else{const s=await e.json();alert(`Failed to add model: ${s.detail||"Unknown error"}`)}}catch{alert("Error adding model")}},be=e=>{L(e),c({m_code:e.m_code,label:e.label,model_type:e.model_type||"custom",provider:e.provider||e.config?.provider||"huggingface",model_id:e.model_id||e.config?.model_id||e.m_code,is_available:e.is_available}),I(!0)},ye=async()=>{try{console.log("Updating model with data:",o);const e={label:o.label,model_type:o.model_type,provider:o.provider,model_id:o.model_id,is_available:o.is_available};if(console.log("Update payload:",e),!$){alert("No model selected for editing");return}const s=await fetch(`/api/admin/models/${$.m_code}`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${localStorage.getItem("adminToken")}`},body:JSON.stringify(e)});if(console.log("Update response status:",s.status),s.ok){const i=await s.json();console.log("Update successful:",i),I(!1),L(null),c({m_code:"",label:"",model_type:"custom",provider:"huggingface",model_id:"",is_available:!1}),console.log("Refreshing models..."),x()}else{const i=await s.json();console.error("Update failed:",i),alert(`Failed to update model: ${i.detail||"Unknown error"}`)}}catch(e){console.error("Update error:",e),alert("Error updating model")}},Ne=async e=>{K(e),M(!0)},Ce=async()=>{try{const e=await fetch(`/api/admin/models/${J}`,{method:"DELETE",headers:{Authorization:`Bearer ${localStorage.getItem("adminToken")}`}});if(e.ok)M(!1),K(""),x();else{const s=await e.json();alert(`Failed to delete model: ${s.detail||"Unknown error"}`)}}catch{alert("Error deleting model")}},Me=async e=>{if(e.preventDefault(),!k.trim()){u("Please enter a password");return}U(!0),u("");try{await Z(k)||u("Invalid password")}catch{u("Login failed. Please try again.")}finally{U(!1)}},Se=()=>{ee(),O(""),u("")};return X?a.jsx(B,{children:a.jsx("div",{className:"flex items-center justify-center min-h-[400px]",children:a.jsxs("div",{className:"text-center",children:[a.jsx("div",{className:"animate-spin rounded-full h-12 w-12 border-b-2 border-ifrcRed mx-auto mb-4"}),a.jsx("p",{className:"text-gray-600",children:"Loading..."})]})})}):F?a.jsxs(B,{children:[a.jsxs("div",{className:l.adminContainer,children:[a.jsx("div",{className:l.adminHeader,children:a.jsx(t,{name:"logout",variant:"secondary",onClick:Se,children:"Logout"})}),a.jsxs("div",{className:l.adminSection,children:[a.jsx(f,{heading:"VLM Model Selection",headingLevel:2,withHeaderBorder:!0,withInternalPadding:!0,children:a.jsxs("div",{className:l.modelSelectionArea,children:[a.jsx("p",{className:"text-gray-700",children:"Select which Vision Language Model to use for caption generation."}),a.jsx("div",{className:l.modelSelectionRow,children:a.jsx(S,{label:"Model",name:"selected-model",value:ae,onChange:e=>ge(e||""),options:[{value:"random",label:"Random"},...z.filter(e=>e.is_available).map(e=>({value:e.m_code,label:e.label}))],keySelector:e=>e.value,labelSelector:e=>e.label})})]})}),a.jsx(f,{heading:"Model Management",headingLevel:2,withHeaderBorder:!0,withInternalPadding:!0,children:a.jsxs("div",{className:l.modelManagementArea,children:[a.jsx("div",{className:l.modelsTable,children:a.jsxs("table",{children:[a.jsx("thead",{children:a.jsxs("tr",{children:[a.jsx("th",{children:"Code"}),a.jsx("th",{children:"Label"}),a.jsx("th",{children:"Provider"}),a.jsx("th",{children:"Model ID"}),a.jsx("th",{children:"Available"}),a.jsx("th",{children:"Actions"})]})}),a.jsx("tbody",{children:z.map(e=>a.jsxs("tr",{children:[a.jsx("td",{className:l.modelCode,children:e.m_code}),a.jsx("td",{children:e.label}),a.jsx("td",{children:e.provider||e.config?.provider||"huggingface"}),a.jsx("td",{className:l.modelId,children:e.model_id||e.config?.model_id||e.m_code||"N/A"}),a.jsx("td",{children:a.jsx(t,{name:`toggle-${e.m_code}`,variant:e.is_available?"primary":"secondary",size:1,onClick:()=>ve(e.m_code,e.is_available),children:e.is_available?"Enabled":"Disabled"})}),a.jsx("td",{children:a.jsxs("div",{className:l.modelActions,children:[a.jsx(t,{name:`edit-${e.m_code}`,variant:"secondary",size:1,onClick:()=>be(e),children:"Edit"}),a.jsx(t,{name:`delete-${e.m_code}`,variant:"secondary",size:1,onClick:()=>Ne(e.m_code),children:"Delete"})]})})]},e.m_code))})]})}),!V&&a.jsx("div",{className:l.addModelButtonContainer,children:a.jsx(t,{name:"show-add-form",variant:"primary",onClick:()=>P(!0),children:"Add New Model"})}),V&&a.jsxs("div",{className:l.addModelForm,children:[a.jsx("h4",{className:l.addModelFormTitle,children:"Add New Model"}),a.jsxs("div",{className:l.addModelFormGrid,children:[a.jsx("div",{className:l.addModelFormField,children:a.jsx(h,{label:"Model Code",name:"model-code",value:o.m_code,onChange:e=>c({...o,m_code:e||""}),placeholder:"e.g., NEW_MODEL_123"})}),a.jsx("div",{className:l.addModelFormField,children:a.jsx(h,{label:"Label",name:"model-label",value:o.label,onChange:e=>c({...o,label:e||""}),placeholder:"e.g., New Model Name"})}),a.jsx("div",{className:l.addModelFormField,children:a.jsx(S,{label:"Provider",name:"model-provider",value:o.provider,onChange:e=>c({...o,provider:e||"huggingface"}),options:[{value:"huggingface",label:"HuggingFace"},{value:"openai",label:"OpenAI"},{value:"google",label:"Google"}],keySelector:e=>e.value,labelSelector:e=>e.label})}),a.jsx("div",{className:l.addModelFormField,children:a.jsx(h,{label:"Model ID",name:"model-id",value:o.model_id,onChange:e=>c({...o,model_id:e||""}),placeholder:"e.g., org/model-name"})}),a.jsx("div",{className:l.addModelFormField,children:a.jsxs("div",{className:l.addModelFormCheckbox,children:[a.jsx("input",{type:"checkbox",checked:o.is_available,onChange:e=>c({...o,is_available:e.target.checked})}),a.jsx("span",{children:"Available for use"})]})})]}),a.jsxs("div",{className:l.addModelFormActions,children:[a.jsx(t,{name:"save-model",variant:"primary",onClick:fe,disabled:!o.m_code||!o.label||!o.model_id,children:"Save Model"}),a.jsx(t,{name:"cancel-add",variant:"secondary",onClick:()=>P(!1),children:"Cancel"})]})]}),ne&&a.jsxs("div",{className:l.addModelForm,children:[a.jsxs("h4",{className:l.addModelFormTitle,children:["Edit Model: ",$?.label]}),a.jsxs("div",{className:l.addModelFormGrid,children:[a.jsx("div",{className:l.addModelFormField,children:a.jsx(h,{label:"Model Code",name:"model-code",value:o.m_code,onChange:e=>c({...o,m_code:e||""}),placeholder:"e.g., NEW_MODEL_123",disabled:!0})}),a.jsx("div",{className:l.addModelFormField,children:a.jsx(h,{label:"Label",name:"model-label",value:o.label,onChange:e=>c({...o,label:e||""}),placeholder:"e.g., New Model Name"})}),a.jsx("div",{className:l.addModelFormField,children:a.jsx(S,{label:"Provider",name:"model-provider",value:o.provider,onChange:e=>c({...o,provider:e||"huggingface"}),options:[{value:"huggingface",label:"HuggingFace"},{value:"openai",label:"OpenAI"},{value:"google",label:"Google"}],keySelector:e=>e.value,labelSelector:e=>e.label})}),a.jsx("div",{className:l.addModelFormField,children:a.jsx(h,{label:"Model ID",name:"model-id",value:o.model_id,onChange:e=>c({...o,model_id:e||""}),placeholder:"e.g., org/model-name"})}),a.jsx("div",{className:l.addModelFormField,children:a.jsxs("div",{className:l.addModelFormCheckbox,children:[a.jsx("input",{type:"checkbox",checked:o.is_available,onChange:e=>c({...o,is_available:e.target.checked})}),a.jsx("span",{children:"Available for use"})]})})]}),a.jsxs("div",{className:l.addModelFormActions,children:[a.jsx(t,{name:"update-model",variant:"primary",onClick:ye,disabled:!o.m_code||!o.label||!o.model_id,children:"Update Model"}),a.jsx(t,{name:"cancel-edit",variant:"secondary",onClick:()=>{I(!1),L(null),c({m_code:"",label:"",model_type:"custom",provider:"huggingface",model_id:"",is_available:!1})},children:"Cancel"})]})]})]})}),a.jsx(f,{heading:"Prompt Management",headingLevel:2,withHeaderBorder:!0,withInternalPadding:!0,children:a.jsxs("div",{className:l.modelManagementArea,children:[a.jsxs("div",{className:l.promptSubsection,children:[a.jsx("h4",{className:l.promptSubsectionTitle,children:"Crisis Maps"}),a.jsx("div",{className:l.modelsTable,children:a.jsxs("table",{children:[a.jsx("thead",{children:a.jsxs("tr",{children:[a.jsx("th",{children:"Code"}),a.jsx("th",{children:"Label"}),a.jsx("th",{children:"Status"}),a.jsx("th",{children:"Actions"})]})}),a.jsx("tbody",{children:G.filter(e=>e.image_type==="crisis_map").sort((e,s)=>e.p_code.localeCompare(s.p_code)).map(e=>a.jsxs("tr",{children:[a.jsx("td",{className:l.modelCode,children:e.p_code}),a.jsx("td",{className:l.promptLabel,children:e.label||"No label"}),a.jsx("td",{children:a.jsx(t,{name:`toggle-crisis-${e.p_code}`,variant:e.is_active?"primary":"secondary",size:1,onClick:()=>Y(e.p_code,"crisis_map"),children:e.is_active?"Active":"Inactive"})}),a.jsx("td",{children:a.jsxs("div",{className:l.modelActions,children:[a.jsx(t,{name:`view-${e.p_code}`,variant:"secondary",size:1,onClick:()=>{_(`=== Prompt Details ===
|
| 12 |
+
Code: ${e.p_code}
|
| 13 |
+
Label: ${e.label}
|
| 14 |
+
Image Type: ${e.image_type}
|
| 15 |
+
Active: ${e.is_active}
|
| 16 |
+
|
| 17 |
+
Metadata Instructions:
|
| 18 |
+
${e.metadata_instructions||"No instructions available"}`),j(`Prompt: ${e.p_code}`),p(!0)},children:"View"}),a.jsx(t,{name:`edit-${e.p_code}`,variant:"secondary",size:1,onClick:()=>q(e),children:"Edit"})]})})]},e.p_code))})]})}),a.jsx("div",{className:l.addModelButtonContainer,children:a.jsx(t,{name:"add-crisis-prompt",variant:"primary",onClick:()=>Q("crisis_map"),children:"Add New Crisis Map Prompt"})})]}),a.jsxs("div",{className:l.promptSubsection,children:[a.jsx("h4",{className:l.promptSubsectionTitle,children:"Drone Images"}),a.jsx("div",{className:l.modelsTable,children:a.jsxs("table",{children:[a.jsx("thead",{children:a.jsxs("tr",{children:[a.jsx("th",{children:"Code"}),a.jsx("th",{children:"Label"}),a.jsx("th",{children:"Status"}),a.jsx("th",{children:"Actions"})]})}),a.jsx("tbody",{children:G.filter(e=>e.image_type==="drone_image").sort((e,s)=>e.p_code.localeCompare(s.p_code)).map(e=>a.jsxs("tr",{children:[a.jsx("td",{className:l.modelCode,children:e.p_code}),a.jsx("td",{className:l.promptLabel,children:e.label||"No label"}),a.jsx("td",{children:a.jsx(t,{name:`toggle-drone-${e.p_code}`,variant:e.is_active?"primary":"secondary",size:1,onClick:()=>Y(e.p_code,"drone_image"),children:e.is_active?"Active":"Inactive"})}),a.jsx("td",{children:a.jsxs("div",{className:l.modelActions,children:[a.jsx(t,{name:`view-${e.p_code}`,variant:"secondary",size:1,onClick:()=>{_(`=== Prompt Details ===
|
| 19 |
+
Code: ${e.p_code}
|
| 20 |
+
Label: ${e.label}
|
| 21 |
+
Image Type: ${e.image_type}
|
| 22 |
+
Active: ${e.is_active}
|
| 23 |
+
|
| 24 |
+
Metadata Instructions:
|
| 25 |
+
${e.metadata_instructions||"No instructions available"}`),j(`Prompt: ${e.p_code}`),p(!0)},children:"View"}),a.jsx(t,{name:`edit-${e.p_code}`,variant:"secondary",size:1,onClick:()=>q(e),children:"Edit"})]})})]},e.p_code))})]})}),a.jsx("div",{className:l.addModelButtonContainer,children:a.jsx(t,{name:"add-drone-prompt",variant:"primary",onClick:()=>Q("drone_image"),children:"Add New Drone Image Prompt"})})]})]})}),a.jsx(f,{heading:"Utilities",headingLevel:2,withHeaderBorder:!0,withInternalPadding:!0,children:a.jsxs("div",{className:"flex flex-wrap gap-4",children:[a.jsx(t,{name:"test-connection",variant:"secondary",onClick:async()=>{_("Testing API connection..."),j("Connection Test Results");try{const e=await fetch("/api/models");if(e.ok){const s=await e.json(),i=`β
API connection successful!
|
| 26 |
+
|
| 27 |
+
Found ${s.models?.length||0} models in database.
|
| 28 |
+
|
| 29 |
+
Available models:
|
| 30 |
+
${s.models?.filter(m=>m.is_available).map(m=>`- ${m.label} (${m.m_code})`).join(`
|
| 31 |
+
`)||"None"}`;_(i)}else{const s=`β API connection failed: HTTP ${e.status}`;_(s)}p(!0)}catch(e){const s=`β Connection error: ${e}`;_(s),p(!0)}},children:"Test Connection"}),a.jsx(t,{name:"view-schemas",variant:"secondary",onClick:()=>{fetch("/api/schemas",{headers:{Authorization:`Bearer ${localStorage.getItem("adminToken")}`}}).then(e=>e.json()).then(e=>{console.log("Schemas Response:",e);let s="",i="Schemas Response";e&&Array.isArray(e)?(s=`Found ${e.length} schemas:
|
| 32 |
+
|
| 33 |
+
`,e.forEach((m,g)=>{s+=`=== Schema ${g+1} ===
|
| 34 |
+
`,s+=JSON.stringify(m,null,2),s+=`
|
| 35 |
+
|
| 36 |
+
`})):e&&typeof e=="object"?s=`Prompts Response:
|
| 37 |
+
|
| 38 |
+
Response type: ${typeof e}
|
| 39 |
+
Keys: ${Object.keys(e).join(", ")}
|
| 40 |
+
|
| 41 |
+
Raw data:
|
| 42 |
+
${JSON.stringify(e,null,2)}`:s=`Prompts Response:
|
| 43 |
+
|
| 44 |
+
Unexpected data type: ${typeof e}
|
| 45 |
+
Value: ${e}`,_(s),j(i),p(!0)}).catch(e=>{console.error("Schemas Error:",e);const s=`Failed to fetch prompts: ${e.message||"Unknown error"}`;_(s),j("Schemas Error"),p(!0)})},children:"View Schemas"})]})})]})]}),re&&a.jsx("div",{className:l.modalOverlay,onClick:()=>M(!1),children:a.jsx("div",{className:l.modalContent,onClick:e=>e.stopPropagation(),children:a.jsxs("div",{className:l.modalBody,children:[a.jsx("h3",{className:l.modalTitle,children:"Delete Model"}),a.jsxs("p",{className:l.modalText,children:["Are you sure you want to delete model ",a.jsx("span",{className:l.modelCode,children:J}),"? This action cannot be undone."]}),a.jsxs("div",{className:l.modalButtons,children:[a.jsx(t,{name:"cancel-delete",variant:"tertiary",onClick:()=>M(!1),children:"Cancel"}),a.jsx(t,{name:"confirm-delete",variant:"secondary",onClick:Ce,children:"Delete"})]})]})})}),ce&&a.jsx("div",{className:l.modalOverlay,onClick:()=>E(!1),children:a.jsx("div",{className:l.modalContent,onClick:e=>e.stopPropagation(),children:a.jsxs("div",{className:l.modalBody,children:[a.jsx("h3",{className:l.modalTitle,children:"Model Added Successfully!"}),a.jsx("div",{className:`${l.modalText} ${l.modalTextLeft}`,children:he}),a.jsx("div",{className:l.modalButtons,children:a.jsx(t,{name:"close-setup-instructions",variant:"secondary",onClick:()=>E(!1),children:"Got it!"})})]})})}),me&&a.jsx("div",{className:l.modalOverlay,onClick:()=>p(!1),children:a.jsx("div",{className:l.modalContent,onClick:e=>e.stopPropagation(),children:a.jsxs("div",{className:l.modalBody,children:[a.jsx("h3",{className:l.modalTitle,children:ue}),a.jsx("div",{className:`${l.modalText} ${l.modalTextLeft}`,children:a.jsx("div",{className:"whitespace-pre-wrap font-mono text-sm leading-relaxed",children:_e})}),a.jsx("div",{className:l.modalButtons,children:a.jsx(t,{name:"close-test-results",variant:"secondary",onClick:()=>p(!1),children:"Close"})})]})})}),te&&a.jsx("div",{className:l.modalOverlay,onClick:()=>y(!1),children:a.jsx("div",{className:l.modalContent,onClick:e=>e.stopPropagation(),children:a.jsxs("div",{className:l.modalBody,children:[a.jsxs("h3",{className:l.modalTitle,children:["Edit Prompt: ",C?.p_code]}),a.jsxs("div",{className:l.modalForm,children:[a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Code:"}),a.jsx(h,{name:"prompt-code",value:C?.p_code,onChange:()=>{},disabled:!0,className:l.formInput})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Label:"}),a.jsx(h,{name:"prompt-label",value:n.label,onChange:e=>r(s=>({...s,label:e||""})),className:l.formInput})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Image Type:"}),a.jsx(S,{name:"prompt-image-type",value:n.image_type,onChange:e=>r(s=>({...s,image_type:e||"crisis_map"})),options:se,keySelector:e=>e.image_type,labelSelector:e=>e.label})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Active Status:"}),a.jsxs("div",{className:l.addModelFormCheckbox,children:[a.jsx("input",{type:"checkbox",checked:n.is_active,onChange:e=>r(s=>({...s,is_active:e.target.checked}))}),a.jsx("span",{children:"Active for this image type"})]})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Metadata Instructions:"}),a.jsx("textarea",{name:"prompt-instructions",value:n.metadata_instructions,onChange:e=>r(s=>({...s,metadata_instructions:e.target.value})),className:`${l.formInput} ${l.textarea}`,rows:8})]})]}),a.jsxs("div",{className:l.modalButtons,children:[a.jsx(t,{name:"cancel-edit-prompt",variant:"tertiary",onClick:()=>{y(!1),A(null),r({p_code:"",label:"",metadata_instructions:"",image_type:"crisis_map",is_active:!1})},children:"Cancel"}),a.jsx(t,{name:"save-prompt",variant:"primary",onClick:je,children:"Save Changes"})]})]})})}),de&&a.jsx("div",{className:l.modalOverlay,onClick:()=>N(!1),children:a.jsx("div",{className:l.modalContent,onClick:e=>e.stopPropagation(),children:a.jsxs("div",{className:l.modalBody,children:[a.jsxs("h3",{className:l.modalTitle,children:["Add New ",ie==="crisis_map"?"Crisis Map":"Drone Image"," Prompt"]}),a.jsxs("div",{className:l.modalForm,children:[a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Code:"}),a.jsx(h,{name:"prompt-code",value:n.p_code,onChange:e=>r(s=>({...s,p_code:e||""})),placeholder:"e.g., CUSTOM_CRISIS_MAP_001",className:l.formInput})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Label:"}),a.jsx(h,{name:"prompt-label",value:n.label,onChange:e=>r(s=>({...s,label:e||""})),placeholder:"Enter prompt description...",className:l.formInput})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Image Type:"}),a.jsx(h,{name:"prompt-image-type",value:n.image_type,onChange:()=>{},disabled:!0,className:l.formInput})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Active Status:"}),a.jsxs("div",{className:l.addModelFormCheckbox,children:[a.jsx("input",{type:"checkbox",checked:n.is_active,onChange:e=>r(s=>({...s,is_active:e.target.checked}))}),a.jsx("span",{children:"Active for this image type"})]})]}),a.jsxs("div",{className:l.formField,children:[a.jsx("label",{className:l.formLabel,children:"Metadata Instructions:"}),a.jsx("textarea",{name:"prompt-instructions",value:n.metadata_instructions,onChange:e=>r(s=>({...s,metadata_instructions:e.target.value})),placeholder:"Enter metadata extraction instructions...",className:`${l.formInput} ${l.textarea}`,rows:8})]})]}),a.jsxs("div",{className:l.modalButtons,children:[a.jsx(t,{name:"cancel-add-prompt",variant:"tertiary",onClick:()=>{N(!1),T(null),r({p_code:"",label:"",metadata_instructions:"",image_type:"crisis_map",is_active:!1})},children:"Cancel"}),a.jsx(t,{name:"save-new-prompt",variant:"primary",onClick:xe,disabled:!n.p_code||!n.label,children:"Create Prompt"})]})]})})})]}):a.jsx(B,{children:a.jsxs("div",{className:"mx-auto max-w-md px-4 sm:px-6 lg:px-8 py-6 sm:py-10",children:[a.jsx("div",{className:"text-center mb-8",children:a.jsx(Fe,{level:2,children:"Admin Login"})}),a.jsxs("form",{onSubmit:Me,className:"space-y-6",children:[a.jsxs("div",{children:[a.jsx("label",{htmlFor:"password",className:"block text-sm font-medium text-gray-700 mb-2",children:"Password"}),a.jsx(h,{id:"password",name:"password",type:"password",value:k,onChange:e=>O(e||""),placeholder:"Enter admin password",required:!0,className:"w-full"})]}),R&&a.jsx("div",{className:"bg-ifrcRed/10 border border-ifrcRed/20 rounded-md p-3",children:a.jsx("p",{className:"text-sm text-ifrcRed font-medium",children:R})}),a.jsx("div",{className:"flex justify-center",children:a.jsx(f,{withInternalPadding:!0,className:"p-2",children:a.jsx(t,{name:"login",type:"submit",variant:"primary",size:2,disabled:D,children:D?"Logging in...":"Login"})})})]})]})})}export{ca as default};
|
py_backend/static/assets/ExportModal-BtNOxnGZ.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
import{r as o,j as e}from"./vendor-react-BxsGb6Ph.js";import{z as i,n as r,F as W,O,f as v,d as P,_ as N,L as B,j as F}from"./vendor-ui-l_DttnRj.js";import{u as A}from"./index-Uy48qW96.js";function ie({sources:_,types:S,regions:f,countries:I,imageTypes:k,isLoadingFilters:a=!1}){const[d,y]=o.useState(!1),{search:T,setSearch:p,srcFilter:w,setSrcFilter:m,catFilter:z,setCatFilter:u,regionFilter:h,setRegionFilter:g,countryFilter:x,setCountryFilter:j,imageTypeFilter:M,setImageTypeFilter:b,uploadTypeFilter:E,setUploadTypeFilter:C,showReferenceExamples:c,setShowReferenceExamples:t,clearAllFilters:n}=A();return e.jsxs("div",{className:"mb-6 space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-4",children:[e.jsx(i,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2",children:e.jsx(r,{name:"toggle-filters",variant:"secondary",onClick:()=>y(!d),className:"whitespace-nowrap",title:d?"Hide Filters":"Show Filters",children:e.jsx(W,{className:"w-4 h-4"})})}),e.jsx(i,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2 flex-1 min-w-[300px]",children:e.jsx(O,{name:"search",placeholder:"Search examples...",value:T,onChange:l=>p(l||"")})}),e.jsx(i,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2",children:e.jsx(r,{name:"clear-filters",variant:"secondary",onClick:n,children:"Clear Filters"})})]}),d&&e.jsx("div",{className:"bg-white/20 backdrop-blur-sm rounded-md p-4",children:e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 gap-4",children:[e.jsx(i,{withInternalPadding:!0,className:"p-2",children:e.jsx(v,{name:"source",placeholder:a?"Loading...":"All Sources",options:_,value:w||null,onChange:l=>m(l||""),keySelector:l=>l.s_code,labelSelector:l=>l.label,required:!1,disabled:a})}),e.jsx(i,{withInternalPadding:!0,className:"p-2",children:e.jsx(v,{name:"category",placeholder:a?"Loading...":"All Categories",options:S,value:z||null,onChange:l=>u(l||""),keySelector:l=>l.t_code,labelSelector:l=>l.label,required:!1,disabled:a})}),e.jsx(i,{withInternalPadding:!0,className:"p-2",children:e.jsx(v,{name:"region",placeholder:a?"Loading...":"All Regions",options:f,value:h||null,onChange:l=>g(l||""),keySelector:l=>l.r_code,labelSelector:l=>l.label,required:!1,disabled:a})}),e.jsx(i,{withInternalPadding:!0,className:"p-2",children:e.jsx(P,{name:"country",placeholder:a?"Loading...":"All Countries",options:I,value:x?[x]:[],onChange:l=>j(l[0]||""),keySelector:l=>l.c_code,labelSelector:l=>l.label,disabled:a})}),e.jsx(i,{withInternalPadding:!0,className:"p-2",children:e.jsx(v,{name:"imageType",placeholder:a?"Loading...":"All Image Types",options:k,value:M||null,onChange:l=>b(l||""),keySelector:l=>l.image_type,labelSelector:l=>l.label,required:!1,disabled:a})}),e.jsx(i,{withInternalPadding:!0,className:"p-2",children:e.jsx(v,{name:"uploadType",placeholder:"All Upload Types",options:[{key:"single",label:"Single Upload"},{key:"multiple",label:"Multiple Upload"}],value:E||null,onChange:l=>C(l||""),keySelector:l=>l.key,labelSelector:l=>l.label,required:!1,disabled:!1})})]})})]})}const R="_fullSizeModalOverlay_cyz3b_1",q="_fullSizeModalContent_cyz3b_29",G="_ratingWarningContent_cyz3b_53",U="_ratingWarningTitle_cyz3b_65",D="_exportModeSection_cyz3b_133",V="_splitConfigSection_cyz3b_143",Y="_splitConfigTitle_cyz3b_153",$="_splitInputsContainer_cyz3b_167",H="_splitInputGroup_cyz3b_183",J="_splitInputLabel_cyz3b_197",K="_splitInput_cyz3b_167",Q="_splitTotal_cyz3b_247",X="_splitTotalError_cyz3b_261",Z="_checkboxesContainer_cyz3b_271",L="_ratingWarningButtons_cyz3b_289",ee="_singleExportMessage_cyz3b_309",le="_navigateButtonContainer_cyz3b_333",se="_loadingOverlay_cyz3b_349",s={fullSizeModalOverlay:R,fullSizeModalContent:q,ratingWarningContent:G,ratingWarningTitle:U,exportModeSection:D,splitConfigSection:V,splitConfigTitle:Y,splitInputsContainer:$,splitInputGroup:H,splitInputLabel:J,splitInput:K,splitTotal:Q,splitTotalError:X,checkboxesContainer:Z,ratingWarningButtons:L,singleExportMessage:ee,navigateButtonContainer:le,loadingOverlay:se};function re({isOpen:_,onClose:S,onExport:f,crisisMapsCount:I,droneImagesCount:k,isLoading:a=!1,exportSuccess:d=!1,variant:y="bulk",onNavigateAndExport:T}){const[p,w]=o.useState("standard"),[m,z]=o.useState(80),[u,h]=o.useState(10),[g,x]=o.useState(10),[j,M]=o.useState(!0),[b,E]=o.useState(!0),C=()=>{if(y==="single"){f(p,["crisis_map","drone_image"]);return}if(!j&&!b){alert("Please select at least one image type to export.");return}const t=[];j&&t.push("crisis_map"),b&&t.push("drone_image"),f(p,t)},c=()=>{S()};return _?y==="single"?e.jsx("div",{className:s.fullSizeModalOverlay,onClick:c,children:e.jsxs("div",{className:s.fullSizeModalContent,onClick:t=>t.stopPropagation(),children:[a&&e.jsx("div",{className:s.loadingOverlay,children:e.jsxs("div",{className:"flex flex-col items-center gap-4",children:[e.jsx(N,{className:"text-ifrcRed"}),e.jsx("div",{className:"text-lg font-medium",children:"Exporting..."}),e.jsx("div",{className:"text-sm text-gray-600",children:"This might take a few seconds"})]})}),d&&e.jsx("div",{className:s.loadingOverlay,children:e.jsxs("div",{className:"flex flex-col items-center gap-4",children:[e.jsx("div",{className:"text-lg font-medium",children:"Export Successful!"}),e.jsx("div",{className:"text-sm text-gray-600",children:"Your dataset has been downloaded"}),e.jsx(r,{name:"close-export-success",onClick:c,className:"mt-4",children:"Close"})]})}),e.jsxs("div",{className:s.ratingWarningContent,children:[e.jsx("h3",{className:s.ratingWarningTitle,children:"Export Single Item"}),e.jsxs("div",{className:s.singleExportMessage,children:[e.jsx("p",{children:"This only exports the 1 item currently on display."}),e.jsx("p",{children:'You may export the entire dataset from the "list view" here:'})]}),e.jsx("div",{className:s.navigateButtonContainer,children:e.jsx(r,{name:"navigate-to-list",variant:"secondary",onClick:T,children:"Navigate to List View"})}),e.jsxs("div",{className:s.ratingWarningButtons,children:[e.jsx(r,{name:"continue-export",onClick:C,disabled:a,children:a?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(N,{className:"text-white"}),"Exporting..."]}):"Continue"}),e.jsx(r,{name:"cancel-export",variant:"tertiary",onClick:c,disabled:a,children:"Cancel"})]})]})]})}):e.jsx("div",{className:s.fullSizeModalOverlay,onClick:c,children:e.jsxs("div",{className:s.fullSizeModalContent,onClick:t=>t.stopPropagation(),children:[a&&e.jsx("div",{className:s.loadingOverlay,children:e.jsxs("div",{className:"flex flex-col items-center gap-4",children:[e.jsx(N,{className:"text-ifrcRed"}),e.jsx("div",{className:"text-lg font-medium",children:"Exporting..."}),e.jsx("div",{className:"text-sm text-gray-600",children:"This might take a few seconds"})]})}),d&&e.jsx("div",{className:s.loadingOverlay,children:e.jsxs("div",{className:"flex flex-col items-center gap-4",children:[e.jsx("div",{className:"text-lg font-medium",children:"Export Successful!"}),e.jsx("div",{className:"text-sm text-gray-600",children:"Your dataset has been downloaded"}),e.jsx(r,{name:"close-export-success",onClick:c,className:"mt-4",children:"Close"})]})}),e.jsxs("div",{className:s.ratingWarningContent,children:[e.jsx("h3",{className:s.ratingWarningTitle,children:"Export Dataset"}),e.jsx("div",{className:s.exportModeSection,children:e.jsx(B,{name:"export-mode",value:p,onChange:t=>{(t==="standard"||t==="fine-tuning")&&w(t)},options:[{key:"standard",label:"Standard"},{key:"fine-tuning",label:"Fine-tuning"}],keySelector:t=>t.key,labelSelector:t=>t.label,disabled:a})}),p==="fine-tuning"&&e.jsxs("div",{className:s.splitConfigSection,children:[e.jsx("div",{className:s.splitConfigTitle,children:"Dataset Split Configuration"}),e.jsxs("div",{className:s.splitInputsContainer,children:[e.jsxs("div",{className:s.splitInputGroup,children:[e.jsx("label",{htmlFor:"train-split",className:s.splitInputLabel,children:"Train (%)"}),e.jsx("input",{id:"train-split",type:"number",min:"0",max:"100",value:m,onChange:t=>{const n=parseInt(t.target.value)||0,l=100-n;l>=0&&(z(n),u+g>l&&(h(Math.floor(l/2)),x(l-Math.floor(l/2))))},className:s.splitInput,disabled:a})]}),e.jsxs("div",{className:s.splitInputGroup,children:[e.jsx("label",{htmlFor:"test-split",className:s.splitInputLabel,children:"Test (%)"}),e.jsx("input",{id:"test-split",type:"number",min:"0",max:"100",value:u,onChange:t=>{const n=parseInt(t.target.value)||0,l=100-m-n;l>=0&&(h(n),x(l))},className:s.splitInput,disabled:a})]}),e.jsxs("div",{className:s.splitInputGroup,children:[e.jsx("label",{htmlFor:"val-split",className:s.splitInputLabel,children:"Val (%)"}),e.jsx("input",{id:"val-split",type:"number",min:"0",max:"100",value:g,onChange:t=>{const n=parseInt(t.target.value)||0,l=100-m-n;l>=0&&(x(n),h(l))},className:s.splitInput,disabled:a})]})]}),m+u+g!==100&&e.jsx("div",{className:s.splitTotal,children:e.jsx("span",{className:s.splitTotalError,children:"Must equal 100%"})})]}),e.jsxs("div",{className:s.checkboxesContainer,children:[e.jsx("div",{className:"flex items-center gap-3",children:e.jsx(F,{name:"crisis-maps",label:`Crisis Maps (${I} images)`,value:j,onChange:t=>M(t),disabled:a})}),e.jsx("div",{className:"flex items-center gap-3",children:e.jsx(F,{name:"drone-images",label:`Drone Images (${k} images)`,value:b,onChange:t=>E(t),disabled:a})})]}),e.jsxs("div",{className:s.ratingWarningButtons,children:[e.jsx(r,{name:"confirm-export",onClick:C,disabled:a,children:a?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(N,{className:"text-white"}),"Exporting..."]}):"Export Selected"}),e.jsx(r,{name:"cancel-export",variant:"tertiary",onClick:c,disabled:a,children:"Cancel"})]})]})]})}):null}export{re as E,ie as F};
|
py_backend/static/assets/index-CwG_dxMe.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-utils-Db80MiSc.js","assets/vendor-DxpCibxB.js","assets/vendor-react-BxsGb6Ph.js"])))=>i.map(i=>d[i]);
|
| 2 |
+
import{u as Se,_ as Te}from"./index-Uy48qW96.js";import{r as m,j as t}from"./vendor-react-BxsGb6Ph.js";import{N as Ie,_ as ie,L as Ee,z as Z,n as D,D as be}from"./vendor-ui-l_DttnRj.js";import{u as Ce}from"./useAdmin-B_k2Fdj-.js";import{F as $e,E as Pe}from"./ExportModal-BtNOxnGZ.js";import{a as Fe,u as De}from"./vendor-DxpCibxB.js";const ke="_tabSelector_o9y1f_1",Le="_metadataTags_o9y1f_8",Oe="_metadataTag_o9y1f_8",Me="_metadataTagSource_o9y1f_32",Re="_metadataTagType_o9y1f_43",Je="_mapItem_o9y1f_54",We="_mapItemImage_o9y1f_72",ze="_mapItemContent_o9y1f_92",Ue="_mapItemTitle_o9y1f_97",Ae="_mapItemMetadata_o9y1f_105",Be="_fullSizeModalOverlay_o9y1f_134",He="_fullSizeModalContent_o9y1f_148",Ve="_ratingWarningContent_o9y1f_159",Ge="_ratingWarningTitle_o9y1f_165",Ze="_ratingWarningText_o9y1f_172",qe="_ratingWarningButtons_o9y1f_179",g={tabSelector:ke,metadataTags:Le,metadataTag:Oe,metadataTagSource:Me,metadataTagType:Re,mapItem:Je,mapItemImage:We,mapItemContent:ze,mapItemTitle:Ue,mapItemMetadata:Ae,fullSizeModalOverlay:Be,fullSizeModalContent:He,ratingWarningContent:Ve,ratingWarningTitle:Ge,ratingWarningText:Ze,ratingWarningButtons:qe};function at(){const k=Fe(),q=De(),{isAuthenticated:ne}=Ce(),[K,oe]=m.useState("explore"),[_,L]=m.useState([]),{search:y,srcFilter:E,catFilter:b,regionFilter:C,countryFilter:$,imageTypeFilter:P,uploadTypeFilter:F,showReferenceExamples:j,setShowReferenceExamples:le}=Se(),[J,re]=m.useState([]),[W,ce]=m.useState([]),[Q,me]=m.useState([]),[ge,de]=m.useState([]),[X,pe]=m.useState([]),[ue,Y]=m.useState(!0),[z,ee]=m.useState(!0),[fe,U]=m.useState(!1),[he,A]=m.useState(!1),[_e,B]=m.useState(!1),[xe,O]=m.useState(!1),[M,te]=m.useState(""),[H,ae]=m.useState(!1),ye=[{key:"explore",label:"List"},{key:"mapDetails",label:"Carousel"}],se=()=>{ee(!0),fetch("/api/images/grouped").then(e=>e.ok?e.json():(console.error("ExplorePage: Grouped endpoint failed, trying legacy endpoint"),fetch("/api/captions/legacy").then(s=>s.ok?s.json():(console.error("ExplorePage: Legacy endpoint failed, trying regular images endpoint"),fetch("/api/images").then(o=>{if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);return o.json()}))))).then(e=>{if(console.log("ExplorePage: API response data:",e),Array.isArray(e)){const s=e.filter(o=>{const f=o.generated&&o.model,u=o.image_id&&o.image_id!=="undefined"&&o.image_id!=="null";return u||console.error("ExplorePage: Item missing valid image_id:",o),f&&u});console.log("ExplorePage: Filtered images with captions:",s.length),L(s)}else console.error("ExplorePage: API response is not an array:",e),L([])}).catch(()=>{L([])}).finally(()=>{ee(!1)})};m.useEffect(()=>{se()},[]),m.useEffect(()=>{const e=()=>{document.hidden||se()};return document.addEventListener("visibilitychange",e),()=>{document.removeEventListener("visibilitychange",e)}},[]),m.useEffect(()=>{new URLSearchParams(q.search).get("export")==="true"&&(U(!0),k("/explore",{replace:!0}))},[q.search,k,y,E,b,C,$,P,j]),m.useEffect(()=>{Y(!0),Promise.all([fetch("/api/sources").then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()}),fetch("/api/types").then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()}),fetch("/api/regions").then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()}),fetch("/api/countries").then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()}),fetch("/api/image-types").then(e=>{if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);return e.json()})]).then(([e,s,o,f,u])=>{re(e),ce(s),me(o),de(f),pe(u)}).catch(()=>{}).finally(()=>{Y(!1)})},[]);const v=m.useMemo(()=>_.filter(e=>{const s=!y||e.title?.toLowerCase().includes(y.toLowerCase())||e.generated?.toLowerCase().includes(y.toLowerCase())||e.source?.toLowerCase().includes(y.toLowerCase())||e.event_type?.toLowerCase().includes(y.toLowerCase()),o=!E||e.source&&e.source.split(", ").some(x=>x.trim()===E),f=!b||e.event_type&&e.event_type.split(", ").some(x=>x.trim()===b),u=!C||e.countries.some(x=>x.r_code===C),N=!$||e.countries.some(x=>x.c_code===$),V=!P||e.image_type===P,R=!F||F==="single"&&(!e.image_count||e.image_count<=1)||F==="multiple"&&e.image_count&&e.image_count>1,w=!j||e.starred===!0;return s&&o&&f&&u&&N&&V&&R&&w}),[_,y,E,b,C,$,P,F,j]),je=async(e,s="fine-tuning")=>{if(e.length===0){alert("No images to export");return}A(!0),B(!1);try{const o=(await Te(async()=>{const{default:i}=await import("./vendor-utils-Db80MiSc.js").then(S=>S.j);return{default:i}},__vite__mapDeps([0,1,2]))).default,f=new o,u=e.filter(i=>i.image_type==="crisis_map"),N=e.filter(i=>i.image_type==="drone_image");if(u.length>0){const i=f.folder("crisis_maps_dataset"),S=i?.folder("images");if(S){let T=1;for(const a of u)try{const h=a.image_count&&a.image_count>1?a.all_image_ids||[a.image_id]:[a.image_id],G=h.map(async(n,p)=>{try{const l=await fetch(`/api/images/${n}/file`);if(!l.ok)throw new Error(`Failed to fetch image ${n}`);const r=await l.blob(),c=a.file_key.split(".").pop()||"jpg",d=`${String(T).padStart(4,"0")}_${String(p+1).padStart(2,"0")}.${c}`;return S.file(d,r),{success:!0,fileName:d,imageId:n}}catch(l){return console.error(`Failed to process image ${n}:`,l),{success:!1,fileName:"",imageId:n}}}),I=(await Promise.all(G)).filter(n=>n.success);if(I.length>0){if(s==="fine-tuning"){const n=I.map(r=>`images/${r.fileName}`),p=Math.random(),l={image:n.length===1?n[0]:n,caption:a.edited||a.generated||"",metadata:{image_id:h,title:a.title,source:a.source,event_type:a.event_type,image_type:a.image_type,countries:a.countries,starred:a.starred,image_count:a.image_count||1}};if(!i)continue;if(p<.8){const r=i.file("train.jsonl");if(r){const c=await r.async("string").then(d=>JSON.parse(d||"[]")).catch(()=>[]);c.push(l),i.file("train.jsonl",JSON.stringify(c,null,2))}else i.file("train.jsonl",JSON.stringify([l],null,2))}else if(p<.9){const r=i.file("test.jsonl");if(r){const c=await r.async("string").then(d=>JSON.parse(d||"[]")).catch(()=>[]);c.push(l),i.file("test.jsonl",JSON.stringify(c,null,2))}else i.file("test.jsonl",JSON.stringify([l],null,2))}else{const r=i.file("val.jsonl");if(r){const c=await r.async("string").then(d=>JSON.parse(d||"[]")).catch(()=>[]);c.push(l),i.file("val.jsonl",JSON.stringify(c,null,2))}else i.file("val.jsonl",JSON.stringify([l],null,2))}}else{const n=I.map(l=>`images/${l.fileName}`),p={image:n.length===1?n[0]:n,caption:a.edited||a.generated||"",metadata:{image_id:h,title:a.title,source:a.source,event_type:a.event_type,image_type:a.image_type,countries:a.countries,starred:a.starred,image_count:a.image_count||1}};i&&i.file(`${String(T).padStart(4,"0")}.json`,JSON.stringify(p,null,2))}T++}}catch(h){console.error(`Failed to process caption ${a.image_id}:`,h)}}}if(N.length>0){const i=f.folder("drone_images_dataset"),S=i?.folder("images");if(S){let T=1;for(const a of N)try{const h=a.image_count&&a.image_count>1?a.all_image_ids||[a.image_id]:[a.image_id],G=h.map(async(n,p)=>{try{const l=await fetch(`/api/images/${n}/file`);if(!l.ok)throw new Error(`Failed to fetch image ${n}`);const r=await l.blob(),c=a.file_key.split(".").pop()||"jpg",d=`${String(T).padStart(4,"0")}_${String(p+1).padStart(2,"0")}.${c}`;return S.file(d,r),{success:!0,fileName:d,imageId:n}}catch(l){return console.error(`Failed to process image ${n}:`,l),{success:!1,fileName:"",imageId:n}}}),I=(await Promise.all(G)).filter(n=>n.success);if(I.length>0){if(s==="fine-tuning"){const n=I.map(r=>`images/${r.fileName}`),p=Math.random(),l={image:n.length===1?n[0]:n,caption:a.edited||a.generated||"",metadata:{image_id:h,title:a.title,source:a.source,event_type:a.event_type,image_type:a.image_type,countries:a.countries,starred:a.starred,image_count:a.image_count||1}};if(!i)continue;if(p<.8){const r=i.file("train.jsonl");if(r){const c=await r.async("string").then(d=>JSON.parse(d||"[]")).catch(()=>[]);c.push(l),i.file("train.jsonl",JSON.stringify(c,null,2))}else i.file("train.jsonl",JSON.stringify([l],null,2))}else if(p<.9){const r=i.file("test.jsonl");if(r){const c=await r.async("string").then(d=>JSON.parse(d||"[]")).catch(()=>[]);c.push(l),i.file("test.jsonl",JSON.stringify(c,null,2))}else i.file("test.jsonl",JSON.stringify([l],null,2))}else{const r=i.file("val.jsonl");if(r){const c=await r.async("string").then(d=>JSON.parse(d||"[]")).catch(()=>[]);c.push(l),i.file("val.jsonl",JSON.stringify(c,null,2))}else i.file("val.jsonl",JSON.stringify([l],null,2))}}else{const n=I.map(l=>`images/${l.fileName}`),p={image:n.length===1?n[0]:n,caption:a.edited||a.generated||"",metadata:{image_id:h,title:a.title,source:a.source,event_type:a.event_type,image_type:a.image_type,countries:a.countries,starred:a.starred,image_count:a.image_count||1}};i&&i.file(`${String(T).padStart(4,"0")}.json`,JSON.stringify(p,null,2))}T++}}catch(h){console.error(`Failed to process caption ${a.image_id}:`,h)}}}const V=await f.generateAsync({type:"blob"}),R=URL.createObjectURL(V),w=document.createElement("a");w.href=R,w.download=`datasets_${s}_${new Date().toISOString().split("T")[0]}.zip`,document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL(R);const x=(u.length||0)+(N.length||0);console.log(`Exported ${s} datasets with ${x} total images:`),u.length>0&&console.log(`- Crisis maps: ${u.length} images`),N.length>0&&console.log(`- Drone images: ${N.length} images`),B(!0)}catch(o){console.error("Export failed:",o),alert("Failed to export dataset. Please try again.")}finally{A(!1)}},ve=e=>{te(e),O(!0)},Ne=async()=>{if(M){ae(!0);try{console.log("Deleting image with ID:",M),(await fetch(`/api/images/${M}`,{method:"DELETE"})).ok?(L(s=>s.filter(o=>o.image_id!==M)),O(!1),te("")):(console.error("Delete failed"),alert("Failed to delete image. Please try again."))}catch(e){console.error("Delete failed:",e),alert("Failed to delete image. Please try again.")}finally{ae(!1)}}};return t.jsxs(Ie,{children:[z?t.jsx("div",{className:"flex flex-col items-center justify-center min-h-[60vh]",children:t.jsxs("div",{className:"flex flex-col items-center gap-4",children:[t.jsx(ie,{className:"text-ifrcRed"}),t.jsx("div",{children:"Loading examples..."})]})}):t.jsxs("div",{className:"max-w-7xl mx-auto",children:[t.jsxs("div",{className:g.tabSelector,children:[t.jsx(Ee,{name:"explore-view",value:K,onChange:e=>{(e==="explore"||e==="mapDetails")&&(oe(e),e==="mapDetails"&&_.length>0&&(_[0]?.image_id&&_[0].image_id!=="undefined"&&_[0].image_id!=="null"?k(`/map/${_[0].image_id}`):console.error("Invalid image_id for navigation:",_[0]?.image_id)))},options:ye,keySelector:e=>e.key,labelSelector:e=>e.label}),t.jsxs("div",{className:"flex items-center gap-2 ml-auto",children:[t.jsx(Z,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2",children:t.jsxs(D,{name:"reference-examples",variant:j?"primary":"secondary",onClick:()=>le(!j),className:"whitespace-nowrap",children:[t.jsx("span",{className:"mr-2",children:j?t.jsx("span",{className:"text-yellow-400",children:"β
"}):t.jsx("span",{className:"text-yellow-400",children:"β"})}),"Reference Examples"]})}),t.jsx(D,{name:"export-dataset",variant:"secondary",onClick:()=>U(!0),children:"Export"})]})]}),K==="explore"?t.jsxs("div",{className:"space-y-6",children:[t.jsx("div",{className:"mb-6 space-y-4",children:t.jsx("div",{className:"flex flex-wrap items-center gap-4",children:t.jsx(Z,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2 flex-1 min-w-[300px]",children:t.jsx($e,{sources:J,types:W,regions:Q,countries:ge,imageTypes:X,isLoadingFilters:ue})})})}),t.jsxs("div",{className:"space-y-4",children:[t.jsx("div",{className:"flex justify-between items-center",children:t.jsxs("p",{className:"text-sm text-gray-600",children:[v.length," of ",_.length," examples"]})}),z&&t.jsx("div",{className:"text-center py-12",children:t.jsxs("div",{className:"flex flex-col items-center gap-4",children:[t.jsx(ie,{className:"text-ifrcRed"}),t.jsx("div",{children:"Loading examples..."})]})}),!z&&t.jsxs("div",{className:"space-y-4",children:[v.map(e=>t.jsxs("div",{className:"flex items-center gap-4",children:[t.jsxs("div",{className:`${g.mapItem} flex-1`,onClick:()=>{console.log("ExplorePage: Clicking on image with ID:",e.image_id),console.log("ExplorePage: Image data:",e),e.image_id&&e.image_id!=="undefined"&&e.image_id!=="null"?(console.log("ExplorePage: Navigating to:",`/map/${e.image_id}`),console.log("ExplorePage: Full navigation URL:",`/#/map/${e.image_id}`),k(`/map/${e.image_id}`)):(console.error("Invalid image_id for navigation:",e.image_id),console.error("Full item data:",JSON.stringify(e,null,2)),alert(`Cannot navigate: Invalid image ID (${e.image_id})`))},children:[t.jsx("div",{className:g.mapItemImage,style:{width:"120px",height:"80px"},children:e.image_url?t.jsxs(t.Fragment,{children:[console.log("ExplorePage: Rendering image with URL:",e.image_url),t.jsx("img",{src:e.image_url,alt:e.file_key,onError:s=>{console.error("ExplorePage: Image failed to load:",e.image_url);const o=s.target;o.style.display="none",o.parentElement.innerHTML="Img"},onLoad:()=>console.log("ExplorePage: Image loaded successfully:",e.image_url)})]}):t.jsxs(t.Fragment,{children:[console.log("ExplorePage: No image_url provided for item:",e),"'Img'"]})}),t.jsxs("div",{className:g.mapItemContent,children:[t.jsx("h3",{className:g.mapItemTitle,children:t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("span",{children:e.title||"Untitled"}),e.starred&&t.jsx("span",{className:"text-red-500 text-lg",title:"Starred image",children:"β
"})]})}),t.jsx("div",{className:g.mapItemMetadata,children:t.jsxs("div",{className:g.metadataTags,children:[e.image_type!=="drone_image"&&t.jsx("span",{className:g.metadataTagSource,children:e.source&&e.source.includes(", ")?e.source.split(", ").map(s=>J.find(o=>o.s_code===s.trim())?.label||s.trim()).join(", "):J.find(s=>s.s_code===e.source)?.label||e.source}),t.jsx("span",{className:g.metadataTagType,children:e.event_type&&e.event_type.includes(", ")?e.event_type.split(", ").map(s=>W.find(o=>o.t_code===s.trim())?.label||s.trim()).join(", "):W.find(s=>s.t_code===e.event_type)?.label||e.event_type}),t.jsx("span",{className:g.metadataTag,children:X.find(s=>s.image_type===e.image_type)?.label||e.image_type}),e.image_count&&e.image_count>1&&t.jsxs("span",{className:g.metadataTag,title:`Multi-upload with ${e.image_count} images`,children:["π· ",e.image_count]}),(!e.image_count||e.image_count<=1)&&t.jsx("span",{className:g.metadataTag,title:"Single Upload",children:"Single"}),e.countries&&e.countries.length>0&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:g.metadataTag,children:Q.find(s=>s.r_code===e.countries[0].r_code)?.label||"Unknown Region"}),t.jsx("span",{className:g.metadataTag,children:e.countries.map(s=>s.label).join(", ")})]})]})})]})]}),ne&&t.jsx(Z,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2",children:t.jsx(D,{name:`delete-${e.image_id}`,variant:"tertiary",size:1,className:"bg-red-50 hover:bg-red-100 text-red-700 border border-red-200 hover:border-red-300",onClick:()=>ve(e.image_id),title:"Delete","aria-label":"Delete saved image",children:t.jsx(be,{className:"w-4 h-4"})})})]},e.image_id)),!v.length&&t.jsx("div",{className:"text-center py-12",children:t.jsx("p",{className:"text-gray-500",children:"No examples found."})})]})]})]}):t.jsx("div",{className:"space-y-6",children:t.jsxs("div",{className:"text-center py-12",children:[t.jsx("p",{className:"text-gray-500",children:"Map Details view coming soon..."}),t.jsx("p",{className:"text-sm text-gray-400 mt-2",children:"This will show detailed information about individual maps"})]})})]}),xe&&t.jsx("div",{className:g.fullSizeModalOverlay,onClick:()=>O(!1),children:t.jsx("div",{className:g.fullSizeModalContent,onClick:e=>e.stopPropagation(),children:t.jsxs("div",{className:g.ratingWarningContent,children:[t.jsx("h3",{className:g.ratingWarningTitle,children:"Delete Image?"}),t.jsx("p",{className:g.ratingWarningText,children:"This action cannot be undone. Are you sure you want to delete this saved image and all related data?"}),t.jsxs("div",{className:g.ratingWarningButtons,children:[t.jsx(D,{name:"confirm-delete",variant:"secondary",onClick:Ne,disabled:H,children:H?"Deleting...":"Delete"}),t.jsx(D,{name:"cancel-delete",variant:"tertiary",onClick:()=>O(!1),disabled:H,children:"Cancel"})]})]})})}),t.jsx(Pe,{isOpen:fe,onClose:()=>{U(!1),B(!1),A(!1)},onExport:(e,s)=>{const o=v.filter(f=>s.includes(f.image_type));je(o,e)},filteredCount:v.length,totalCount:_.length,hasFilters:!!(y||E||b||C||$||P||F||j),crisisMapsCount:v.filter(e=>e.image_type==="crisis_map").length,droneImagesCount:v.filter(e=>e.image_type==="drone_image").length,isLoading:he,exportSuccess:_e})]})}export{at as default};
|
py_backend/static/assets/index-Uy48qW96.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DMU6q_dg.js","assets/vendor-react-BxsGb6Ph.js","assets/vendor-DxpCibxB.js","assets/vendor-ui-l_DttnRj.js","assets/vendor-ui-DpEM1HT6.css","assets/index-BsrMOmjk.css","assets/index-CwG_dxMe.js","assets/useAdmin-B_k2Fdj-.js","assets/ExportModal-BtNOxnGZ.js","assets/ExportModal-BoB3JpqO.css","assets/index-BzPMJFRS.css","assets/AdminPage-Dz89QBtX.js","assets/AdminPage-VgSjQ50W.css","assets/index-jo0G9peP.js","assets/index-tDgjKyWF.css"])))=>i.map(i=>d[i]);
|
| 2 |
+
import{r as a,j as e,L as zt,u as Ot,c as $t,R as Bt,b as Ut}from"./vendor-react-BxsGb6Ph.js";import{N as ln,G as Wt,U as Fn,S as Ht,A as Vt,z as U,n as w,M as Gt,Q as qt,a as Yt,b as Zt,L as Kt,B as cn,D as dn,C as Jt,c as Qt,O as D,f as J,d as Ln,e as Xt,_ as rn,R as te,l as ea,t as na}from"./vendor-ui-l_DttnRj.js";import{u as ta,a as un,O as aa,k as sa}from"./vendor-DxpCibxB.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))p(c);new MutationObserver(c=>{for(const d of c)if(d.type==="childList")for(const _ of d.addedNodes)_.tagName==="LINK"&&_.rel==="modulepreload"&&p(_)}).observe(document,{childList:!0,subtree:!0});function o(c){const d={};return c.integrity&&(d.integrity=c.integrity),c.referrerPolicy&&(d.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?d.credentials="include":c.crossOrigin==="anonymous"?d.credentials="omit":d.credentials="same-origin",d}function p(c){if(c.ep)return;c.ep=!0;const d=o(c);fetch(c.href,d)}})();const ia="modulepreload",oa=function(i){return"/"+i},Tn={},B=function(s,o,p){let c=Promise.resolve();if(o&&o.length>0){let S=function(x){return Promise.all(x.map(l=>Promise.resolve(l).then(b=>({status:"fulfilled",value:b}),b=>({status:"rejected",reason:b}))))};document.getElementsByTagName("link");const _=document.querySelector("meta[property=csp-nonce]"),C=_?.nonce||_?.getAttribute("nonce");c=S(o.map(x=>{if(x=oa(x),x in Tn)return;Tn[x]=!0;const l=x.endsWith(".css"),b=l?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${x}"]${b}`))return;const M=document.createElement("link");if(M.rel=l?"stylesheet":ia,l||(M.as="script"),M.crossOrigin="",M.href=x,C&&M.setAttribute("nonce",C),document.head.appendChild(M),l)return new Promise((E,j)=>{M.addEventListener("load",E),M.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${x}`)))})}))}function d(_){const C=new Event("vite:preloadError",{cancelable:!0});if(C.payload=_,window.dispatchEvent(C),!C.defaultPrevented)throw _}return c.then(_=>{for(const C of _||[])C.status==="rejected"&&d(C.reason);return s().catch(d)})},ra="_dropdownContainer_1six7_3",la="_dropdownMenu_1six7_15",ca="_dropdownContent_1six7_43",on={dropdownContainer:ra,dropdownMenu:la,dropdownContent:ca},da=[{to:"/upload",label:"Upload",Icon:Fn},{to:"/explore",label:"Explore",Icon:Ht},{to:"/analytics",label:"Analytics",Icon:Vt}];function ua(){const i=ta(),s=un(),[o,p]=a.useState(!1),c=a.useRef(null);return a.useEffect(()=>{const d=_=>{c.current&&!c.current.contains(_.target)&&p(!1)};return document.addEventListener("mousedown",d),()=>{document.removeEventListener("mousedown",d)}},[]),e.jsx("nav",{className:"border-b border-gray-200 bg-white shadow-sm sticky top-0 z-50 backdrop-blur-sm bg-white/95",children:e.jsxs(ln,{className:"border-b-2 border-ifrcRed",contentClassName:"grid grid-cols-3 items-center py-6",children:[e.jsxs("div",{className:"flex items-center gap-4 min-w-0 cursor-pointer group transition-all duration-200 hover:scale-105",onClick:()=>{if(!(i.pathname==="/upload"||i.pathname==="/")){if(i.pathname==="/upload"){if(window.confirmNavigationIfNeeded){window.confirmNavigationIfNeeded("/");return}if(!confirm("You have unsaved changes. Are you sure you want to leave?"))return}s("/")}},children:[e.jsx("div",{className:"p-2 rounded-lg bg-gradient-to-br from-ifrcRed/10 to-ifrcRed/20 group-hover:from-ifrcRed/20 group-hover:to-ifrcRed/30 transition-all duration-200",children:e.jsx(Wt,{className:"h-8 w-8 flex-shrink-0 text-ifrcRed"})}),e.jsx("div",{className:"flex flex-col",children:e.jsx("span",{className:"font-bold text-xl text-gray-900 leading-tight",children:"PromptAid Vision"})})]}),e.jsx("div",{className:"flex justify-center",children:e.jsx("nav",{className:"flex items-center space-x-4 bg-gray-50/80 rounded-xl p-2 backdrop-blur-sm",children:da.map(({to:d,label:_,Icon:C})=>{const S=i.pathname===d||d==="/upload"&&i.pathname==="/"||d==="/explore"&&i.pathname.startsWith("/map/"),x=i.pathname==="/upload"||i.pathname==="/",l=d==="/upload"||d==="/";return e.jsxs("div",{className:"relative",children:[e.jsx(U,{withInternalPadding:!0,className:"p-2",children:e.jsxs(w,{name:_.toLowerCase(),variant:S?"primary":"tertiary",size:1,className:`transition-all duration-200 ${S?"shadow-lg shadow-ifrcRed/20 transform scale-105":"hover:bg-white hover:shadow-md hover:scale-105"}`,onClick:()=>{if(!(x&&l)){if(i.pathname==="/upload"){if(window.confirmNavigationIfNeeded){window.confirmNavigationIfNeeded(d);return}if(!confirm("You have unsaved changes. Are you sure you want to leave?"))return}s(d)}},children:[e.jsx(C,{className:`w-4 h-4 transition-transform duration-200 ${S?"scale-110":"group-hover:scale-110"}`}),e.jsx("span",{className:"inline ml-2 font-semibold",children:_})]})}),S&&e.jsx("div",{className:"absolute -bottom-2 left-1/2 transform -translate-x-1/2 w-8 h-1 bg-ifrcRed rounded-full animate-pulse"})]},d)})})}),e.jsx("div",{className:"flex justify-end",children:e.jsxs("div",{className:on.dropdownContainer,ref:c,children:[e.jsx(U,{withInternalPadding:!0,className:"p-2",children:e.jsx(w,{name:"more-options",variant:o?"primary":"tertiary",size:1,className:"transition-all duration-200",onClick:()=>p(!o),children:e.jsx(Gt,{className:"w-4 h-4"})})}),o&&e.jsx("div",{className:on.dropdownMenu,children:e.jsxs("div",{className:on.dropdownContent,children:[e.jsx(U,{withInternalPadding:!0,className:"p-2",children:e.jsxs(w,{name:"help-support",variant:"tertiary",size:1,className:"w-full justify-start",onClick:()=>{if(p(!1),i.pathname==="/upload"){if(window.confirmNavigationIfNeeded){window.confirmNavigationIfNeeded("/help");return}if(!confirm("You have unsaved changes. Are you sure you want to leave?"))return}s("/help")},children:[e.jsx(qt,{className:"w-4 h-4"}),e.jsx("span",{className:"ml-2 font-semibold",children:"Help & Support"})]})}),e.jsx(U,{withInternalPadding:!0,className:"p-2",children:e.jsxs(w,{name:"dev",variant:"tertiary",size:1,className:"w-full justify-start",onClick:()=>{if(p(!1),i.pathname==="/upload"){if(window.confirmNavigationIfNeeded){window.confirmNavigationIfNeeded("/admin");return}if(!confirm("You have unsaved changes. Are you sure you want to leave?"))return}s("/admin")},children:[e.jsx(Yt,{className:"w-4 h-4"}),e.jsx("span",{className:"ml-2 font-semibold",children:"Dev"})]})})]})})]})})]})})}function ga(){return e.jsxs(e.Fragment,{children:[e.jsx(ua,{}),e.jsx(aa,{})]})}const pa="_uploadContainer_1w5i1_1",ma="_dropZone_1w5i1_9",ha="_hasFile_1w5i1_30",fa="_dropZoneIcon_1w5i1_37",xa="_dropZoneText_1w5i1_43",va="_dropZoneSubtext_1w5i1_49",_a="_filePreview_1w5i1_55",ja="_filePreviewImage_1w5i1_64",wa="_fileName_1w5i1_110",Ca="_fileInfo_1w5i1_118",ya="_helpLink_1w5i1_125",Sa="_loadingContainer_1w5i1_145",ba="_loadingText_1w5i1_153",Na="_generateButtonContainer_1w5i1_157",ka="_uploadedMapContainer_1w5i1_165",Ia="_uploadedMapImage_1w5i1_169",Ma="_formGrid_1w5i1_209",La="_titleField_1w5i1_222",Ta="_ratingDescription_1w5i1_230",Da="_ratingSlider_1w5i1_235",Ea="_ratingLabel_1w5i1_242",Pa="_ratingInput_1w5i1_251",Fa="_ratingValue_1w5i1_256",Ra="_submitSection_1w5i1_266",Aa="_successContainer_1w5i1_275",za="_successHeading_1w5i1_280",Oa="_successText_1w5i1_285",$a="_successButton_1w5i1_291",Ba="_viewFullSizeButton_1w5i1_297",Ua="_fullSizeModalOverlay_1w5i1_306",Wa="_lightModalOverlay_1w5i1_320",Ha="_fullSizeModalContent_1w5i1_334",Va="_fullSizeModalHeader_1w5i1_345",Ga="_fullSizeModalImage_1w5i1_361",qa="_confirmSection_1w5i1_398",Ya="_step2Layout_1w5i1_407",Za="_topRow_1w5i1_413",Ka="_ratingHidden_1w5i1_421",Ja="_imageSection_1w5i1_425",Qa="_ratingContent_1w5i1_435",Xa="_mapColumn_1w5i1_453",es="_contentColumn_1w5i1_458",ns="_step2bLayout_1w5i1_465",ts="_metadataSectionCard_1w5i1_562",as="_droneMetadataSection_1w5i1_571",ss="_droneMetadataHeading_1w5i1_577",is="_droneMetadataGrid_1w5i1_585",os="_rtkFixContainer_1w5i1_591",rs="_rtkFixLabel_1w5i1_597",ls="_rtkFixCheckbox_1w5i1_606",cs="_confirmButtonContainer_1w5i1_621",ds="_ratingWarningContent_1w5i1_629",us="_ratingWarningTitle_1w5i1_637",gs="_ratingWarningText_1w5i1_644",ps="_ratingWarningButtons_1w5i1_651",ms="_preprocessingProgress_1w5i1_658",hs="_carouselContainer_1w5i1_711",fs="_carouselImageWrapper_1w5i1_716",xs="_carouselImage_1w5i1_716",vs="_carouselNavigation_1w5i1_739",_s="_carouselButton_1w5i1_751",js="_carouselIndicators_1w5i1_775",ws="_carouselIndicator_1w5i1_775",Cs="_carouselIndicatorActive_1w5i1_804",ys="_viewImageButtonContainer_1w5i1_840",t={uploadContainer:pa,dropZone:ma,hasFile:ha,dropZoneIcon:fa,dropZoneText:xa,dropZoneSubtext:va,filePreview:_a,filePreviewImage:ja,fileName:wa,fileInfo:Ca,helpLink:ya,loadingContainer:Sa,loadingText:ba,generateButtonContainer:Na,uploadedMapContainer:ka,uploadedMapImage:Ia,formGrid:Ma,titleField:La,ratingDescription:Ta,ratingSlider:Da,ratingLabel:Ea,ratingInput:Pa,ratingValue:Fa,submitSection:Ra,successContainer:Aa,successHeading:za,successText:Oa,successButton:$a,viewFullSizeButton:Ba,fullSizeModalOverlay:Ua,lightModalOverlay:Wa,fullSizeModalContent:Ha,fullSizeModalHeader:Va,fullSizeModalImage:Ga,confirmSection:qa,step2Layout:Ya,topRow:Za,ratingHidden:Ka,imageSection:Ja,ratingContent:Qa,mapColumn:Xa,contentColumn:es,step2bLayout:ns,metadataSectionCard:ts,droneMetadataSection:as,droneMetadataHeading:ss,droneMetadataGrid:is,rtkFixContainer:os,rtkFixLabel:rs,rtkFixCheckbox:ls,confirmButtonContainer:cs,ratingWarningContent:ds,ratingWarningTitle:us,ratingWarningText:gs,ratingWarningButtons:ps,preprocessingProgress:ms,carouselContainer:hs,carouselImageWrapper:fs,carouselImage:xs,carouselNavigation:vs,carouselButton:_s,carouselIndicators:js,carouselIndicator:ws,carouselIndicatorActive:Cs,viewImageButtonContainer:ys},Rn=a.createContext(void 0),Ss=({children:i})=>{const[s,o]=a.useState(""),[p,c]=a.useState(""),[d,_]=a.useState(""),[C,S]=a.useState(""),[x,l]=a.useState(""),[b,M]=a.useState(""),[E,j]=a.useState(""),[F,A]=a.useState(!1),L={search:s,srcFilter:p,catFilter:d,regionFilter:C,countryFilter:x,imageTypeFilter:b,uploadTypeFilter:E,showReferenceExamples:F,setSearch:o,setSrcFilter:c,setCatFilter:_,setRegionFilter:S,setCountryFilter:l,setImageTypeFilter:M,setUploadTypeFilter:j,setShowReferenceExamples:A,clearAllFilters:()=>{o(""),c(""),_(""),S(""),l(""),M(""),j(""),A(!1)}};return e.jsx(Rn.Provider,{value:L,children:i})},bs=()=>{const i=a.useContext(Rn);if(i===void 0)throw new Error("useFilterContext must be used within a FilterProvider");return i};function Dn({files:i,file:s,preview:o,imageType:p,onFileChange:c,onRemoveImage:d,onAddImage:_,onImageTypeChange:C,onChangeFile:S}){const x=l=>{l.preventDefault();const b=l.dataTransfer.files?.[0];b&&c(b)};return e.jsxs("div",{className:"space-y-6",children:[e.jsx("p",{className:"text-gray-700 leading-relaxed max-w-2xl mx-auto",children:"This app evaluates how well multimodal AI models analyze and describe crisis maps and drone imagery. Upload an image and the AI will generate a description. Then you can review and rate the result based on your expertise."}),e.jsx("div",{className:t.helpLink,children:e.jsxs(zt,{to:"/help",className:t.helpLink,children:["More ",e.jsx(Zt,{className:"w-3 h-3"})]})}),e.jsx("div",{className:"flex justify-center",children:e.jsx(U,{withInternalPadding:!0,className:"bg-transparent border-none shadow-none",children:e.jsx(Kt,{name:"image-type",value:p,onChange:l=>C(l),options:[{key:"crisis_map",label:"Crisis Maps"},{key:"drone_image",label:"Drone Imagery"}],keySelector:l=>l.key,labelSelector:l=>l.label})})}),e.jsxs("div",{className:`${t.dropZone} ${s?t.hasFile:""}`,onDragOver:l=>l.preventDefault(),onDrop:x,children:[i.length>1?e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-4",children:i.map((l,b)=>e.jsxs("div",{className:"relative",children:[e.jsx("img",{src:URL.createObjectURL(l),alt:`Image ${b+1}`,className:"w-full h-32 object-cover rounded"}),e.jsx(cn,{name:"remove-image",variant:"tertiary",onClick:()=>d(b),title:"Remove image",ariaLabel:"Remove image",className:"absolute top-2 right-2 bg-white/90 hover:bg-white shadow-md hover:shadow-lg border border-gray-200 hover:border-red-300 transition-all duration-200 backdrop-blur-sm",children:e.jsx(dn,{className:"w-4 h-4"})}),e.jsx("div",{className:"text-xs text-center mt-1",children:l.name})]},b))}):s&&o?e.jsxs("div",{className:t.filePreview,children:[e.jsx("div",{className:t.filePreviewImage,children:e.jsx("img",{src:o,alt:"File preview"})}),e.jsx("p",{className:t.fileName,children:s.name}),e.jsxs("p",{className:t.fileInfo,children:[(s.size/1024/1024).toFixed(2)," MB"]})]}):e.jsxs(e.Fragment,{children:[e.jsx(Fn,{className:t.dropZoneIcon}),e.jsx("p",{className:t.dropZoneText,children:"Drag & Drop any file here"}),e.jsx("p",{className:t.dropZoneSubtext,children:"or"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("label",{className:"inline-block cursor-pointer",children:[e.jsx("input",{type:"file",className:"sr-only",accept:".jpg,.jpeg,.png,.tiff,.tif,.heic,.heif,.webp,.gif,.pdf",onChange:l=>{s&&S?S(l.target.files?.[0]):c(l.target.files?.[0])}}),e.jsx(w,{name:"upload",variant:"secondary",size:1,onClick:()=>document.querySelector('input[type="file"]')?.click(),children:s?"Change Image":"Browse Files"})]}),s&&i.length<5&&e.jsx(w,{name:"add-image",variant:"secondary",size:1,onClick:_,children:"Add Image"})]})]})]})}function En({files:i,imageUrl:s,preview:o,onViewFullSize:p,currentImageIndex:c=0,onGoToPrevious:d,onGoToNext:_,onGoToImage:C,showCarousel:S=!1}){return S&&i.length>1?e.jsx(U,{heading:"Uploaded Images",headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,children:e.jsxs("div",{className:t.carouselContainer,children:[e.jsx("div",{className:t.carouselImageWrapper,children:i[c]?e.jsx("img",{src:URL.createObjectURL(i[c]),alt:`Image ${c+1}`,className:t.carouselImage}):e.jsx("div",{className:t.imagePlaceholder,children:"No image available"})}),e.jsxs("div",{className:t.carouselNavigation,children:[e.jsx(w,{name:"previous-image",variant:"tertiary",size:1,onClick:d,className:t.carouselButton,children:e.jsx(Jt,{className:"w-4 h-4"})}),e.jsx("div",{className:t.carouselIndicators,children:i.map((x,l)=>e.jsx("button",{onClick:()=>C?.(l),className:`${t.carouselIndicator} ${l===c?t.carouselIndicatorActive:""}`,children:l+1},l))}),e.jsx(w,{name:"next-image",variant:"tertiary",size:1,onClick:_,className:t.carouselButton,children:e.jsx(Qt,{className:"w-4 h-4"})})]}),e.jsx("div",{className:t.viewImageButtonContainer,children:e.jsx(w,{name:"view-full-size-carousel",variant:"secondary",size:1,onClick:()=>p({file:i[c],index:c}),disabled:!i[c],children:"View Image"})})]})}):i.length>1?e.jsx("div",{className:"space-y-6",children:i.map((x,l)=>e.jsx(U,{heading:`Image ${l+1}: ${x.name}`,headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,children:e.jsxs("div",{className:t.uploadedMapContainer,children:[e.jsx("div",{className:t.uploadedMapImage,children:e.jsx("img",{src:URL.createObjectURL(x),alt:`Image ${l+1}`})}),e.jsx("div",{className:t.viewFullSizeButton,children:e.jsx(w,{name:`view-full-size-${l}`,variant:"secondary",size:1,onClick:()=>p({file:x,index:l}),children:"View Image"})})]})},l))}):e.jsx(U,{heading:"Uploaded Image",headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,children:e.jsxs("div",{className:t.uploadedMapContainer,children:[e.jsx("div",{className:t.uploadedMapImage,children:e.jsx("img",{src:s||o||void 0,alt:"Uploaded image preview"})}),e.jsx("div",{className:t.viewFullSizeButton,children:e.jsx(w,{name:"view-full-size",variant:"secondary",size:1,onClick:()=>p(),children:"View Image"})})]})})}function Ns({files:i,imageType:s,title:o,source:p,eventType:c,epsg:d,countries:_,centerLon:C,centerLat:S,amslM:x,aglM:l,headingDeg:b,yawDeg:M,pitchDeg:E,rollDeg:j,rtkFix:F,stdHM:A,stdVM:z,metadataArray:L,sources:G,types:q,spatialReferences:Y,imageTypes:R,countriesOptions:Q,onTitleChange:Z,onSourceChange:ae,onEventTypeChange:K,onEpsgChange:se,onCountriesChange:ie,onCenterLonChange:oe,onCenterLatChange:re,onAmslMChange:le,onAglMChange:ce,onHeadingDegChange:de,onYawDegChange:ue,onPitchDegChange:ge,onRollDegChange:pe,onRtkFixChange:me,onStdHMChange:he,onStdVMChange:fe,onImageTypeChange:xe,updateMetadataForImage:P}){return i.length>1?e.jsxs("div",{children:[e.jsx("div",{className:"mb-4",children:e.jsx(D,{label:"Shared Title",name:"title",value:o,onChange:Z,placeholder:"Enter a title for all images...",required:!0})}),i.map((N,m)=>e.jsx("div",{className:"mb-6",children:e.jsx(U,{heading:`Image ${m+1}: ${N.name}`,headingLevel:4,withHeaderBorder:!0,withInternalPadding:!0,children:e.jsxs("div",{className:t.formGrid,children:[s!=="drone_image"&&e.jsx(J,{label:"Source",name:`source_${m}`,value:L[m]?.source||"",onChange:h=>P(m,"source",h),options:G,keySelector:h=>h.s_code,labelSelector:h=>h.label,required:!0}),e.jsx(J,{label:"Event Type",name:`event_type_${m}`,value:L[m]?.eventType||"",onChange:h=>P(m,"eventType",h),options:q,keySelector:h=>h.t_code,labelSelector:h=>h.label,required:s!=="drone_image"}),e.jsx(J,{label:"EPSG",name:`epsg_${m}`,value:L[m]?.epsg||"",onChange:h=>P(m,"epsg",h),options:Y,keySelector:h=>h.epsg,labelSelector:h=>`${h.srid} (EPSG:${h.epsg})`,placeholder:"EPSG",required:s!=="drone_image"}),e.jsx(Ln,{label:"Countries (optional)",name:`countries_${m}`,value:L[m]?.countries||[],onChange:h=>P(m,"countries",h),options:Q,keySelector:h=>h.c_code,labelSelector:h=>h.label,placeholder:"Select one or more"}),s==="drone_image"&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:t.droneMetadataSection,children:[e.jsx("h4",{className:t.droneMetadataHeading,children:"Drone Flight Data"}),e.jsxs("div",{className:t.droneMetadataGrid,children:[e.jsx(D,{label:"Center Longitude",name:`center_lon_${m}`,value:L[m]?.centerLon||"",onChange:h=>P(m,"centerLon",h),placeholder:"e.g., -122.4194",step:"any"}),e.jsx(D,{label:"Center Latitude",name:`center_lat_${m}`,value:L[m]?.centerLat||"",onChange:h=>P(m,"centerLat",h),placeholder:"e.g., 37.7749",step:"any"}),e.jsx(D,{label:"Altitude AMSL (m)",name:`amsl_m_${m}`,value:L[m]?.amslM||"",onChange:h=>P(m,"amslM",h),placeholder:"e.g., 100.5",step:"any"}),e.jsx(D,{label:"Altitude AGL (m)",name:`agl_m_${m}`,value:L[m]?.aglM||"",onChange:h=>P(m,"aglM",h),placeholder:"e.g., 50.2",step:"any"}),e.jsx(D,{label:"Heading (degrees)",name:`heading_deg_${m}`,value:L[m]?.headingDeg||"",onChange:h=>P(m,"headingDeg",h),placeholder:"e.g., 180.0",step:"any"}),e.jsx(D,{label:"Yaw (degrees)",name:`yaw_deg_${m}`,value:L[m]?.yawDeg||"",onChange:h=>P(m,"yawDeg",h),placeholder:"e.g., 90.0",step:"any"}),e.jsx(D,{label:"Pitch (degrees)",name:`pitch_deg_${m}`,value:L[m]?.pitchDeg||"",onChange:h=>P(m,"pitchDeg",h),placeholder:"e.g., 0.0",step:"any"}),e.jsx(D,{label:"Roll (degrees)",name:`roll_deg_${m}`,value:L[m]?.rollDeg||"",onChange:h=>P(m,"rollDeg",h),placeholder:"e.g., 0.0",step:"any"}),e.jsx("div",{className:t.rtkFixContainer,children:e.jsxs("label",{className:t.rtkFixLabel,children:[e.jsx("input",{type:"checkbox",checked:L[m]?.rtkFix||!1,onChange:h=>P(m,"rtkFix",h.target.checked),className:t.rtkFixCheckbox}),"RTK Fix Available"]})}),e.jsx(D,{label:"Horizontal Std Dev (m)",name:`std_h_m_${m}`,value:L[m]?.stdHM||"",onChange:h=>P(m,"stdHM",h),placeholder:"e.g., 0.1",step:"any"}),e.jsx(D,{label:"Vertical Std Dev (m)",name:`std_v_m_${m}`,value:L[m]?.stdVM||"",onChange:h=>P(m,"stdVM",h),placeholder:"e.g., 0.2",step:"any"})]})]})})]})})},m))]}):e.jsxs("div",{className:t.formGrid,children:[e.jsx("div",{className:t.titleField,children:e.jsx(D,{label:"Title",name:"title",value:o,onChange:Z,placeholder:"Enter a title for this map...",required:!0})}),s!=="drone_image"&&e.jsx(J,{label:"Source",name:"source",value:p,onChange:ae,options:G,keySelector:N=>N.s_code,labelSelector:N=>N.label,required:!0}),e.jsx(J,{label:"Event Type",name:"event_type",value:c,onChange:K,options:q,keySelector:N=>N.t_code,labelSelector:N=>N.label,required:s!=="drone_image"}),e.jsx(J,{label:"EPSG",name:"epsg",value:d,onChange:se,options:Y,keySelector:N=>N.epsg,labelSelector:N=>`${N.srid} (EPSG:${N.epsg})`,placeholder:"EPSG",required:s!=="drone_image"}),e.jsx(J,{label:"Image Type",name:"image_type",value:s,onChange:xe,options:R,keySelector:N=>N.image_type,labelSelector:N=>N.label,required:!0}),e.jsx(Ln,{label:"Countries (optional)",name:"countries",value:_,onChange:ie,options:Q,keySelector:N=>N.c_code,labelSelector:N=>N.label,placeholder:"Select one or more"}),s==="drone_image"&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:t.droneMetadataSection,children:[e.jsx("h4",{className:t.droneMetadataHeading,children:"Drone Flight Data"}),e.jsxs("div",{className:t.droneMetadataGrid,children:[e.jsx(D,{label:"Center Longitude",name:"center_lon",value:C,onChange:oe,placeholder:"e.g., -122.4194",step:"any"}),e.jsx(D,{label:"Center Latitude",name:"center_lat",value:S,onChange:re,placeholder:"e.g., 37.7749",step:"any"}),e.jsx(D,{label:"Altitude AMSL (m)",name:"amsl_m",value:x,onChange:le,placeholder:"e.g., 100.5",step:"any"}),e.jsx(D,{label:"Altitude AGL (m)",name:"agl_m",value:l,onChange:ce,placeholder:"e.g., 50.2",step:"any"}),e.jsx(D,{label:"Heading (degrees)",name:"heading_deg",value:b,onChange:de,placeholder:"e.g., 180.0",step:"any"}),e.jsx(D,{label:"Yaw (degrees)",name:"yaw_deg",value:M,onChange:ue,placeholder:"e.g., 90.0",step:"any"}),e.jsx(D,{label:"Pitch (degrees)",name:"pitch_deg",value:E,onChange:ge,placeholder:"e.g., 0.0",step:"any"}),e.jsx(D,{label:"Roll (degrees)",name:"roll_deg",value:j,onChange:pe,placeholder:"e.g., 0.0",step:"any"}),e.jsx("div",{className:t.rtkFixContainer,children:e.jsxs("label",{className:t.rtkFixLabel,children:[e.jsx("input",{type:"checkbox",checked:F,onChange:N=>me(N.target.checked),className:t.rtkFixCheckbox}),"RTK Fix Available"]})}),e.jsx(D,{label:"Horizontal Std Dev (m)",name:"std_h_m",value:A,onChange:he,placeholder:"e.g., 0.1",step:"any"}),e.jsx(D,{label:"Vertical Std Dev (m)",name:"std_v_m",value:z,onChange:fe,placeholder:"e.g., 0.2",step:"any"})]})]})})]})}function ks({isPerformanceConfirmed:i,scores:s,onScoreChange:o,onConfirmRatings:p,onEditRatings:c}){return i?null:e.jsx(U,{heading:"AI Performance Rating",headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,children:e.jsxs("div",{className:t.ratingContent,children:[e.jsx("p",{className:t.ratingDescription,children:"How well did the AI perform on the task?"}),["accuracy","context","usability"].map(d=>e.jsxs("div",{className:t.ratingSlider,children:[e.jsx("label",{className:t.ratingLabel,children:d}),e.jsx("input",{type:"range",min:0,max:100,value:s[d],onChange:_=>o(d,Number(_.target.value)),className:t.ratingInput}),e.jsx("span",{className:t.ratingValue,children:s[d]})]},d)),e.jsx("div",{className:t.confirmButtonContainer,children:e.jsx(w,{name:"confirm-ratings",variant:"secondary",onClick:p,children:"Confirm Ratings"})})]})})}function Is({description:i,analysis:s,recommendedActions:o,onDescriptionChange:p,onAnalysisChange:c,onRecommendedActionsChange:d,onBack:_,onDelete:C,onSubmit:S,onEditRatings:x,isPerformanceConfirmed:l=!1}){const b=M=>{if(M){const E=M.split(`
|
| 3 |
+
`),j=E.findIndex(z=>z.startsWith("Description:")),F=E.findIndex(z=>z.startsWith("Analysis:")),A=E.findIndex(z=>z.startsWith("Recommended Actions:"));j!==-1&&F!==-1&&A!==-1&&(p(E.slice(j+1,F).join(`
|
| 4 |
+
`).trim()),c(E.slice(F+1,A).join(`
|
| 5 |
+
`).trim()),d(E.slice(A+1).join(`
|
| 6 |
+
`).trim()))}};return e.jsxs(U,{heading:"Generated Text",headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,children:[e.jsx("div",{className:"text-left space-y-4",children:e.jsx("div",{children:e.jsx(Xt,{name:"generatedContent",value:`Description:
|
| 7 |
+
${i||"AI-generated description will appear here..."}
|
| 8 |
+
|
| 9 |
+
Analysis:
|
| 10 |
+
${s||"AI-generated analysis will appear here..."}
|
| 11 |
+
|
| 12 |
+
Recommended Actions:
|
| 13 |
+
${o||"AI-generated recommended actions will appear here..."}`,onChange:b,rows:12,placeholder:"AI-generated content will appear here..."})})}),e.jsxs("div",{className:t.submitSection,children:[e.jsx(w,{name:"back",variant:"secondary",onClick:_,children:"Back"}),l&&x&&e.jsx(w,{name:"edit-ratings",variant:"secondary",onClick:x,children:"Edit Ratings"}),e.jsx(cn,{name:"delete",variant:"tertiary",onClick:C,title:"Delete",ariaLabel:"Delete uploaded image",children:e.jsx(dn,{})}),e.jsx(w,{name:"submit",onClick:S,children:"Submit"})]})]})}function Ms({isOpen:i,imageUrl:s,preview:o,selectedImageData:p,onClose:c}){if(!i)return null;let d,_;return p?(d=URL.createObjectURL(p.file),_=`Image ${p.index+1}: ${p.file.name}`):(d=s||o||void 0,_="Full size map"),e.jsx("div",{className:t.fullSizeModalOverlay,onClick:c,children:e.jsxs("div",{className:t.fullSizeModalContent,onClick:C=>C.stopPropagation(),children:[e.jsx("div",{className:t.fullSizeModalHeader,children:e.jsx(w,{name:"close-modal",variant:"tertiary",size:1,onClick:c,children:"β"})}),e.jsx("div",{className:t.fullSizeModalImage,children:e.jsx("img",{src:d,alt:_})})]})})}function Ls({isOpen:i,onClose:s}){return i?e.jsx("div",{className:t.fullSizeModalOverlay,onClick:s,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:o=>o.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"Please Confirm Your Ratings"}),e.jsx("p",{className:t.ratingWarningText,children:'You must confirm your performance ratings before submitting. Please go back to the rating section and click "Confirm Ratings".'}),e.jsx("div",{className:t.ratingWarningButtons,children:e.jsx(w,{name:"close-warning",variant:"secondary",onClick:s,children:"Close"})})]})})}):null}function Ts({isOpen:i,onConfirm:s,onCancel:o}){return i?e.jsx("div",{className:t.fullSizeModalOverlay,onClick:o,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:p=>p.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"Delete Image?"}),e.jsx("p",{className:t.ratingWarningText,children:"This action cannot be undone. Are you sure you want to delete this uploaded image?"}),e.jsxs("div",{className:t.ratingWarningButtons,children:[e.jsx(w,{name:"confirm-delete",variant:"secondary",onClick:s,children:"Delete"}),e.jsx(w,{name:"cancel-delete",variant:"tertiary",onClick:o,children:"Cancel"})]})]})})}):null}function Ds({isOpen:i,onConfirm:s,onCancel:o}){return i?e.jsx("div",{className:t.fullSizeModalOverlay,onClick:o,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:p=>p.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"Leave Page?"}),e.jsx("p",{className:t.ratingWarningText,children:"Your uploaded image will be deleted if you leave this page. Are you sure you want to continue?"}),e.jsxs("div",{className:t.ratingWarningButtons,children:[e.jsx(w,{name:"confirm-navigation",variant:"secondary",onClick:s,children:"Leave Page"}),e.jsx(w,{name:"cancel-navigation",variant:"tertiary",onClick:o,children:"Stay"})]})]})})}):null}function Es({isOpen:i,fallbackInfo:s,onClose:o}){return!i||!s?null:e.jsx("div",{className:t.fullSizeModalOverlay,onClick:o,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:p=>p.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"Model Changed"}),e.jsxs("p",{className:t.ratingWarningText,children:[s.originalModel," is currently unavailable. We've automatically switched to ",s.fallbackModel," to complete your request."]}),e.jsx("div",{className:t.ratingWarningButtons,children:e.jsx(w,{name:"close-fallback",variant:"secondary",onClick:o,children:"Got it"})})]})})})}function Ps({isOpen:i,preprocessingInfo:s,onClose:o}){return!i||!s?null:e.jsx("div",{className:t.fullSizeModalOverlay,onClick:o,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:p=>p.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"File Converted"}),e.jsxs("p",{className:t.ratingWarningText,children:["Your file ",e.jsx("strong",{children:s.original_filename})," has been converted from",e.jsxs("strong",{children:[" ",s.original_mime_type]})," to",e.jsxs("strong",{children:[" ",s.processed_mime_type]})," for optimal processing.",e.jsx("br",{}),e.jsx("br",{}),"This conversion ensures your file is in the best format for our AI models to analyze."]}),e.jsx("div",{className:t.ratingWarningButtons,children:e.jsx(w,{name:"close-preprocessing",variant:"secondary",onClick:o,children:"Got it"})})]})})})}function Fs({isOpen:i,preprocessingFile:s,isPreprocessing:o,preprocessingProgress:p,onConfirm:c,onCancel:d}){return i?e.jsx("div",{className:t.fullSizeModalOverlay,onClick:o?void 0:d,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:_=>_.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"File Conversion Required"}),e.jsx("p",{className:t.ratingWarningText,children:"The file you selected will be converted to PNG format. This ensures optimal compatibility and processing by our AI models."}),!o&&e.jsxs("div",{className:t.ratingWarningButtons,children:[e.jsx(w,{name:"confirm-preprocessing",variant:"secondary",onClick:c,children:"Convert File"}),e.jsx(w,{name:"cancel-preprocessing",variant:"tertiary",onClick:d,children:"Cancel"})]}),o&&e.jsxs("div",{className:t.preprocessingProgress,children:[e.jsx("p",{children:p}),e.jsx(rn,{className:"text-ifrcRed"})]})]})})}):null}function Rs({isOpen:i,unsupportedFile:s,onClose:o}){return!i||!s?null:e.jsx("div",{className:t.fullSizeModalOverlay,onClick:o,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:p=>p.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"Unsupported File Format"}),e.jsxs("p",{className:t.ratingWarningText,children:["The file ",e.jsx("strong",{children:s.name})," is not supported for upload.",e.jsx("br",{}),e.jsx("br",{}),e.jsx("strong",{children:"Supported formats:"}),e.jsx("br",{}),"β’ Images: JPEG, PNG, TIFF, HEIC, WebP, GIF",e.jsx("br",{}),"β’ Documents: PDF (will be converted to image)",e.jsx("br",{}),e.jsx("br",{}),e.jsx("strong",{children:"Recommendation:"})," Convert your file to JPEG or PNG format for best compatibility."]}),e.jsx("div",{className:t.ratingWarningButtons,children:e.jsx(w,{name:"close-unsupported",variant:"secondary",onClick:o,children:"Got it"})})]})})})}function As({isOpen:i,oversizedFile:s,onClose:o,onCancel:p}){return!i||!s?null:e.jsx("div",{className:t.lightModalOverlay,onClick:p,children:e.jsx("div",{className:t.fullSizeModalContent,onClick:c=>c.stopPropagation(),children:e.jsxs("div",{className:t.ratingWarningContent,children:[e.jsx("h3",{className:t.ratingWarningTitle,children:"File Size Warning"}),e.jsxs("p",{className:t.ratingWarningText,children:["The file ",e.jsx("strong",{children:s.name})," is large (",(s.size/(1024*1024)).toFixed(1),"MB).",e.jsx("br",{}),e.jsx("br",{}),e.jsx("strong",{children:"Warning:"})," This file size might exceed the limits of the AI models we use.",e.jsx("br",{}),e.jsx("br",{}),"You can still proceed, but consider using a smaller file if you encounter issues."]}),e.jsxs("div",{className:t.ratingWarningButtons,children:[e.jsx(w,{name:"continue-size-warning",variant:"secondary",onClick:o,children:"Continue"}),e.jsx(w,{name:"cancel-size-warning",variant:"tertiary",onClick:p,children:"Cancel"})]})]})})})}const Pe="selectedVlmModel";function Pn(){const[i]=Ot(),s=un(),[o,p]=a.useState(1),[c,d]=a.useState(!1),[_,C]=a.useState(!1),S=a.useRef(o),x=a.useRef(null),[l,b]=a.useState(null),[M,E]=a.useState(null),[j,F]=a.useState([]),[A,z]=a.useState(""),[L,G]=a.useState(""),[q,Y]=a.useState(""),[R,Q]=a.useState("crisis_map"),[Z,ae]=a.useState([]),[K,se]=a.useState(""),[ie,oe]=a.useState(""),[re,le]=a.useState(""),[ce,de]=a.useState(""),[ue,ge]=a.useState(""),[pe,me]=a.useState(""),[he,fe]=a.useState(""),[xe,P]=a.useState(""),[N,m]=a.useState(""),[h,Fe]=a.useState(!1),[Re,Ae]=a.useState(""),[ze,Oe]=a.useState(""),[$e,Se]=a.useState([]),[An,zn]=a.useState([]),[On,$n]=a.useState([]),[Bn,Un]=a.useState([]),[Wn,Hn]=a.useState([]),[Vn,Gn]=a.useState([]),[W,be]=a.useState(null),[Be,X]=a.useState([]),[Ne,gn]=a.useState(null),[qn,pn]=a.useState(""),[mn,Ue]=a.useState(""),[hn,We]=a.useState(""),[fn,He]=a.useState(""),[ke,xn]=a.useState({accuracy:50,context:50,usability:50}),[Yn,Ve]=a.useState(!1),[Zn,Ge]=a.useState(null),[ve,Ie]=a.useState(!1),[Kn,vn]=a.useState(!1),[Jn,qe]=a.useState(!1),[Qn,Me]=a.useState(!1),[Ye,Ze]=a.useState(null),[Xn,Ke]=a.useState(!1),[et,_n]=a.useState(null),[nt,Je]=a.useState(!1),[tt,jn]=a.useState(null),[at,ee]=a.useState(!1),[Qe,ne]=a.useState(null),[st,_e]=a.useState(!1),[it,H]=a.useState(""),[ot,Le]=a.useState(!1),[rt,Xe]=a.useState(null),[lt,je]=a.useState(!1),[ct,en]=a.useState(null),[dt,Te]=a.useState(0);S.current=o,x.current=W;const ut=n=>z(n||""),gt=n=>G(n||""),pt=n=>Y(n||""),nn=n=>Q(n||""),mt=n=>ae(Array.isArray(n)?n:[]),ht=n=>oe(n||""),ft=n=>le(n||""),xt=n=>de(n||""),vt=n=>ge(n||""),_t=n=>me(n||""),jt=n=>fe(n||""),wt=n=>P(n||""),Ct=n=>m(n||""),yt=n=>Fe(n||!1),St=n=>Ae(n||""),bt=n=>Oe(n||""),De=n=>p(n),Nt=a.useCallback(()=>{j.length>1&&Te(n=>n>0?n-1:j.length-1)},[j.length]),kt=a.useCallback(()=>{j.length>1&&Te(n=>n<j.length-1?n+1:0)},[j.length]),It=a.useCallback(n=>{n>=0&&n<j.length&&Te(n)},[j.length]),wn=()=>{if(j.length<5){const n=document.createElement("input");n.type="file",n.accept=".jpg,.jpeg,.png,.tiff,.tif,.heic,.heif,.webp,.gif,.pdf",n.onchange=f=>{const u=f.target;if(u.files&&u.files[0]){const g=u.files[0];tn(g)}},n.click()}},Cn=n=>{F(f=>{const u=f.filter((g,r)=>r!==n);return u.length===1?E(u[0]):u.length===0&&E(null),u}),Se(f=>f.filter((u,g)=>g!==n))},Mt=(n,f,u)=>{Se(g=>{const r=[...g];return r[n]||(r[n]={source:"",eventType:"",epsg:"",countries:[],centerLon:"",centerLat:"",amslM:"",aglM:"",headingDeg:"",yawDeg:"",pitchDeg:"",rollDeg:"",rtkFix:!1,stdHM:"",stdVM:""}),r[n]={...r[n],[f]:u},r})},yn=n=>{const f=["image/jpeg","image/jpg","image/png"],u=[".jpg",".jpeg",".png"];let g=!f.includes(n.type);if(!g&&n.name){const r=n.name.toLowerCase().substring(n.name.lastIndexOf("."));g=!u.includes(r)}return g},Sn=n=>{const f=["text/html","text/css","application/javascript","application/json","text/plain","application/xml","text/xml","application/zip","application/x-zip-compressed","application/x-rar-compressed","application/x-7z-compressed","audio/","video/","text/csv","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document"];for(const u of f)if(n.type.startsWith(u))return!0;if(n.name){const u=n.name.toLowerCase().substring(n.name.lastIndexOf("."));if([".html",".htm",".css",".js",".json",".txt",".xml",".zip",".rar",".7z",".csv",".xlsx",".xls",".pptx",".ppt",".docx",".doc",".mp3",".mp4",".avi",".mov"].includes(u))return!0}return!1},tn=n=>{if(n){if(console.log("File selected:",n.name,"Type:",n.type,"Size:",n.size),n.size/(1024*1024)>5&&(console.log("File too large, showing size warning modal"),en(n),je(!0)),Sn(n)){console.log("File format not supported at all, showing unsupported format modal"),Xe(n),Le(!0);return}yn(n)?(console.log("File needs preprocessing, showing modal"),ne(n),ee(!0)):(console.log("File does not need preprocessing, setting directly"),j.length===0?(E(n),F([n])):F(u=>[...u,n]))}},bn=n=>{if(n){if(console.log("File changed:",n.name,"Type:",n.type,"Size:",n.size),n.size/(1024*1024)>5&&(console.log("File too large, showing size warning modal"),en(n),je(!0)),Sn(n)){console.log("File format not supported at all, showing unsupported format modal"),Xe(n),Le(!0);return}yn(n)?(console.log("File needs preprocessing, showing modal"),ne(n),ee(!0)):(console.log("File does not need preprocessing, replacing last file"),j.length>1?(F(u=>{const g=[...u];return g[g.length-1]=n,g}),j.length===1&&E(n)):(E(n),F([n])))}};async function we(n){const f=await n.text();try{return f?JSON.parse(f):{}}catch{return{error:f}}}function an(n,f){const u=n instanceof Error?n.message:`Failed to ${f.toLowerCase()}`;alert(u)}async function Nn(){if(j.length!==0){d(!0);try{j.length===1?await Lt():await Tt()}catch(n){an(n,"Upload")}finally{d(!1)}}}async function Lt(){console.log("DEBUG: Starting single image upload");const n=new FormData;n.append("file",j[0]),n.append("title",K),n.append("image_type",R),A&&n.append("source",A),L&&n.append("event_type",L),q&&n.append("epsg",q),Z.length>0&&Z.forEach(r=>n.append("countries",r)),R==="drone_image"&&(ie&&n.append("center_lon",ie),re&&n.append("center_lat",re),ce&&n.append("amsl_m",ce),ue&&n.append("agl_m",ue),pe&&n.append("heading_deg",pe),he&&n.append("yaw_deg",he),xe&&n.append("pitch_deg",xe),N&&n.append("roll_deg",N),h&&n.append("rtk_fix",h.toString()),Re&&n.append("std_h_m",Re),ze&&n.append("std_v_m",ze));const f=localStorage.getItem(Pe);f&&n.append("model_name",f);const u=await fetch("/api/images/",{method:"POST",body:n}),g=await we(u);if(!u.ok)throw new Error(g.error||"Upload failed");console.log("DEBUG: Single upload response:",g),await kn(g,!1)}async function Tt(){console.log("DEBUG: Starting multi-image upload");const n=new FormData;j.forEach(r=>n.append("files",r)),n.append("title",K),n.append("image_type",R),$e.forEach((r,v)=>{r.source&&n.append(`source_${v}`,r.source),r.eventType&&n.append(`event_type_${v}`,r.eventType),r.epsg&&n.append(`epsg_${v}`,r.epsg),r.countries.length>0&&r.countries.forEach(T=>n.append(`countries_${v}`,T)),R==="drone_image"&&(r.centerLon&&n.append(`center_lon_${v}`,r.centerLon),r.centerLat&&n.append(`center_lat_${v}`,r.centerLat),r.amslM&&n.append(`amsl_m_${v}`,r.amslM),r.aglM&&n.append(`agl_m_${v}`,r.aglM),r.headingDeg&&n.append(`heading_deg_${v}`,r.headingDeg),r.yawDeg&&n.append(`yaw_deg_${v}`,r.yawDeg),r.pitchDeg&&n.append(`pitch_deg_${v}`,r.pitchDeg),r.rollDeg&&n.append(`roll_deg_${v}`,r.rollDeg),r.rtkFix&&n.append(`rtk_fix_${v}`,r.rtkFix.toString()),r.stdHM&&n.append(`std_h_m_${v}`,r.stdHM),r.stdVM&&n.append(`std_v_m_${v}`,r.stdVM))});const f=localStorage.getItem(Pe);f&&n.append("model_name",f);const u=await fetch("/api/images/multi",{method:"POST",body:n}),g=await we(u);if(!u.ok)throw new Error(g.error||"Upload failed");console.log("DEBUG: Multi upload response:",g),await kn(g,!0)}async function kn(n,f){gn(n.image_url),n.preprocessing_info&&typeof n.preprocessing_info=="object"&&"was_preprocessed"in n.preprocessing_info&&n.preprocessing_info.was_preprocessed===!0&&(jn(n.preprocessing_info),Je(!0));const u=n.image_id;if(!u)throw new Error("Upload failed: image_id not found");if(be(u),f)if(n.image_ids&&Array.isArray(n.image_ids)){const y=n.image_ids;console.log("DEBUG: Storing image IDs for multi-upload:",y),X(y)}else console.log("DEBUG: Multi-upload but no image_ids found, using single ID"),X([u]);else console.log("DEBUG: Storing single image ID:",u),X([u]);const g=n,r=g.raw_json?.fallback_info;r&&(_n({originalModel:r.original_model,fallbackModel:r.fallback_model,reason:r.reason}),Ke(!0));const v=g.raw_json?.metadata;if(v){const y=v.metadata||v;if(y&&typeof y=="object"){const O=[];if(f){const k=y.metadata_images;if(k&&typeof k=="object")for(let $=1;$<=j.length;$++){const Ce=`image${$}`,sn=k[Ce];if(sn&&typeof sn=="object"){const ye=sn;O.push({source:ye.source||"",eventType:ye.type||"",epsg:ye.epsg||"",countries:Array.isArray(ye.countries)?ye.countries:[],centerLon:"",centerLat:"",amslM:"",aglM:"",headingDeg:"",yawDeg:"",pitchDeg:"",rollDeg:"",rtkFix:!1,stdHM:"",stdVM:""})}else O.push({source:"",eventType:"",epsg:"",countries:[],centerLon:"",centerLat:"",amslM:"",aglM:"",headingDeg:"",yawDeg:"",pitchDeg:"",rollDeg:"",rtkFix:!1,stdHM:"",stdVM:""})}else{const $={source:y.source||"",eventType:y.type||"",epsg:y.epsg||"",countries:Array.isArray(y.countries)?y.countries:[],centerLon:"",centerLat:"",amslM:"",aglM:"",headingDeg:"",yawDeg:"",pitchDeg:"",rollDeg:"",rtkFix:!1,stdHM:"",stdVM:""};for(let Ce=0;Ce<j.length;Ce++)O.push({...$})}}else{const k={source:y.source||"",eventType:y.type||"",epsg:y.epsg||"",countries:Array.isArray(y.countries)?y.countries:[],centerLon:"",centerLat:"",amslM:"",aglM:"",headingDeg:"",yawDeg:"",pitchDeg:"",rollDeg:"",rtkFix:!1,stdHM:"",stdVM:""};O.push(k)}if(Se(O),O.length>0){const k=O[0];if(y&&typeof y=="object"){const $=y.title;$&&se($||"")}z(k.source||""),G(k.eventType||""),Y(k.epsg||""),ae(k.countries||[]),R==="drone_image"&&(oe(k.centerLon||""),le(k.centerLat||""),de(k.amslM||""),ge(k.aglM||""),me(k.headingDeg||""),fe(k.yawDeg||""),P(k.pitchDeg||""),m(k.rollDeg||""),Fe(k.rtkFix||!1),Ae(k.stdHM||""),Oe(k.stdVM||""))}}}const T=g.raw_json?.metadata;T&&(T.description&&Ue(T.description),T.analysis&&We(T.analysis),T.recommended_actions&&He(T.recommended_actions)),g.generated&&pn(g.generated),De("2a")}async function Dt(){if(console.log("handleSubmit called with:",{uploadedImageId:W,title:K,draft:qn}),!W)return alert("No image to submit");if(!ve){vn(!0);return}try{const n=Be.length>0?Be:[W];console.log("DEBUG: Submit - Using image IDs:",n),console.log("DEBUG: Submit - uploadedImageIds:",Be),console.log("DEBUG: Submit - uploadedImageId:",W);for(let v=0;v<n.length;v++){const T=n[v],y=$e[v]||{source:A||"OTHER",eventType:L||"OTHER",epsg:q||"OTHER",countries:Z||[]},O={source:R==="drone_image"?void 0:y.source||"OTHER",event_type:y.eventType||"OTHER",epsg:y.epsg||"OTHER",image_type:R,countries:y.countries||[]};console.log(`Updating metadata for image ${v+1}:`,O);const k=await fetch(`/api/images/${T}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(O)}),$=await we(k);if(!k.ok)throw new Error($.error||`Metadata update failed for image ${v+1}`)}const f=`Description: ${mn}
|
| 14 |
+
|
| 15 |
+
Analysis: ${hn}
|
| 16 |
+
|
| 17 |
+
Recommended Actions: ${fn}`,u={title:K,edited:f,accuracy:ke.accuracy,context:ke.context,usability:ke.usability};console.log("Updating caption:",u);const g=await fetch(`/api/images/${W}/caption`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),r=await we(g);if(!g.ok)throw new Error(r.error||"Caption update failed");be(null),X([]),De(3)}catch(n){an(n,"Submit")}}async function In(){if(console.log("handleDelete called with uploadedImageId:",W),!W){alert("No image to delete. Please try refreshing the page.");return}qe(!0)}async function Et(){try{console.log("Deleting image with ID:",W);const n=await fetch(`/api/images/${W}`,{method:"DELETE"});if(!n.ok){const f=await we(n);throw new Error(f.error||`Delete failed with status ${n.status}`)}qe(!1),Mn()}catch(n){an(n,"Delete")}}const Mn=()=>{Ie(!1),p(1),E(null),F([]),b(null),be(null),X([]),gn(null),se(""),z(""),G(""),Y(""),ae([]),oe(""),le(""),de(""),ge(""),me(""),fe(""),P(""),m(""),Fe(!1),Ae(""),Oe(""),xn({accuracy:50,context:50,usability:50}),pn(""),Ue(""),We(""),He(""),Se([]),Ke(!1),_n(null),Je(!1),jn(null),ee(!1),ne(null),_e(!1),H(""),Le(!1),Xe(null),je(!1),en(null),s("/upload",{replace:!0})},Ee=a.useCallback(n=>{n==="/upload"||n==="/"||(x.current?(Ze(n),Me(!0)):s(n))},[s]);async function Pt(){if(Ye&&x.current)try{await fetch(`/api/images/${x.current}`,{method:"DELETE"}),Me(!1),Ze(null),s(Ye)}catch(n){console.error("Failed to delete image before navigation:",n),Me(!1),Ze(null),s(Ye)}}const Ft=async()=>{if(Qe){_e(!0),H("Starting file conversion...");try{const n=new FormData;n.append("file",Qe),n.append("preprocess_only","true"),H("Converting file format...");const f=await fetch("/api/images/preprocess",{method:"POST",body:n});if(!f.ok)throw new Error("Preprocessing failed");const u=await f.json();H("Finalizing conversion...");const g=atob(u.processed_content),r=new Uint8Array(g.length);for(let y=0;y<g.length;y++)r[y]=g.charCodeAt(y);const v=new File([r],u.processed_filename,{type:u.processed_mime_type}),T=URL.createObjectURL(v);j.length===0?(E(v),F([v])):F(y=>[...y,v]),b(T),H("Conversion complete!"),setTimeout(()=>{ee(!1),ne(null),_e(!1),H("")},1e3)}catch(n){console.error("Preprocessing error:",n),H("Conversion failed. Please try again."),setTimeout(()=>{ee(!1),ne(null),_e(!1),H("")},2e3)}}},Rt=()=>{ee(!1),ne(null),_e(!1),H("")},At=async n=>{C(!0);try{const f=n.map(async v=>{const T=await fetch(`/api/images/${v}`);if(!T.ok)throw new Error(`Failed to fetch image ${v}`);const y=await T.json(),O=await fetch(`/api/images/${v}/file`);if(!O.ok)throw new Error(`Failed to fetch image file ${v}`);const k=await O.blob(),$=y.file_key.split("/").pop()||`contributed_${v}.png`;return{file:new File([k],$,{type:k.type}),imageData:y}}),u=await Promise.all(f),g=u.map(v=>v.file),r=u[0]?.imageData;F(g),X(n),n.length===1&&be(n[0]),g.length>=1&&E(g[0]),r?.image_type&&Q(r.image_type)}catch(f){console.error("Failed to fetch contributed images:",f),alert(`Failed to load contributed images: ${f instanceof Error?f.message:"Unknown error"}`)}finally{C(!1)}};return a.useEffect(()=>{Promise.all([fetch("/api/sources").then(n=>n.json()),fetch("/api/types").then(n=>n.json()),fetch("/api/spatial-references").then(n=>n.json()),fetch("/api/image-types").then(n=>n.json()),fetch("/api/countries").then(n=>n.json()),fetch("/api/models").then(n=>n.json())]).then(([n,f,u,g,r,v])=>{!localStorage.getItem(Pe)&&v?.length&&localStorage.setItem(Pe,v[0].m_code),zn(n),$n(f),Un(u),Hn(g),Gn(r),n.length>0&&z(n[0].s_code),G("OTHER"),Y("OTHER"),g.length>0&&!i.get("imageType")&&!R&&Q(g[0].image_type)})},[i,R]),a.useEffect(()=>(window.confirmNavigationIfNeeded=n=>{Ee(n)},()=>{delete window.confirmNavigationIfNeeded}),[Ee]),a.useEffect(()=>{const n=g=>{if(x.current){const r="You have an uploaded image that will be deleted if you leave this page. Are you sure you want to leave?";return g.preventDefault(),g.returnValue=r,r}},f=()=>{x.current&&fetch(`/api/images/${x.current}`,{method:"DELETE"}).catch(console.error)},u=g=>{const r=g.target,v=r.closest("a[href]")||r.closest("[data-navigate]");if(v&&x.current){const T=v.getAttribute("href")||v.getAttribute("data-navigate");T&&T!=="#"&&!T.startsWith("javascript:")&&!T.startsWith("mailto:")&&(g.preventDefault(),g.stopPropagation(),Ee(T))}};return window.addEventListener("beforeunload",n),document.addEventListener("click",u,!0),()=>{window.removeEventListener("beforeunload",n),document.removeEventListener("click",u,!0),f()}},[Ee]),a.useEffect(()=>{if(!M){b(null);return}const n=URL.createObjectURL(M);return b(n),()=>URL.revokeObjectURL(n)},[M]),a.useEffect(()=>{const n=i.get("contribute"),f=i.get("imageIds");if(n==="true"&&f){const u=f.split(",").filter(g=>g.trim());u.length>0&&At(u)}},[i]),a.useEffect(()=>{o==="2b"&&Te(0)},[o]),e.jsxs(ln,{children:[o!==3&&e.jsx("div",{className:"max-w-7xl mx-auto",children:e.jsxs("div",{className:t.uploadContainer,"data-step":o,children:[o===1&&!i.get("step")&&!_&&e.jsx(Dn,{files:j,file:M,preview:l,imageType:R,onFileChange:tn,onRemoveImage:Cn,onAddImage:wn,onImageTypeChange:nn,onChangeFile:bn}),o===1&&i.get("contribute")==="true"&&!_&&j.length>0&&e.jsx(Dn,{files:j,file:M,preview:l,imageType:R,onFileChange:tn,onRemoveImage:Cn,onAddImage:wn,onImageTypeChange:nn,onChangeFile:bn}),c&&e.jsxs("div",{className:t.loadingContainer,children:[e.jsx(rn,{className:"text-ifrcRed"}),e.jsx("p",{className:t.loadingText,children:"Generating..."})]}),_&&e.jsxs("div",{className:t.loadingContainer,children:[e.jsx(rn,{className:"text-ifrcRed"}),e.jsx("p",{className:t.loadingText,children:"Loading contribution..."})]}),(o===1&&!c&&!_||o===1&&i.get("contribute")==="true"&&!c&&!_&&j.length>0)&&e.jsx("div",{className:t.generateButtonContainer,children:Ne?e.jsx(w,{name:"generate-from-url",onClick:Nn,children:"Generate Caption"}):e.jsx(w,{name:"generate",disabled:j.length===0,onClick:Nn,children:"Generate"})}),o==="2a"&&e.jsxs("div",{className:t.step2Layout,children:[e.jsx("div",{className:t.mapColumn,children:e.jsx(En,{files:j,imageUrl:Ne,preview:l,onViewFullSize:n=>{Ge(n||null),Ve(!0)}})}),e.jsx("div",{className:t.contentColumn,children:e.jsxs("div",{className:t.metadataSectionCard,children:[e.jsx(Ns,{files:j,imageType:R,title:K,source:A,eventType:L,epsg:q,countries:Z,centerLon:ie,centerLat:re,amslM:ce,aglM:ue,headingDeg:pe,yawDeg:he,pitchDeg:xe,rollDeg:N,rtkFix:h,stdHM:Re,stdVM:ze,metadataArray:$e,sources:An,types:On,spatialReferences:Bn,imageTypes:Wn,countriesOptions:Vn,onTitleChange:n=>se(n||""),onSourceChange:ut,onEventTypeChange:gt,onEpsgChange:pt,onCountriesChange:mt,onCenterLonChange:ht,onCenterLatChange:ft,onAmslMChange:xt,onAglMChange:vt,onHeadingDegChange:_t,onYawDegChange:jt,onPitchDegChange:wt,onRollDegChange:Ct,onRtkFixChange:yt,onStdHMChange:St,onStdVMChange:bt,onImageTypeChange:nn,updateMetadataForImage:Mt}),e.jsxs("div",{className:t.confirmSection,children:[e.jsx(cn,{name:"delete",variant:"tertiary",onClick:In,title:"Delete",ariaLabel:"Delete uploaded image",children:e.jsx(dn,{})}),e.jsx(w,{name:"confirm-metadata",onClick:()=>De("2b"),children:"Next"})]})]})})]}),o==="2b"&&e.jsxs("div",{className:t.step2bLayout,children:[e.jsxs("div",{className:`${t.topRow} ${ve?t.ratingHidden:""}`,children:[e.jsx("div",{className:t.imageSection,children:e.jsx(En,{files:j,imageUrl:Ne,preview:l,onViewFullSize:n=>{Ge(n||null),Ve(!0)},currentImageIndex:dt,onGoToPrevious:Nt,onGoToNext:kt,onGoToImage:It,showCarousel:!0})}),!ve&&e.jsx("div",{className:t.metadataSectionCard,children:e.jsx(ks,{isPerformanceConfirmed:ve,scores:ke,onScoreChange:(n,f)=>xn(u=>({...u,[n]:f})),onConfirmRatings:()=>Ie(!0),onEditRatings:()=>Ie(!1)})})]}),e.jsx("div",{className:t.metadataSectionCard,children:e.jsx(Is,{description:mn,analysis:hn,recommendedActions:fn,onDescriptionChange:n=>Ue(n||""),onAnalysisChange:n=>We(n||""),onRecommendedActionsChange:n=>He(n||""),onBack:()=>De("2a"),onDelete:In,onSubmit:Dt,onEditRatings:()=>Ie(!1),isPerformanceConfirmed:ve})})]})]})}),o===3&&e.jsxs("div",{className:t.successContainer,children:[e.jsx(te,{level:2,className:t.successHeading,children:"Saved!"}),e.jsx("p",{className:t.successText,children:i.get("contribute")==="true"?"Your contribution has been successfully saved.":"Your caption has been successfully saved."}),e.jsx("div",{className:t.successButton,children:e.jsx(w,{name:"upload-another",onClick:()=>{Mn()},children:"Upload Another"})})]}),e.jsx(Ms,{isOpen:Yn,imageUrl:Ne,preview:l,selectedImageData:Zn,onClose:()=>{Ve(!1),Ge(null)}}),e.jsx(Ls,{isOpen:Kn,onClose:()=>vn(!1)}),e.jsx(Ts,{isOpen:Jn,onConfirm:Et,onCancel:()=>qe(!1)}),e.jsx(Ds,{isOpen:Qn,onConfirm:Pt,onCancel:()=>Me(!1)}),e.jsx(Es,{isOpen:Xn,fallbackInfo:et,onClose:()=>Ke(!1)}),e.jsx(Ps,{isOpen:nt,preprocessingInfo:tt,onClose:()=>Je(!1)}),e.jsx(Fs,{isOpen:at,preprocessingFile:Qe,isPreprocessing:st,preprocessingProgress:it,onConfirm:Ft,onCancel:Rt}),e.jsx(Rs,{isOpen:ot,unsupportedFile:rt,onClose:()=>Le(!1)}),e.jsx(As,{isOpen:lt,oversizedFile:ct,onClose:()=>je(!1),onCancel:()=>je(!1)})]})}const zs="_helpContainer_1wavj_1",Os="_helpSection_1wavj_13",$s="_sectionHeader_1wavj_49",Bs="_sectionTitle_1wavj_91",Us="_sectionContent_1wavj_105",Ws="_guidelinesList_1wavj_119",Hs="_buttonContainer_1wavj_181",I={helpContainer:zs,helpSection:Os,sectionHeader:$s,sectionTitle:Bs,sectionContent:Us,guidelinesList:Ws,buttonContainer:Hs};function Vs(){const i=un(),{setShowReferenceExamples:s}=bs(),o=()=>{i("/upload")},p=()=>{s(!0),i("/explore")},c=()=>{i("/analytics?view=crisis_maps")};return e.jsx(ln,{className:"py-10",children:e.jsx("div",{className:I.helpContainer,children:e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:I.helpSection,children:[e.jsx("div",{className:I.sectionHeader,children:e.jsx(te,{level:3,className:I.sectionTitle,children:"Introduction"})}),e.jsx("div",{className:I.sectionContent,children:"In collaboration with the IFRC, PromptAid Vision is a tool that generates textual descriptions of crisis maps/crisis drone images utiliing Visual language models. This prototype is for collecting data for the fine-tuning of our own models. We aim to utilize AI tools to support national societies with rapid decision making during emergencies."}),e.jsx("div",{className:I.buttonContainer,children:e.jsx(w,{name:"upload-now",variant:"secondary",onClick:o,children:"Upload now β"})})]}),e.jsxs("div",{className:I.helpSection,children:[e.jsx("div",{className:I.sectionHeader,children:e.jsx(te,{level:3,className:I.sectionTitle,children:"Guidelines"})}),e.jsxs("div",{className:I.sectionContent,children:["To make the process smoother, please follow the guidelines below:",e.jsxs("ul",{className:I.guidelinesList,children:[e.jsx("li",{children:"Avoid uploading images that are not crisis maps/crisis drone images."}),e.jsx("li",{children:"Confirm the image details prior to modifying the description."}),e.jsx("li",{children:"Before the modification, please read the description generated and provide a rating via the rating sliders."}),e.jsx("li",{children:'Click the "Submit" button to save the description.'})]})]}),e.jsx("div",{className:I.buttonContainer,children:e.jsx(w,{name:"see-examples",variant:"secondary",onClick:p,children:"See examples β"})})]}),e.jsxs("div",{className:I.helpSection,children:[e.jsx("div",{className:I.sectionHeader,children:e.jsx(te,{level:3,className:I.sectionTitle,children:"VLMs"})}),e.jsx("div",{className:I.sectionContent,children:"PromptAid Vision uses a variety of Visual Language Models (VLMs). A random VLM is selected for each upload. Therefore feel free to delete and reupload. You can view performance details here:"}),e.jsx("div",{className:I.buttonContainer,children:e.jsx(w,{name:"view-vlm-details",variant:"secondary",onClick:c,children:"View VLM details β"})})]}),e.jsxs("div",{className:I.helpSection,children:[e.jsx("div",{className:I.sectionHeader,children:e.jsx(te,{level:3,className:I.sectionTitle,children:"Dataset"})}),e.jsx("div",{className:I.sectionContent,children:"All users are able to export the dataset. You could apply filters when exporting, and it have the option to organize based on model fine-tuning formats."}),e.jsx("div",{className:I.buttonContainer,children:e.jsx(w,{name:"export-dataset",variant:"secondary",onClick:()=>{s(!1),i("/explore"),setTimeout(()=>{const d=document.querySelector('[name="export-dataset"]');d&&d.click()},100)},children:"Export dataset β"})})]}),e.jsxs("div",{className:I.helpSection,children:[e.jsx("div",{className:I.sectionHeader,children:e.jsx(te,{level:3,className:I.sectionTitle,children:"Contact us"})}),e.jsx("div",{className:I.sectionContent,children:"Need help or have questions about PromptAid Vision? Our team is here to support you."}),e.jsx("div",{className:I.buttonContainer,children:e.jsx(w,{name:"contact-support",variant:"secondary",disabled:!0,children:"Get in touch β"})})]})]})})})}const Gs=a.createContext(void 0),qs=({children:i})=>{const[s,o]=a.useState(!1),[p,c]=a.useState(!0),d=async()=>{const x=localStorage.getItem("adminToken");if(!x){o(!1),c(!1);return}try{(await fetch("/api/admin/verify",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${x}`}})).ok?o(!0):(localStorage.removeItem("adminToken"),o(!1))}catch(l){console.error("Error verifying admin token:",l),localStorage.removeItem("adminToken"),o(!1)}finally{c(!1)}},_=async x=>{try{const l=await fetch("/api/admin/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:x})});if(l.ok){const b=await l.json();return localStorage.setItem("adminToken",b.access_token),o(!0),!0}else return!1}catch(l){return console.error("Login error:",l),!1}},C=()=>{localStorage.removeItem("adminToken"),o(!1)};a.useEffect(()=>{d()},[]);const S={isAuthenticated:s,isLoading:p,login:_,logout:C,verifyToken:d};return e.jsx(Gs.Provider,{value:S,children:i})},Ys=a.lazy(()=>B(()=>import("./index-DMU6q_dg.js"),__vite__mapDeps([0,1,2,3,4,5]))),Zs=a.lazy(()=>B(()=>import("./index-CwG_dxMe.js"),__vite__mapDeps([6,1,2,3,4,7,8,9,10]))),Ks=a.lazy(()=>B(()=>import("./AdminPage-Dz89QBtX.js"),__vite__mapDeps([11,1,2,7,3,4,12]))),Js=a.lazy(()=>B(()=>import("./index-jo0G9peP.js"),__vite__mapDeps([13,1,2,3,4,7,8,9,14])));class Qs extends a.Component{constructor(s){super(s),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(s,o){console.error("Error caught by boundary:",s,o)}render(){return this.state.hasError?e.jsxs("div",{style:{padding:"20px",textAlign:"center"},children:[e.jsx("h2",{children:"Something went wrong"}),e.jsx("p",{children:"Please refresh the page to try again."}),e.jsx("button",{onClick:()=>window.location.reload(),children:"Refresh Page"})]}):this.props.children}}const V=i=>{const s=i();return s.catch(()=>{}),s},Xs=()=>{"requestIdleCallback"in window?requestIdleCallback(()=>{V(()=>B(()=>import("./index-DMU6q_dg.js"),__vite__mapDeps([0,1,2,3,4,5]))),V(()=>B(()=>import("./index-CwG_dxMe.js"),__vite__mapDeps([6,1,2,3,4,7,8,9,10]))),V(()=>B(()=>import("./AdminPage-Dz89QBtX.js"),__vite__mapDeps([11,1,2,7,3,4,12]))),V(()=>B(()=>import("./index-jo0G9peP.js"),__vite__mapDeps([13,1,2,3,4,7,8,9,14])))}):setTimeout(()=>{V(()=>B(()=>import("./index-DMU6q_dg.js"),__vite__mapDeps([0,1,2,3,4,5]))),V(()=>B(()=>import("./index-CwG_dxMe.js"),__vite__mapDeps([6,1,2,3,4,7,8,9,10]))),V(()=>B(()=>import("./AdminPage-Dz89QBtX.js"),__vite__mapDeps([11,1,2,7,3,4,12]))),V(()=>B(()=>import("./index-jo0G9peP.js"),__vite__mapDeps([13,1,2,3,4,7,8,9,14])))},1e3)},ei=$t([{element:e.jsx(ga,{}),children:[{path:"/",element:e.jsx(Pn,{})},{path:"/upload",element:e.jsx(Pn,{})},{path:"/analytics",element:e.jsx(a.Suspense,{fallback:e.jsx("div",{children:"Loading Analytics..."}),children:e.jsx(Ys,{})})},{path:"/explore",element:e.jsx(a.Suspense,{fallback:e.jsx("div",{children:"Loading Explore..."}),children:e.jsx(Zs,{})})},{path:"/help",element:e.jsx(Vs,{})},{path:"/admin",element:e.jsx(a.Suspense,{fallback:e.jsx("div",{children:"Loading Admin..."}),children:e.jsx(Ks,{})})},{path:"/map/:mapId",element:e.jsx(a.Suspense,{fallback:e.jsx("div",{children:"Loading Map Details..."}),children:e.jsx(Js,{})})}]}],{basename:"/"});function ni(){const[i,s]=a.useState([]);a.useEffect(()=>{Xs()},[]);const o=a.useCallback(C=>{s(S=>sa([...S,C],x=>x.name)??S)},[s]),p=a.useCallback(C=>{s(S=>{const x=S.findIndex(b=>b.name===C);if(x===-1)return S;const l=[...S];return l.splice(x,1),l})},[s]),c=a.useCallback((C,S)=>{s(x=>{const l=x.findIndex(M=>M.name===C);if(l===-1)return x;const b=[...x];return b[l]={...b[l],...S},b})},[s]),d=a.useMemo(()=>({alerts:i,addAlert:o,removeAlert:p,updateAlert:c}),[i,o,p,c]),_=a.useMemo(()=>({languageNamespaceStatus:{},setLanguageNamespaceStatus:()=>{},currentLanguage:"en",setCurrentLanguage:()=>{},strings:{},setStrings:()=>{},registerNamespace:()=>{}}),[]);return e.jsx(Qs,{children:e.jsx(ea.Provider,{value:d,children:e.jsx(na.Provider,{value:_,children:e.jsx(qs,{children:e.jsx(Ss,{children:e.jsx(Bt,{router:ei})})})})})})}function ti(){return e.jsx(ni,{})}Ut.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(ti,{})}));export{Gs as A,Ms as F,B as _,bs as u};
|
py_backend/static/assets/index-jo0G9peP.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-utils-Db80MiSc.js","assets/vendor-DxpCibxB.js","assets/vendor-react-BxsGb6Ph.js"])))=>i.map(i=>d[i]);
|
| 2 |
+
import{u as Xe,F as Ye,_ as ea}from"./index-Uy48qW96.js";import{j as a,r as g}from"./vendor-react-BxsGb6Ph.js";import{N as X,n as T,_ as ve,L as aa,z as E,C as se,c as ie,D as ta}from"./vendor-ui-l_DttnRj.js";import{u as sa}from"./useAdmin-B_k2Fdj-.js";import{F as ia,E as na}from"./ExportModal-BtNOxnGZ.js";import{n as oa,a as ra}from"./vendor-DxpCibxB.js";const la="_tabSelector_usssr_1",ca="_imageContainer_usssr_12",da="_imagePlaceholder_usssr_33",ga="_metadataTags_usssr_45",ma="_metadataTag_usssr_45",ua="_captionContainer_usssr_67",pa="_captionText_usssr_74",fa="_gridLayout_usssr_131",ha="_detailsSection_usssr_155",_a="_loadingContainer_usssr_161",xa="_errorContainer_usssr_171",ya="_fullSizeModalOverlay_usssr_205",va="_fullSizeModalContent_usssr_219",wa="_ratingWarningContent_usssr_230",Ca="_ratingWarningTitle_usssr_236",ja="_ratingWarningText_usssr_243",Ia="_ratingWarningButtons_usssr_250",Na="_carouselContainer_usssr_365",ba="_carouselImageWrapper_usssr_370",Sa="_carouselImage_usssr_370",La="_carouselNavigation_usssr_393",Da="_carouselButton_usssr_405",ka="_carouselIndicators_usssr_429",Ma="_carouselIndicator_usssr_429",Ta="_carouselIndicatorActive_usssr_458",Fa="_singleImageContainer_usssr_488",Ea="_viewImageButtonContainer_usssr_494",p={tabSelector:la,imageContainer:ca,imagePlaceholder:da,metadataTags:ga,metadataTag:ma,captionContainer:ua,captionText:pa,gridLayout:fa,detailsSection:ha,loadingContainer:_a,errorContainer:xa,fullSizeModalOverlay:ya,fullSizeModalContent:va,ratingWarningContent:wa,ratingWarningTitle:Ca,ratingWarningText:ja,ratingWarningButtons:Ia,carouselContainer:Na,carouselImageWrapper:ba,carouselImage:Sa,carouselNavigation:La,carouselButton:Da,carouselIndicators:ka,carouselIndicator:Ma,carouselIndicatorActive:Ta,singleImageContainer:Fa,viewImageButtonContainer:Ea};function it(){const{mapId:u}=oa(),y=ra(),{isAuthenticated:ne}=sa();console.log("MapDetailsPage: Current URL:",window.location.href),console.log("MapDetailsPage: Hash:",window.location.hash),console.log("MapDetailsPage: mapId from useParams:",u),console.log("MapDetailsPage: mapId type:",typeof u),console.log("MapDetailsPage: mapId length:",u?.length),console.log("MapDetailsPage: mapId value:",JSON.stringify(u));const we=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;if(!u||u==="undefined"||u==="null"||u.trim()===""||!we.test(u))return a.jsx(X,{children:a.jsxs("div",{className:"flex flex-col items-center gap-4 text-center py-12",children:[a.jsx("div",{className:"text-4xl",children:"β οΈ"}),a.jsx("div",{className:"text-xl font-semibold",children:"Invalid Map ID"}),a.jsx("div",{children:"The map ID provided is not valid."}),a.jsxs("div",{className:"text-sm text-gray-500 mt-2",children:['Debug Info: mapId = "',u,'" (type: ',typeof u,")"]}),a.jsx(T,{name:"back-to-explore",variant:"secondary",onClick:()=>y("/explore"),children:"Return to Explore"})]})});const[oe,Ce]=g.useState("mapDetails"),[e,Y]=g.useState(null),[W,P]=g.useState(!0),[re,O]=g.useState(null),[le,je]=g.useState([]),[ce,Ie]=g.useState([]),[de,Ne]=g.useState([]),[ge,be]=g.useState([]),[Se,Le]=g.useState([]),[De,ke]=g.useState(!1),[Me,Te]=g.useState(!1),[B,q]=g.useState(!1),[Fe,G]=g.useState(!1),[me,Z]=g.useState(!1),[Ee,ee]=g.useState(!1),[Re,ae]=g.useState(!1),[Ra,$a]=g.useState("standard"),[R,Pa]=g.useState(80),[J,Aa]=g.useState(10),[za,Oa]=g.useState(10),[Ua,Wa]=g.useState(!0),[Ba,Ja]=g.useState(!0),[K,Q]=g.useState(!1),[$e,ue]=g.useState(!1),[Pe,pe]=g.useState(null),[D,H]=g.useState([]),[A,z]=g.useState(0),[V,fe]=g.useState(!1),{search:d,setSearch:Ha,srcFilter:v,setSrcFilter:Va,catFilter:w,setCatFilter:qa,regionFilter:C,setRegionFilter:Ga,countryFilter:j,setCountryFilter:Za,imageTypeFilter:I,setImageTypeFilter:Ka,uploadTypeFilter:N,setUploadTypeFilter:Qa,showReferenceExamples:k,setShowReferenceExamples:Ae,clearAllFilters:ze}=Xe(),Oe=[{key:"explore",label:"List"},{key:"mapDetails",label:"Carousel"}],he=g.useCallback(async t=>{if(console.log("fetchMapData called with id:",t),console.log("fetchMapData id type:",typeof t),!t||t==="undefined"||t==="null"||t.trim()===""){console.log("fetchMapData: Invalid ID detected:",t),O("Invalid Map ID"),P(!1);return}if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)){console.log("fetchMapData: Invalid UUID format:",t),O("Invalid Map ID format"),P(!1);return}console.log("fetchMapData: Making API call for id:",t),q(!0),P(!0);try{const f=await fetch(`/api/images/${t}`);if(!f.ok)throw new Error("Map not found");const s=await f.json();if(Y(s),s.all_image_ids&&s.all_image_ids.length>1)await _e(s.all_image_ids);else if(s.image_count&&s.image_count>1){console.log("Multi-upload detected but no all_image_ids, trying grouped endpoint");try{const l=await fetch("/api/images/grouped");if(l.ok){const r=(await l.json()).find(c=>c.all_image_ids&&c.all_image_ids.includes(s.image_id));r&&r.all_image_ids?await _e(r.all_image_ids):(H([s]),z(0))}else H([s]),z(0)}catch(l){console.error("Failed to fetch from grouped endpoint:",l),H([s]),z(0)}}else H([s]),z(0);await te(t)}catch(f){O(f instanceof Error?f.message:"Unknown error occurred")}finally{P(!1),q(!1)}},[]),_e=g.useCallback(async t=>{console.log("fetchAllImages called with imageIds:",t),fe(!0);try{const o=t.map(async s=>{const l=await fetch(`/api/images/${s}`);if(!l.ok)throw new Error(`Failed to fetch image ${s}`);return l.json()}),f=await Promise.all(o);H(f),z(0),console.log("fetchAllImages: Loaded",f.length,"images")}catch(o){console.error("fetchAllImages error:",o),O(o instanceof Error?o.message:"Failed to load all images")}finally{fe(!1)}},[]),Ue=g.useCallback(()=>{D.length>1&&z(t=>t>0?t-1:D.length-1)},[D.length]),We=g.useCallback(()=>{D.length>1&&z(t=>t<D.length-1?t+1:0)},[D.length]),Be=g.useCallback(t=>{t>=0&&t<D.length&&z(t)},[D.length]),xe=g.useCallback(t=>{const o=t||(D.length>0?D[A]:e);o&&(pe(o),ue(!0))},[D,A,e]),Je=g.useCallback(()=>{ue(!1),pe(null)},[]);g.useEffect(()=>{if(console.log("MapDetailsPage: mapId from useParams:",u),console.log("MapDetailsPage: mapId type:",typeof u),console.log("MapDetailsPage: mapId value:",u),!u||u==="undefined"||u==="null"||u.trim()===""||u===void 0||u===null){console.log("MapDetailsPage: Invalid mapId, setting error"),O("Map ID is required"),P(!1);return}if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(u)){console.log("MapDetailsPage: Invalid UUID format:",u),O("Invalid Map ID format"),P(!1);return}console.log("MapDetailsPage: Fetching data for mapId:",u),he(u)},[u,he]),g.useEffect(()=>{if(!e||W||K)return;if(!u||u==="undefined"||u==="null"||u.trim()===""){console.log("Auto-navigation skipped: Invalid mapId");return}if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(u)){console.log("Auto-navigation skipped: Invalid mapId format");return}(()=>{const f=!d||e.title?.toLowerCase().includes(d.toLowerCase())||e.generated?.toLowerCase().includes(d.toLowerCase())||e.source?.toLowerCase().includes(d.toLowerCase())||e.event_type?.toLowerCase().includes(d.toLowerCase()),s=!v||e.source===v,l=!w||e.event_type===w,i=!C||e.countries.some(M=>M.r_code===C),r=!j||e.countries.some(M=>M.c_code===j),c=!I||e.image_type===I,n=!k||e.starred===!0,x=f&&s&&l&&i&&r&&c&&n;return console.log("Auto-navigation check:",{mapId:u,search:d,srcFilter:v,catFilter:w,regionFilter:C,countryFilter:j,imageTypeFilter:I,showReferenceExamples:k,matchesSearch:f,matchesSource:s,matchesCategory:l,matchesRegion:i,matchesCountry:r,matchesImageType:c,matchesReferenceExamples:n,matches:x}),x})()||(console.log("Current map does not match filters, looking for first matching item"),fetch("/api/images").then(f=>f.json()).then(f=>{console.log("Auto-navigation: Received images from API:",f.length),console.log("Auto-navigation: First few images:",f.slice(0,3).map(l=>({image_id:l.image_id,title:l.title})));const s=f.find(l=>{const i=!d||l.title?.toLowerCase().includes(d.toLowerCase())||l.generated?.toLowerCase().includes(d.toLowerCase())||l.source?.toLowerCase().includes(d.toLowerCase())||l.event_type?.toLowerCase().includes(d.toLowerCase()),r=!v||l.source===v,c=!w||l.event_type===w,n=!C||l.countries?.some(m=>m.r_code===C),x=!j||l.countries?.some(m=>m.c_code===j),M=!I||l.image_type===I,S=!k||l.starred===!0;return i&&r&&c&&n&&x&&M&&S});console.log("Auto-navigation: Found first matching image:",s?{image_id:s.image_id,title:s.title,source:s.source}:"No matching image found"),s&&s.image_id&&s.image_id!=="undefined"&&s.image_id!=="null"&&s.image_id.trim()!==""&&s.image_id!==u&&(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s.image_id)?(console.log("Auto-navigating to:",s.image_id),y(`/map/${s.image_id}`)):console.error("Auto-navigation blocked: Invalid image_id format:",s.image_id))}).catch(console.error))},[e,d,v,w,C,j,I,k,u,y,W,K]);const te=async t=>{if(!(!t||t==="undefined"||t==="null"||t.trim()===""))try{const o=await fetch("/api/images/grouped");if(o.ok){const s=(await o.json()).filter(i=>{const r=!d||i.title?.toLowerCase().includes(d.toLowerCase())||i.generated?.toLowerCase().includes(d.toLowerCase())||i.source?.toLowerCase().includes(d.toLowerCase())||i.event_type?.toLowerCase().includes(d.toLowerCase()),c=!v||i.source===v,n=!w||i.event_type===w,x=!C||i.countries?.some(_=>_.r_code===C),M=!j||i.countries?.some(_=>_.c_code===j),S=!I||i.image_type===I,m=!N||N==="single"&&(!i.image_count||i.image_count<=1)||N==="multiple"&&i.image_count&&i.image_count>1,b=!k||i.starred===!0;return r&&c&&n&&x&&M&&S&&m&&b}),l=s.findIndex(i=>i.image_id===t);ke(s.length>1&&l>0),Te(s.length>1&&l<s.length-1)}}catch(o){console.error("Failed to check navigation availability:",o)}},ye=async t=>{if(!B){q(!0);try{const o=await fetch("/api/images/grouped");if(o.ok){const f=await o.json(),s=f.filter(n=>{const x=!d||n.title?.toLowerCase().includes(d.toLowerCase())||n.generated?.toLowerCase().includes(d.toLowerCase())||n.source?.toLowerCase().includes(d.toLowerCase())||n.event_type?.toLowerCase().includes(d.toLowerCase()),M=!v||n.source===v,S=!w||n.event_type===w,m=!C||n.countries?.some($=>$.r_code===C),b=!j||n.countries?.some($=>$.c_code===j),_=!I||n.image_type===I,L=!N||N==="single"&&(!n.image_count||n.image_count<=1)||N==="multiple"&&n.image_count&&n.image_count>1,U=!k||n.starred===!0;return x&&M&&S&&m&&b&&_&&L&&U});if(s.findIndex(n=>n.image_id===u)===-1){const n=f.find(x=>x.image_id===u);n&&s.push(n)}const i=s.findIndex(n=>n.image_id===u);if(i===-1){console.error("Current image not found in filtered list");return}let r;t==="previous"?r=i>0?i-1:s.length-1:r=i<s.length-1?i+1:0;const c=s[r];c&&c.image_id&&c.image_id!=="undefined"&&c.image_id!=="null"&&c.image_id.trim()!==""&&(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(c.image_id)?(console.log("Carousel navigating to:",c.image_id),y(`/map/${c.image_id}`)):console.error("Carousel navigation blocked: Invalid image_id format:",c.image_id))}}catch(o){console.error("Failed to navigate to item:",o)}finally{q(!1)}}};g.useEffect(()=>{e&&u&&!W&&!K&&te(u)},[e,u,d,v,w,C,j,I,N,k,W,K,te]),g.useEffect(()=>{Promise.all([fetch("/api/sources").then(t=>t.json()),fetch("/api/types").then(t=>t.json()),fetch("/api/image-types").then(t=>t.json()),fetch("/api/regions").then(t=>t.json()),fetch("/api/countries").then(t=>t.json())]).then(([t,o,f,s,l])=>{je(t),Ie(o),Ne(f),be(s),Le(l)}).catch(console.error)},[]);const He=async()=>{e&&G(!0)},Ve=async()=>{if(e)try{(await fetch(`/api/images/${e.image_id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({starred:!e.starred})})).ok?Y(o=>o?{...o,starred:!o.starred}:null):console.error("Failed to toggle starred status")}catch(t){console.error("Error toggling starred status:",t)}},qe=async()=>{if(e){Q(!0);try{if(console.log("Deleting image with ID:",e.image_id),(await fetch(`/api/images/${e.image_id}`,{method:"DELETE"})).ok){Y(o=>o?{...o,starred:!o.starred}:null),G(!1);try{const o=await fetch("/api/images/grouped");if(o.ok){const s=(await o.json()).filter(i=>{const r=!d||i.title?.toLowerCase().includes(d.toLowerCase())||i.generated?.toLowerCase().includes(d.toLowerCase())||i.source?.toLowerCase().includes(d.toLowerCase())||i.event_type?.toLowerCase().includes(d.toLowerCase()),c=!v||i.source===v,n=!w||i.event_type===w,x=!C||i.countries?.some(_=>_.r_code===C),M=!j||i.countries?.some(_=>_.c_code===j),S=!I||i.image_type===I,m=!N||N==="single"&&(!i.image_count||i.image_count<=1)||N==="multiple"&&i.image_count&&i.image_count>1,b=!k||i.starred===!0;return r&&c&&n&&x&&M&&S&&m&&b}),l=s.filter(i=>i.image_id!==e.image_id);if(l.length>0){const i=s.findIndex(c=>c.image_id===e.image_id);let r;if(i===s.length-1?r=i-1:r=i,console.log("Navigation target:",{currentIndex:i,targetIndex:r,targetId:l[r]?.image_id}),r>=0&&r<l.length){const c=l[r];c&&c.image_id&&c.image_id!=="undefined"&&c.image_id!=="null"&&c.image_id.trim()!==""?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(c.image_id)?(console.log("Navigating to:",c.image_id),y(`/map/${c.image_id}`)):(console.error("Navigation blocked: Invalid image_id format:",c.image_id),y("/explore")):(console.error("Navigation blocked: Invalid image_id:",c?.image_id),y("/explore"))}else l[0]&&l[0].image_id&&l[0].image_id!=="undefined"&&l[0].image_id!=="null"&&l[0].image_id.trim()!==""?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(l[0].image_id)?(console.log("Fallback navigation to first item:",l[0].image_id),y(`/map/${l[0].image_id}`)):(console.error("Fallback navigation blocked: Invalid image_id format:",l[0].image_id),y("/explore")):(console.log("No valid remaining items, going to explore page"),y("/explore"))}else console.log("No remaining items, going to explore page"),y("/explore")}else y("/explore")}catch(o){console.error("Failed to navigate to next item:",o),y("/explore")}finally{Q(!1)}}else console.error("Delete failed"),Q(!1)}catch(t){console.error("Delete failed:",t),Q(!1)}}},h=g.useMemo(()=>{if(!e)return null;if(!d&&!v&&!w&&!C&&!j&&!I&&!N&&!k)return e;const t=!d||e.title?.toLowerCase().includes(d.toLowerCase())||e.generated?.toLowerCase().includes(d.toLowerCase())||e.source?.toLowerCase().includes(d.toLowerCase())||e.event_type?.toLowerCase().includes(d.toLowerCase()),o=!v||e.source===v,f=!w||e.event_type===w,s=!C||e.countries.some(x=>x.r_code===C),l=!j||e.countries.some(x=>x.c_code===j),i=!I||e.image_type===I,r=!N||N==="single"&&(!e.image_count||e.image_count<=1)||N==="multiple"&&e.image_count&&e.image_count>1,c=!k||e.starred===!0,n=t&&o&&f&&s&&l&&i&&r&&c;return!n&&(d||v||w||C||j||I||N||k)?(setTimeout(()=>{Ge()},100),e):n?e:null},[e,d,v,w,C,j,I,N,k]),Ge=g.useCallback(async()=>{P(!0);try{const t=await fetch("/api/images/grouped");if(t.ok){const f=(await t.json()).filter(s=>{const l=!d||s.title?.toLowerCase().includes(d.toLowerCase())||s.generated?.toLowerCase().includes(d.toLowerCase())||s.source?.toLowerCase().includes(d.toLowerCase())||s.event_type?.toLowerCase().includes(d.toLowerCase()),i=!v||s.source===v,r=!w||s.event_type===w,c=!C||s.countries?.some(m=>m.r_code===C),n=!j||s.countries?.some(m=>m.c_code===j),x=!I||s.image_type===I,M=!N||N==="single"&&(!s.image_count||s.image_count<=1)||N==="multiple"&&s.image_count&&s.image_count>1,S=!k||s.starred===!0;return l&&i&&r&&c&&n&&x&&M&&S});if(f.length>0){const s=f[0];s&&s.image_id&&y(`/map/${s.image_id}`)}else y("/explore")}}catch(t){console.error("Failed to navigate to matching image:",t),y("/explore")}finally{P(!1)}},[d,v,w,C,j,I,N,k,y]),Ze=()=>{if(!e)return;if(!e.all_image_ids||e.all_image_ids.length<=1){const s=`/upload?step=1&contribute=true&imageIds=${[e.image_id].join(",")}`;y(s);return}const o=`/upload?step=1&contribute=true&imageIds=${e.all_image_ids.join(",")}`;y(o)},F=(t,o)=>({image:`images/${o}`,caption:t.edited||t.generated||"",metadata:{image_id:t.image_count&&t.image_count>1?t.all_image_ids||[t.image_id]:t.image_id,title:t.title,source:t.source,event_type:t.event_type,image_type:t.image_type,countries:t.countries,starred:t.starred,image_count:t.image_count||1}}),Ke=async t=>{if(e){ee(!0),ae(!1);try{const o=(await ea(async()=>{const{default:r}=await import("./vendor-utils-Db80MiSc.js").then(c=>c.j);return{default:r}},__vite__mapDeps([0,1,2]))).default,f=new o;if(e.image_type==="crisis_map"){const r=f.folder("crisis_maps_dataset"),c=r?.folder("images");if(c)try{const n=e.image_count&&e.image_count>1?e.all_image_ids||[e.image_id]:[e.image_id],x=n.map(async(m,b)=>{try{const _=await fetch(`/api/images/${m}/file`);if(!_.ok)throw new Error(`Failed to fetch image ${m}`);const L=await _.blob(),U=e.file_key.split(".").pop()||"jpg",$=`0001_${String(b+1).padStart(2,"0")}.${U}`;return c.file($,L),{success:!0,fileName:$,imageId:m}}catch(_){return console.error(`Failed to process image ${m}:`,_),{success:!1,fileName:"",imageId:m}}}),S=(await Promise.all(x)).filter(m=>m.success);if(S.length===0)throw new Error("No images could be processed");if(t==="fine-tuning"){const m=[],b=[],_=[],L=S.map(Qe=>`images/${Qe.fileName}`),U=Math.random(),$={image:L.length===1?L[0]:L,caption:e.edited||e.generated||"",metadata:{image_id:n,title:e.title,source:e.source,event_type:e.event_type,image_type:e.image_type,countries:e.countries,starred:e.starred,image_count:e.image_count||1}};U<R/100?m.push($):U<(R+J)/100?b.push($):_.push($),r&&(r.file("train.jsonl",JSON.stringify(m,null,2)),r.file("test.jsonl",JSON.stringify(b,null,2)),r.file("val.jsonl",JSON.stringify(_,null,2)))}else{const m=S.map(_=>`images/${_.fileName}`),b={image:m.length===1?m[0]:m,caption:e.edited||e.generated||"",metadata:{image_id:n,title:e.title,source:e.source,event_type:e.event_type,image_type:e.image_type,countries:e.countries,starred:e.starred,image_count:e.image_count||1}};r&&r.file("0001.json",JSON.stringify(b,null,2))}}catch(n){throw console.error(`Failed to process image ${e.image_id}:`,n),n}}else if(e.image_type==="drone_image"){const r=f.folder("drone_images_dataset"),c=r?.folder("images");if(c)try{const n=await fetch(`/api/images/${e.image_id}/file`);if(!n.ok)throw new Error(`Failed to fetch image ${e.image_id}`);const x=await n.blob(),S=`0001.${e.file_key.split(".").pop()||"jpg"}`;if(c.file(S,x),t==="fine-tuning"){const m=[],b=[],_=[];if(String(e?.image_type)==="crisis_map"){const L=Math.random();L<R/100?m.push(F(e,"0001")):L<(R+J)/100?b.push(F(e,"0001")):_.push(F(e,"0001"))}else if(String(e?.image_type)==="drone_image"){const L=Math.random();L<R/100?m.push(F(e,"0001")):L<(R+J)/100?b.push(F(e,"0001")):_.push(F(e,"0001"))}r&&(r.file("train.jsonl",JSON.stringify(m,null,2)),r.file("test.jsonl",JSON.stringify(b,null,2)),r.file("val.jsonl",JSON.stringify(_,null,2)))}else{const m={image:`images/${S}`,caption:e.edited||e.generated||"",metadata:{image_id:e.image_count&&e.image_count>1?e.all_image_ids||[e.image_id]:e.image_id,title:e.title,source:e.source,event_type:e.event_type,image_type:e.image_type,countries:e.countries,starred:e.starred,image_count:e.image_count||1}};r&&r.file("0001.json",JSON.stringify(m,null,2))}}catch(n){throw console.error(`Failed to process image ${e.image_id}:`,n),n}}else{const r=f.folder("generic_dataset"),c=r?.folder("images");if(c)try{const n=await fetch(`/api/images/${e.image_id}/file`);if(!n.ok)throw new Error(`Failed to fetch image ${e.image_id}`);const x=await n.blob(),S=`0001.${e.file_key.split(".").pop()||"jpg"}`;if(c.file(S,x),t==="fine-tuning"){const m=[],b=[],_=[];if(String(e?.image_type)==="crisis_map"){const L=Math.random();L<R/100?m.push(F(e,"0001")):L<(R+J)/100?b.push(F(e,"0001")):_.push(F(e,"0001"))}else if(String(e?.image_type)==="drone_image"){const L=Math.random();L<R/100?m.push(F(e,"0001")):L<(R+J)/100?b.push(F(e,"0001")):_.push(F(e,"0001"))}r&&(r.file("train.jsonl",JSON.stringify(m,null,2)),r.file("test.jsonl",JSON.stringify(b,null,2)),r.file("val.jsonl",JSON.stringify(_,null,2)))}else{const m={image:`images/${S}`,caption:e.edited||e.generated||"",metadata:{image_id:e.image_count&&e.image_count>1?e.all_image_ids||[e.image_id]:e.image_id,title:e.title,source:e.source,event_type:e.event_type,image_type:e.image_type,countries:e.countries,starred:e.starred,image_count:e.image_count||1}};r&&r.file("0001.json",JSON.stringify(m,null,2))}}catch(n){throw console.error(`Failed to process image ${e.image_id}:`,n),n}}const s=await f.generateAsync({type:"blob"}),l=URL.createObjectURL(s),i=document.createElement("a");i.href=l,i.download=`dataset_${e.image_type}_${e.image_id}_${t}_${new Date().toISOString().split("T")[0]}.zip`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(l),console.log(`Exported ${e.image_type} dataset with 1 image in ${t} mode`),ae(!0)}catch(o){console.error("Export failed:",o),alert("Failed to export dataset. Please try again.")}finally{ee(!1)}}};return W?a.jsx(X,{children:a.jsx("div",{className:p.loadingContainer,children:a.jsxs("div",{className:"flex flex-col items-center gap-4",children:[a.jsx(ve,{className:"text-ifrcRed"}),a.jsx("div",{children:"Loading map details..."})]})})}):re||!e?a.jsx(X,{children:a.jsx("div",{className:p.errorContainer,children:a.jsxs("div",{className:"flex flex-col items-center gap-4 text-center",children:[a.jsx("div",{className:"text-4xl",children:"β οΈ"}),a.jsx("div",{className:"text-xl font-semibold",children:"Unable to load map"}),a.jsx("div",{children:re||"Map not found"}),a.jsx(T,{name:"back-to-explore",variant:"secondary",onClick:()=>y("/explore"),children:"Return to Explore"})]})})}):a.jsxs(X,{children:[a.jsxs("div",{className:"max-w-7xl mx-auto",children:[a.jsxs("div",{className:p.tabSelector,children:[a.jsx(aa,{name:"map-details-view",value:oe,onChange:t=>{(t==="mapDetails"||t==="explore")&&(Ce(t),t==="explore"&&y("/explore"))},options:Oe,keySelector:t=>t.key,labelSelector:t=>t.label}),a.jsxs("div",{className:"flex items-center gap-2 ml-auto",children:[a.jsx(E,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2",children:a.jsxs(T,{name:"reference-examples",variant:k?"primary":"secondary",onClick:()=>Ae(!k),className:"whitespace-nowrap",children:[a.jsx("span",{className:"mr-2",children:k?a.jsx("span",{className:"text-yellow-400",children:"β
"}):a.jsx("span",{className:"text-yellow-400",children:"β"})}),"Reference Examples"]})}),a.jsx(T,{name:"export-dataset",variant:"secondary",onClick:()=>Z(!0),children:"Export"})]})]}),a.jsx(ia,{sources:le,types:ce,regions:ge,countries:Se,imageTypes:de,isLoadingFilters:!1}),oe==="mapDetails"?a.jsx("div",{className:"relative",children:h?a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:p.gridLayout,children:[a.jsxs(E,{heading:a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{children:h.title||"Map Image"}),h.starred&&a.jsx("span",{className:"text-red-500 text-xl",title:"Starred image",children:"β
"})]}),headingLevel:2,withHeaderBorder:!0,withInternalPadding:!0,spacing:"comfortable",children:[a.jsx("div",{className:p.imageContainer,children:e?.image_count&&e.image_count>1||D.length>1?a.jsxs("div",{className:p.carouselContainer,children:[a.jsx("div",{className:p.carouselImageWrapper,children:V?a.jsxs("div",{className:p.imagePlaceholder,children:[a.jsx(ve,{className:"text-ifrcRed"}),a.jsx("div",{children:"Loading images..."})]}):D[A]?.image_url?a.jsx("img",{src:D[A].image_url,alt:D[A].file_key,className:p.carouselImage}):a.jsx("div",{className:p.imagePlaceholder,children:"No image available"})}),a.jsxs("div",{className:p.carouselNavigation,children:[a.jsx(T,{name:"previous-image",variant:"tertiary",size:1,onClick:Ue,disabled:V,className:p.carouselButton,children:a.jsx(se,{className:"w-4 h-4"})}),a.jsx("div",{className:p.carouselIndicators,children:D.map((t,o)=>a.jsx("button",{onClick:()=>Be(o),className:`${p.carouselIndicator} ${o===A?p.carouselIndicatorActive:""}`,disabled:V,children:o+1},o))}),a.jsx(T,{name:"next-image",variant:"tertiary",size:1,onClick:We,disabled:V,className:p.carouselButton,children:a.jsx(ie,{className:"w-4 h-4"})})]}),a.jsx("div",{className:p.viewImageButtonContainer,children:a.jsx(T,{name:"view-full-size-carousel",variant:"secondary",size:1,onClick:()=>xe(D[A]),disabled:V||!D[A]?.image_url,children:"View Image"})})]}):a.jsxs("div",{className:p.singleImageContainer,children:[h.image_url?a.jsx("img",{src:h.image_url,alt:h.file_key}):a.jsx("div",{className:p.imagePlaceholder,children:"No image available"}),a.jsx("div",{className:p.viewImageButtonContainer,children:a.jsx(T,{name:"view-full-size-single",variant:"secondary",size:1,onClick:()=>xe(h),disabled:!h.image_url,children:"View Image"})})]})}),a.jsx(E,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-md p-2",children:a.jsxs("div",{className:p.metadataTags,children:[h.image_type!=="drone_image"&&a.jsx("span",{className:p.metadataTag,children:le.find(t=>t.s_code===h.source)?.label||h.source}),a.jsx("span",{className:p.metadataTag,children:ce.find(t=>t.t_code===h.event_type)?.label||h.event_type}),a.jsx("span",{className:p.metadataTag,children:de.find(t=>t.image_type===h.image_type)?.label||h.image_type}),h.countries&&h.countries.length>0&&a.jsxs(a.Fragment,{children:[a.jsx("span",{className:p.metadataTag,children:ge.find(t=>t.r_code===h.countries[0].r_code)?.label||"Unknown Region"}),a.jsx("span",{className:p.metadataTag,children:h.countries.map(t=>t.label).join(", ")})]}),h.image_count&&h.image_count>1&&a.jsxs("span",{className:p.metadataTag,title:`Multi-upload with ${h.image_count} images`,children:["π· ",h.image_count]}),(!h.image_count||h.image_count<=1)&&a.jsx("span",{className:p.metadataTag,title:"Single Upload",children:"Single"})]})})]}),a.jsx("div",{className:p.detailsSection,children:h.edited&&h.edited.includes("Description:")||h.generated&&h.generated.includes("Description:")?a.jsx(E,{heading:"AI Generated Content",headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,spacing:"comfortable",children:a.jsx("div",{className:p.captionContainer,children:a.jsx("div",{className:p.captionText,children:(h.edited||h.generated||"").split(`
|
| 3 |
+
`).map((t,o)=>a.jsx("div",{children:t.startsWith("Description:")||t.startsWith("Analysis:")||t.startsWith("Recommended Actions:")?a.jsx("h4",{className:"font-semibold text-gray-800 mt-4 mb-2",children:t}):t.trim()===""?a.jsx("br",{}):a.jsx("p",{className:"mb-2",children:t})},o))})})}):a.jsx(E,{heading:"Description",headingLevel:3,withHeaderBorder:!0,withInternalPadding:!0,spacing:"comfortable",children:a.jsx("div",{className:p.captionContainer,children:h.generated?a.jsx("div",{className:p.captionText,children:a.jsx("p",{children:h.edited||h.generated})}):a.jsx("p",{children:"β no caption yet β"})})})})]}),a.jsx("div",{className:"flex items-center justify-center mt-8",children:a.jsx(E,{withInternalPadding:!0,className:"bg-white/20 backdrop-blur-sm rounded-lg p-4",children:a.jsxs("div",{className:"flex items-center gap-4",children:[De&&a.jsx(E,{withInternalPadding:!0,className:"rounded-md p-2",children:a.jsx(T,{name:"previous-item",variant:"tertiary",size:1,className:`bg-white/90 hover:bg-white shadow-lg border border-gray-200 ${B?"opacity-50 cursor-not-allowed":"hover:scale-110"}`,onClick:()=>ye("previous"),disabled:B,children:a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsxs("div",{className:"flex -space-x-1",children:[a.jsx(se,{className:"w-4 h-4"}),a.jsx(se,{className:"w-4 h-4"})]}),a.jsx("span",{className:"font-semibold",children:"Previous"})]})})}),ne&&a.jsx(E,{withInternalPadding:!0,className:"rounded-md p-2",children:a.jsx(T,{name:"delete",variant:"tertiary",size:1,className:"bg-red-50 hover:bg-red-100 text-red-700 border border-red-200 hover:border-red-300",onClick:He,title:"Delete","aria-label":"Delete saved image",children:a.jsx(ta,{className:"w-4 h-4"})})}),a.jsx(E,{withInternalPadding:!0,className:"rounded-md p-2",children:a.jsx(T,{name:"contribute",onClick:Ze,children:"Contribute"})}),ne&&a.jsx(E,{withInternalPadding:!0,className:"rounded-md p-2",children:a.jsx(T,{name:"toggle-star",variant:"tertiary",size:1,className:`${e?.starred?"bg-red-100 hover:bg-red-200 text-red-800 border-2 border-red-400":"bg-gray-100 hover:bg-gray-200 text-gray-600 border-2 border-gray-300"} w-16 h-8 rounded-full transition-all duration-200 flex items-center justify-center`,onClick:Ve,title:e?.starred?"Unstar image":"Star image","aria-label":e?.starred?"Unstar image":"Star image",children:a.jsx("span",{className:`text-lg transition-all duration-200 ${e?.starred?"text-red-600":"text-gray-500"}`,children:e?.starred?"β
":"β"})})}),Me&&a.jsx(E,{withInternalPadding:!0,className:"rounded-md p-2",children:a.jsx(T,{name:"next-item",variant:"tertiary",size:1,className:`bg-white/90 hover:bg-white shadow-lg border border-gray-200 ${B?"opacity-50 cursor-not-allowed":"hover:scale-110"}`,onClick:()=>ye("next"),disabled:B,children:a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx("span",{className:"font-semibold",children:"Next"}),a.jsxs("div",{className:"flex -space-x-1",children:[a.jsx(ie,{className:"w-4 h-4"}),a.jsx(ie,{className:"w-4 h-4"})]})]})})})]})})})]}):a.jsxs("div",{className:"text-center py-12",children:[a.jsx("div",{className:"text-xl font-semibold text-gray-600 mb-4",children:"No matches found"}),a.jsx("div",{className:"mt-4",children:a.jsx(T,{name:"clear-filters",variant:"secondary",onClick:ze,children:"Clear Filters"})})]})}):null]}),Fe&&a.jsx("div",{className:p.fullSizeModalOverlay,onClick:()=>G(!1),children:a.jsx("div",{className:p.fullSizeModalContent,onClick:t=>t.stopPropagation(),children:a.jsxs("div",{className:p.ratingWarningContent,children:[a.jsx("h3",{className:p.ratingWarningTitle,children:"Delete Image?"}),a.jsx("p",{className:p.ratingWarningText,children:"This action cannot be undone. Are you sure you want to delete this saved image and all related data?"}),a.jsxs("div",{className:p.ratingWarningButtons,children:[a.jsx(T,{name:"confirm-delete",variant:"secondary",onClick:qe,children:"Delete"}),a.jsx(T,{name:"cancel-delete",variant:"tertiary",onClick:()=>G(!1),children:"Cancel"})]})]})})}),me&&a.jsx(na,{isOpen:me,onClose:()=>{Z(!1),ae(!1),ee(!1)},onExport:(t,o)=>{o.includes(e.image_type)&&Ke(t)},filteredCount:1,totalCount:1,hasFilters:!1,crisisMapsCount:e.image_type==="crisis_map"?1:0,droneImagesCount:e.image_type==="drone_image"?1:0,isLoading:Ee,exportSuccess:Re,variant:"single",onNavigateToList:()=>{Z(!1),y("/explore")},onNavigateAndExport:()=>{Z(!1),y("/explore?export=true")}}),a.jsx(Ye,{isOpen:$e,imageUrl:Pe?.image_url||null,preview:null,selectedImageData:null,onClose:Je})]})}export{it as default};
|
py_backend/static/assets/useAdmin-B_k2Fdj-.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
import{r}from"./vendor-react-BxsGb6Ph.js";import{A as o}from"./index-Uy48qW96.js";const i=()=>{const t=r.useContext(o);if(t===void 0)throw new Error("useAdmin must be used within an AdminProvider");return t};export{i as u};
|
py_backend/static/index.html
CHANGED
|
@@ -35,7 +35,7 @@
|
|
| 35 |
});
|
| 36 |
}
|
| 37 |
</script>
|
| 38 |
-
<script type="module" crossorigin src="/assets/index-
|
| 39 |
<link rel="modulepreload" crossorigin href="/assets/vendor-DxpCibxB.js">
|
| 40 |
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BxsGb6Ph.js">
|
| 41 |
<link rel="modulepreload" crossorigin href="/assets/vendor-ui-l_DttnRj.js">
|
|
|
|
| 35 |
});
|
| 36 |
}
|
| 37 |
</script>
|
| 38 |
+
<script type="module" crossorigin src="/assets/index-Uy48qW96.js"></script>
|
| 39 |
<link rel="modulepreload" crossorigin href="/assets/vendor-DxpCibxB.js">
|
| 40 |
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BxsGb6Ph.js">
|
| 41 |
<link rel="modulepreload" crossorigin href="/assets/vendor-ui-l_DttnRj.js">
|
py_backend/static/sw.js
CHANGED
|
@@ -40,8 +40,8 @@ self.addEventListener('fetch', (event) => {
|
|
| 40 |
const { request } = event;
|
| 41 |
const url = new URL(request.url);
|
| 42 |
|
| 43 |
-
// Skip non-GET requests
|
| 44 |
-
if (request.method !== 'GET') {
|
| 45 |
return;
|
| 46 |
}
|
| 47 |
|
|
|
|
| 40 |
const { request } = event;
|
| 41 |
const url = new URL(request.url);
|
| 42 |
|
| 43 |
+
// Skip non-GET requests and non-HTTP(S) requests
|
| 44 |
+
if (request.method !== 'GET' || (url.protocol !== 'http:' && url.protocol !== 'https:')) {
|
| 45 |
return;
|
| 46 |
}
|
| 47 |
|