Spaces:
Running
Running
image type filter bar
Browse files
docker-compose.yml
CHANGED
|
@@ -9,7 +9,7 @@ services:
|
|
| 9 |
POSTGRES_PASSWORD: promptaid
|
| 10 |
POSTGRES_DB: promptaid
|
| 11 |
ports:
|
| 12 |
-
- "5434:5432"
|
| 13 |
volumes:
|
| 14 |
- pgdata:/var/lib/postgresql/data
|
| 15 |
|
|
@@ -39,11 +39,7 @@ services:
|
|
| 39 |
- minio_data:/data
|
| 40 |
depends_on:
|
| 41 |
- postgres
|
| 42 |
-
|
| 43 |
-
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
| 44 |
-
interval: 30s
|
| 45 |
-
timeout: 20s
|
| 46 |
-
retries: 3
|
| 47 |
|
| 48 |
app:
|
| 49 |
build: .
|
|
@@ -55,10 +51,8 @@ services:
|
|
| 55 |
- DATABASE_URL=postgresql://promptaid:promptaid@postgres:5432/promptaid
|
| 56 |
- S3_ENDPOINT=http://minio:9000 # Override for container networking
|
| 57 |
depends_on:
|
| 58 |
-
postgres
|
| 59 |
-
|
| 60 |
-
minio:
|
| 61 |
-
condition: service_healthy
|
| 62 |
volumes:
|
| 63 |
- ./py_backend:/app
|
| 64 |
- /app/__pycache__
|
|
|
|
| 9 |
POSTGRES_PASSWORD: promptaid
|
| 10 |
POSTGRES_DB: promptaid
|
| 11 |
ports:
|
| 12 |
+
- "5434:5432"
|
| 13 |
volumes:
|
| 14 |
- pgdata:/var/lib/postgresql/data
|
| 15 |
|
|
|
|
| 39 |
- minio_data:/data
|
| 40 |
depends_on:
|
| 41 |
- postgres
|
| 42 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
app:
|
| 45 |
build: .
|
|
|
|
| 51 |
- DATABASE_URL=postgresql://promptaid:promptaid@postgres:5432/promptaid
|
| 52 |
- S3_ENDPOINT=http://minio:9000 # Override for container networking
|
| 53 |
depends_on:
|
| 54 |
+
- postgres
|
| 55 |
+
- minio
|
|
|
|
|
|
|
| 56 |
volumes:
|
| 57 |
- ./py_backend:/app
|
| 58 |
- /app/__pycache__
|
frontend/src/pages/ExplorePage/ExplorePage.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { PageContainer, TextInput, SelectInput, MultiSelectInput, Container, SegmentInput, Spinner } from '@ifrc-go/ui';
|
| 2 |
import { useState, useEffect, useMemo } from 'react';
|
| 3 |
import { useNavigate } from 'react-router-dom';
|
| 4 |
import styles from './ExplorePage.module.css';
|
|
@@ -36,6 +36,7 @@ export default function ExplorePage() {
|
|
| 36 |
const [catFilter, setCatFilter] = useState('');
|
| 37 |
const [regionFilter, setRegionFilter] = useState('');
|
| 38 |
const [countryFilter, setCountryFilter] = useState('');
|
|
|
|
| 39 |
const [sources, setSources] = useState<{s_code: string, label: string}[]>([]);
|
| 40 |
const [types, setTypes] = useState<{t_code: string, label: string}[]>([]);
|
| 41 |
const [regions, setRegions] = useState<{r_code: string, label: string}[]>([]);
|
|
@@ -145,10 +146,11 @@ export default function ExplorePage() {
|
|
| 145 |
c.countries.some(country => country.r_code === regionFilter);
|
| 146 |
const matchesCountry = !countryFilter ||
|
| 147 |
c.countries.some(country => country.c_code === countryFilter);
|
|
|
|
| 148 |
|
| 149 |
-
return matchesSearch && matchesSource && matchesCategory && matchesRegion && matchesCountry;
|
| 150 |
});
|
| 151 |
-
}, [captions, search, srcFilter, catFilter, regionFilter, countryFilter]);
|
| 152 |
|
| 153 |
|
| 154 |
return (
|
|
@@ -246,6 +248,20 @@ export default function ExplorePage() {
|
|
| 246 |
disabled={isLoadingFilters}
|
| 247 |
/>
|
| 248 |
</Container>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
</div>
|
| 250 |
</div>
|
| 251 |
|
|
@@ -255,6 +271,20 @@ export default function ExplorePage() {
|
|
| 255 |
<p className="text-sm text-gray-600">
|
| 256 |
{filtered.length} of {captions.length} examples
|
| 257 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
</div>
|
| 259 |
|
| 260 |
{/* Loading State */}
|
|
|
|
| 1 |
+
import { PageContainer, TextInput, SelectInput, MultiSelectInput, Container, SegmentInput, Spinner, Button } from '@ifrc-go/ui';
|
| 2 |
import { useState, useEffect, useMemo } from 'react';
|
| 3 |
import { useNavigate } from 'react-router-dom';
|
| 4 |
import styles from './ExplorePage.module.css';
|
|
|
|
| 36 |
const [catFilter, setCatFilter] = useState('');
|
| 37 |
const [regionFilter, setRegionFilter] = useState('');
|
| 38 |
const [countryFilter, setCountryFilter] = useState('');
|
| 39 |
+
const [imageTypeFilter, setImageTypeFilter] = useState('');
|
| 40 |
const [sources, setSources] = useState<{s_code: string, label: string}[]>([]);
|
| 41 |
const [types, setTypes] = useState<{t_code: string, label: string}[]>([]);
|
| 42 |
const [regions, setRegions] = useState<{r_code: string, label: string}[]>([]);
|
|
|
|
| 146 |
c.countries.some(country => country.r_code === regionFilter);
|
| 147 |
const matchesCountry = !countryFilter ||
|
| 148 |
c.countries.some(country => country.c_code === countryFilter);
|
| 149 |
+
const matchesImageType = !imageTypeFilter || c.image_type === imageTypeFilter;
|
| 150 |
|
| 151 |
+
return matchesSearch && matchesSource && matchesCategory && matchesRegion && matchesCountry && matchesImageType;
|
| 152 |
});
|
| 153 |
+
}, [captions, search, srcFilter, catFilter, regionFilter, countryFilter, imageTypeFilter]);
|
| 154 |
|
| 155 |
|
| 156 |
return (
|
|
|
|
| 248 |
disabled={isLoadingFilters}
|
| 249 |
/>
|
| 250 |
</Container>
|
| 251 |
+
|
| 252 |
+
<Container withInternalPadding className="bg-white/20 backdrop-blur-sm rounded-md p-2">
|
| 253 |
+
<SelectInput
|
| 254 |
+
name="imageType"
|
| 255 |
+
placeholder={isLoadingFilters ? "Loading..." : "All Image Types"}
|
| 256 |
+
options={imageTypes}
|
| 257 |
+
value={imageTypeFilter || null}
|
| 258 |
+
onChange={(v) => setImageTypeFilter(v as string || '')}
|
| 259 |
+
keySelector={(o) => o.image_type}
|
| 260 |
+
labelSelector={(o) => o.label}
|
| 261 |
+
required={false}
|
| 262 |
+
disabled={isLoadingFilters}
|
| 263 |
+
/>
|
| 264 |
+
</Container>
|
| 265 |
</div>
|
| 266 |
</div>
|
| 267 |
|
|
|
|
| 271 |
<p className="text-sm text-gray-600">
|
| 272 |
{filtered.length} of {captions.length} examples
|
| 273 |
</p>
|
| 274 |
+
<Button
|
| 275 |
+
name="clear-filters"
|
| 276 |
+
variant="secondary"
|
| 277 |
+
onClick={() => {
|
| 278 |
+
setSearch('');
|
| 279 |
+
setSrcFilter('');
|
| 280 |
+
setCatFilter('');
|
| 281 |
+
setRegionFilter('');
|
| 282 |
+
setCountryFilter('');
|
| 283 |
+
setImageTypeFilter('');
|
| 284 |
+
}}
|
| 285 |
+
>
|
| 286 |
+
Clear Filters
|
| 287 |
+
</Button>
|
| 288 |
</div>
|
| 289 |
|
| 290 |
{/* Loading State */}
|
frontend/src/pages/MapDetailsPage/MapDetailPage.tsx
CHANGED
|
@@ -55,6 +55,7 @@ export default function MapDetailPage() {
|
|
| 55 |
const [catFilter, setCatFilter] = useState('');
|
| 56 |
const [regionFilter, setRegionFilter] = useState('');
|
| 57 |
const [countryFilter, setCountryFilter] = useState('');
|
|
|
|
| 58 |
|
| 59 |
const viewOptions = [
|
| 60 |
{ key: 'explore' as const, label: 'Explore' },
|
|
@@ -164,9 +165,10 @@ export default function MapDetailPage() {
|
|
| 164 |
map.countries.some(country => country.r_code === regionFilter);
|
| 165 |
const matchesCountry = !countryFilter ||
|
| 166 |
map.countries.some(country => country.c_code === countryFilter);
|
|
|
|
| 167 |
|
| 168 |
-
return matchesSearch && matchesSource && matchesCategory && matchesRegion && matchesCountry ? map : null;
|
| 169 |
-
}, [map, search, srcFilter, catFilter, regionFilter, countryFilter]);
|
| 170 |
|
| 171 |
const handleContribute = async () => {
|
| 172 |
if (!map) return;
|
|
@@ -346,6 +348,19 @@ export default function MapDetailPage() {
|
|
| 346 |
labelSelector={(o) => o.label}
|
| 347 |
/>
|
| 348 |
</Container>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
</div>
|
| 350 |
</div>
|
| 351 |
|
|
@@ -461,7 +476,14 @@ export default function MapDetailPage() {
|
|
| 461 |
onClick={handleContribute}
|
| 462 |
disabled={isGenerating}
|
| 463 |
>
|
| 464 |
-
{isGenerating ?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 465 |
</Button>
|
| 466 |
</Container>
|
| 467 |
|
|
@@ -506,6 +528,7 @@ export default function MapDetailPage() {
|
|
| 506 |
setCatFilter('');
|
| 507 |
setRegionFilter('');
|
| 508 |
setCountryFilter('');
|
|
|
|
| 509 |
}}
|
| 510 |
>
|
| 511 |
Clear Filters
|
|
|
|
| 55 |
const [catFilter, setCatFilter] = useState('');
|
| 56 |
const [regionFilter, setRegionFilter] = useState('');
|
| 57 |
const [countryFilter, setCountryFilter] = useState('');
|
| 58 |
+
const [imageTypeFilter, setImageTypeFilter] = useState('');
|
| 59 |
|
| 60 |
const viewOptions = [
|
| 61 |
{ key: 'explore' as const, label: 'Explore' },
|
|
|
|
| 165 |
map.countries.some(country => country.r_code === regionFilter);
|
| 166 |
const matchesCountry = !countryFilter ||
|
| 167 |
map.countries.some(country => country.c_code === countryFilter);
|
| 168 |
+
const matchesImageType = !imageTypeFilter || map.image_type === imageTypeFilter;
|
| 169 |
|
| 170 |
+
return matchesSearch && matchesSource && matchesCategory && matchesRegion && matchesCountry && matchesImageType ? map : null;
|
| 171 |
+
}, [map, search, srcFilter, catFilter, regionFilter, countryFilter, imageTypeFilter]);
|
| 172 |
|
| 173 |
const handleContribute = async () => {
|
| 174 |
if (!map) return;
|
|
|
|
| 348 |
labelSelector={(o) => o.label}
|
| 349 |
/>
|
| 350 |
</Container>
|
| 351 |
+
|
| 352 |
+
<Container withInternalPadding className="bg-white/20 backdrop-blur-sm rounded-md p-2">
|
| 353 |
+
<SelectInput
|
| 354 |
+
name="imageType"
|
| 355 |
+
placeholder="All Image Types"
|
| 356 |
+
options={imageTypes}
|
| 357 |
+
value={imageTypeFilter || null}
|
| 358 |
+
onChange={(v) => setImageTypeFilter(v as string || '')}
|
| 359 |
+
keySelector={(o) => o.image_type}
|
| 360 |
+
labelSelector={(o) => o.label}
|
| 361 |
+
required={false}
|
| 362 |
+
/>
|
| 363 |
+
</Container>
|
| 364 |
</div>
|
| 365 |
</div>
|
| 366 |
|
|
|
|
| 476 |
onClick={handleContribute}
|
| 477 |
disabled={isGenerating}
|
| 478 |
>
|
| 479 |
+
{isGenerating ? (
|
| 480 |
+
<div className="flex items-center gap-2">
|
| 481 |
+
<Spinner className="text-white" />
|
| 482 |
+
<span>Generating...</span>
|
| 483 |
+
</div>
|
| 484 |
+
) : (
|
| 485 |
+
'Contribute'
|
| 486 |
+
)}
|
| 487 |
</Button>
|
| 488 |
</Container>
|
| 489 |
|
|
|
|
| 528 |
setCatFilter('');
|
| 529 |
setRegionFilter('');
|
| 530 |
setCountryFilter('');
|
| 531 |
+
setImageTypeFilter('');
|
| 532 |
}}
|
| 533 |
>
|
| 534 |
Clear Filters
|