import { FormEvent, useState } from "react"; import { Alert, Box, Button, Card, CardActions, CardContent, CircularProgress, Stack, TextField, Typography } from "@mui/material"; import SearchIcon from "@mui/icons-material/Search"; import AddIcon from "@mui/icons-material/Add"; import { useNavigate } from "react-router-dom"; import { api } from "../api"; type DiscoveredJob = { id: string; title: string; company?: string; location?: string; modifiedAt?: string; url: string; source: string; countryCode: string; }; export default function JobDiscoveryPage() { const navigate = useNavigate(); const [query, setQuery] = useState(""); const [location, setLocation] = useState(""); const [jobs, setJobs] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const search = async (event: FormEvent) => { event.preventDefault(); setLoading(true); setError(""); try { const response = await api.get("/job-discovery/search", { params: { q: query || undefined, location: location || undefined } }); setJobs(response.data ?? []); } catch { setError("NAV job discovery is temporarily unavailable."); } finally { setLoading(false); } }; return ( setQuery(event.target.value)} /> setLocation(event.target.value)} /> Official Norwegian vacancies from NAV. FINN, Indeed and LinkedIn jobs can still be captured by URL. {error ? {error} : null} {!loading && jobs.length === 0 ? Search recent active vacancies by role, company, or municipality. : null} {jobs.map((job) => ( {job.title} {[job.company, job.location].filter(Boolean).join(" · ")} NAV · Norway{job.modifiedAt ? " · Updated " + new Date(job.modifiedAt).toLocaleDateString() : ""} ))} ); }