feat: add advanced filters UI to jobs page
Frontend: - Add salaryMin, salaryMax, currencyFilter, visaSupport state - Enable sortBy dropdown with 4 options (recent, salary_desc, salary_asc, relevance) - Add currency filter (BRL, USD, EUR, JPY) - Update api.ts jobsApi.list with new filter params - Fix employmentType query param name (was 'type') All filters now match backend API endpoints
This commit is contained in:
parent
9a4e469a18
commit
246c55b0f5
2 changed files with 48 additions and 4 deletions
|
|
@ -32,9 +32,15 @@ function JobsContent() {
|
|||
const [locationFilter, setLocationFilter] = useState("")
|
||||
const [typeFilter, setTypeFilter] = useState("all")
|
||||
const [workModeFilter, setWorkModeFilter] = useState("all")
|
||||
const [sortBy, setSortBy] = useState("recent") // Client-side sort or ignore? Backend doesn't support sort yet generally.
|
||||
const [sortBy, setSortBy] = useState("recent")
|
||||
const [showFilters, setShowFilters] = useState(false)
|
||||
|
||||
// Advanced filters
|
||||
const [salaryMin, setSalaryMin] = useState("")
|
||||
const [salaryMax, setSalaryMax] = useState("")
|
||||
const [currencyFilter, setCurrencyFilter] = useState("all")
|
||||
const [visaSupport, setVisaSupport] = useState(false)
|
||||
|
||||
// Pagination state
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [totalJobs, setTotalJobs] = useState(0)
|
||||
|
|
@ -82,6 +88,11 @@ function JobsContent() {
|
|||
location: debouncedLocation || undefined,
|
||||
type: typeFilter === "all" ? undefined : typeFilter,
|
||||
workMode: workModeFilter === "all" ? undefined : workModeFilter,
|
||||
salaryMin: salaryMin ? parseFloat(salaryMin) : undefined,
|
||||
salaryMax: salaryMax ? parseFloat(salaryMax) : undefined,
|
||||
currency: currencyFilter === "all" ? undefined : currencyFilter,
|
||||
visaSupport: visaSupport || undefined,
|
||||
sortBy: sortBy || undefined,
|
||||
})
|
||||
|
||||
// Transform the raw API response to frontend format
|
||||
|
|
@ -121,6 +132,11 @@ function JobsContent() {
|
|||
setLocationFilter("")
|
||||
setTypeFilter("all")
|
||||
setWorkModeFilter("all")
|
||||
setSalaryMin("")
|
||||
setSalaryMax("")
|
||||
setCurrencyFilter("all")
|
||||
setVisaSupport(false)
|
||||
setSortBy("recent")
|
||||
}
|
||||
|
||||
const getTypeLabel = (type: string) => {
|
||||
|
|
@ -244,13 +260,29 @@ function JobsContent() {
|
|||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Select value={sortBy} onValueChange={setSortBy} disabled>
|
||||
<Select value={sortBy} onValueChange={setSortBy}>
|
||||
<SelectTrigger>
|
||||
<ArrowUpDown className="h-4 w-4 mr-2" />
|
||||
<SelectValue placeholder={t('jobs.filters.order')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="recent">{t('jobs.sort.recent')}</SelectItem>
|
||||
<SelectItem value="recent">{t('jobs.sort.recent') || 'Mais recentes'}</SelectItem>
|
||||
<SelectItem value="salary_desc">{t('jobs.sort.salaryDesc') || 'Maior salário'}</SelectItem>
|
||||
<SelectItem value="salary_asc">{t('jobs.sort.salaryAsc') || 'Menor salário'}</SelectItem>
|
||||
<SelectItem value="relevance">{t('jobs.sort.relevance') || 'Relevância'}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Select value={currencyFilter} onValueChange={setCurrencyFilter}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Moeda" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Todas moedas</SelectItem>
|
||||
<SelectItem value="BRL">R$ (BRL)</SelectItem>
|
||||
<SelectItem value="USD">$ (USD)</SelectItem>
|
||||
<SelectItem value="EUR">€ (EUR)</SelectItem>
|
||||
<SelectItem value="JPY">¥ (JPY)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
|
|
|||
|
|
@ -313,15 +313,27 @@ export const jobsApi = {
|
|||
type?: string;
|
||||
workMode?: string;
|
||||
companyId?: string;
|
||||
// Advanced filters
|
||||
salaryMin?: number;
|
||||
salaryMax?: number;
|
||||
currency?: string;
|
||||
visaSupport?: boolean;
|
||||
sortBy?: string;
|
||||
}) => {
|
||||
const query = new URLSearchParams();
|
||||
if (params.page) query.append("page", params.page.toString());
|
||||
if (params.limit) query.append("limit", params.limit.toString());
|
||||
if (params.q) query.append("q", params.q);
|
||||
if (params.location) query.append("location", params.location);
|
||||
if (params.type) query.append("type", params.type);
|
||||
if (params.type) query.append("employmentType", params.type);
|
||||
if (params.workMode) query.append("workMode", params.workMode);
|
||||
if (params.companyId) query.append("companyId", params.companyId);
|
||||
// Advanced filters
|
||||
if (params.salaryMin) query.append("salaryMin", params.salaryMin.toString());
|
||||
if (params.salaryMax) query.append("salaryMax", params.salaryMax.toString());
|
||||
if (params.currency) query.append("currency", params.currency);
|
||||
if (params.visaSupport) query.append("visaSupport", "true");
|
||||
if (params.sortBy) query.append("sortBy", params.sortBy);
|
||||
|
||||
return apiRequest<{
|
||||
data: ApiJob[];
|
||||
|
|
|
|||
Loading…
Reference in a new issue