/opt/canhelp/apps/web/src/app/tasks
NameSizeModeActions
new/-0755rm
[id]/-0755rm
page.tsx101240644editdlrm
TaskFiltersClient.tsx76440644editdlrm
TaskFiltersForm.tsx4930644editdlrm
TaskListClient.tsx57510644editdlrm
TaskMapClient.tsx92400644editdlrm
TaskMapDynamic.tsx6580644editdlrm
TaskModeToggle.tsx15890644editdlrm
TasksAuthGuard.tsx650644editdlrm
TaskViewToggle.tsx21320644editdlrm
Edit: /opt/canhelp/apps/web/src/app/tasks/TaskFiltersClient.tsx (7644B)
'use client' import { useState } from 'react' import { useRouter, usePathname } from 'next/navigation' import { useLocale } from '@/context/locale' import { TaskCategoryPicker } from '@/components/TaskCategoryPicker' import { TaskLocationPicker } from '@/components/TaskLocationPicker' interface Props { categories: any[] locationTree: any[] budgetRange: { min: number; max: number } initialMode: 'for_me' | 'all' initialQ?: string initialCategory?: string initialLocation?: string initialBudgetMin?: string initialBudgetMax?: string } export function TaskFiltersClient({ categories, locationTree, budgetRange, initialMode, initialQ, initialCategory, initialLocation, initialBudgetMin, initialBudgetMax, }: Props) { const router = useRouter() const pathname = usePathname() const { t, locale } = useLocale() const catLocale = locale === 'en' ? 'en' : locale === 'ru' ? 'ru' : locale === 'uk' ? 'uk' : 'el' const [mode, setMode] = useState<'for_me' | 'all'>(initialMode) const [q, setQ] = useState(initialQ ?? '') const [selectedCategory, setSelectedCategory] = useState(initialCategory ?? '') const [selectedLocation, setSelectedLocation] = useState(initialLocation ?? '') const hasFilter = !!(initialQ || initialCategory || initialLocation || initialBudgetMin || initialBudgetMax) function buildUrl(overrides: Record) { const base: Record = { mode: mode === 'for_me' ? undefined : 'all', q: q || undefined, category: selectedCategory || undefined, location: selectedLocation || undefined, budgetMin: initialBudgetMin || undefined, budgetMax: initialBudgetMax || undefined, ...overrides, } const qs = new URLSearchParams() for (const [k, v] of Object.entries(base)) { if (v) qs.set(k, v) } return `${pathname}${qs.toString() ? '?' + qs.toString() : ''}` } function handleModeChange(newMode: 'for_me' | 'all') { setMode(newMode) setSelectedCategory('') router.push(buildUrl({ mode: newMode === 'for_me' ? undefined : 'all', category: undefined })) } function handleCategoryChange(slug: string) { setSelectedCategory(slug) router.push(buildUrl({ category: slug || undefined })) } function handleLocationChange(slug: string) { setSelectedLocation(slug) router.push(buildUrl({ location: slug || undefined })) } function handleSubmit(e: React.FormEvent) { e.preventDefault() const fd = new FormData(e.currentTarget) const budgetMin = (fd.get('budgetMin') as string) || undefined const budgetMax = (fd.get('budgetMax') as string) || undefined router.push(buildUrl({ budgetMin, budgetMax })) } function handleReset() { setQ('') setSelectedCategory('') setSelectedLocation('') router.push(mode === 'for_me' ? '/tasks' : '/tasks?mode=all') } const forMeLabel = t('find_tasks.for_me') const allLabel = t('find_tasks.all') const locAnyLabel = t('create.field.location.any') const locAllLabel = t('create.field.location.all') const catPlaceholder = t('filter.category.all') return (
{/* Mode toggle inside sidebar */}
{/* Search */}
setQ(e.target.value)} placeholder={t('tasks.search.placeholder')} className="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400" />
{/* Category — only shown in "all" mode */} {mode === 'all' && categories.length > 0 && (
)} {/* Location */} {locationTree.length > 0 && (
)} {/* Budget */}
{budgetRange.max > 0 && (

{t('tasks.budget.range')} {budgetRange.min}€ — {budgetRange.max}€

)}
{hasFilter && ( )}
) }