/opt/canhelp/apps/web/src/app/tasks
Edit: /opt/canhelp/apps/web/src/app/tasks/TaskListClient.tsx (5751B)
'use client'
import { useState } from 'react'
import Link from 'next/link'
import { useLocale } from '@/context/locale'
import { getTranslations } from '@/lib/translations'
import type { Locale } from '@/lib/translations'
import { taskTitle, taskDescription, formatPrice } from '@/lib/taskLocale'
import { shortName } from '@/lib/formatName'
const BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000'
interface Props {
initialTasks: any[]
initialTotal: number
filterParams: Record
locale: Locale
catMap: Record
locMap: Record
mode?: 'for_me' | 'all'
}
export function TaskListClient({ initialTasks, initialTotal, filterParams, locale: localeProp, catMap, locMap, mode = 'all' }: Props) {
const { locale } = useLocale()
const t = getTranslations(locale)
const [tasks, setTasks] = useState(initialTasks)
const [total] = useState(initialTotal)
const [page, setPage] = useState(1)
const [loading, setLoading] = useState(false)
const hasMore = tasks.length < total
async function loadMore() {
setLoading(true)
try {
const nextPage = page + 1
const params = new URLSearchParams({ ...filterParams, page: String(nextPage), limit: '10' })
const endpoint = mode === 'for_me' ? '/tasks/for-me' : '/tasks'
const res = await fetch(`${BASE}/api${endpoint}?${params}`, { credentials: 'include' })
const json = await res.json()
setTasks(prev => [...prev, ...(json.data || [])])
setPage(nextPage)
} finally {
setLoading(false)
}
}
if (tasks.length === 0) {
return (
)
}
return (
{tasks.map((row: any) => {
const task = row.task || row
const customer = row.customer
return (
{task.category ? (catMap[task.category] ?? task.category) : t('tasks.category.general')}
{task.location && (
📍 {locMap[task.location] ?? task.location}
)}
{taskTitle(task, locale)}
{taskDescription(task, locale)}
{task.budget ? (
<>
{formatPrice(task.budget)}€
{task.budgetNegotiable && (
{t('task.budget_negotiable')}
)}
>
) : task.budgetNegotiable ? (
{t('task.budget_negotiable')}
) : null}
{task.deadline ? t('task.deadline') : t('task.created_at')}:
{new Date(task.deadline ?? task.createdAt).toLocaleDateString(
locale === 'ru' ? 'ru-RU' : locale === 'en' ? 'en-US' : 'el-GR'
)}
{customer && (
{shortName(customer.name)}
{customer.rating && (
★ {Number(customer.rating).toFixed(1)}
)}
{customer.image ? (

) : (
{shortName(customer.name).charAt(0).toUpperCase()}
)}
)}
)
})}
{hasMore && (
)}
)
}