bbuddy-ui/src/components/Experts/ExpertsList.tsx

150 lines
6.1 KiB
TypeScript

'use client';
import React, { useEffect, useState } from 'react';
import { useSearchParams } from 'next/navigation';
import { List, Tag } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import isEqual from 'lodash/isEqual';
import Image from 'next/image';
import { Link, useRouter } from '../../i18n/routing';
import { ExpertsData, Filter, GeneralFilter } from '../../types/experts';
import { getObjectByFilter, getObjectByAdditionalFilter, getSearchParamsString } from '../../utils/filter';
import { getDuration, getPrice } from '../../utils/expert';
import { getExpertsList } from '../../actions/experts';
import { CustomPagination } from '../view/CustomPagination';
import { CustomSpin } from '../view/CustomSpin';
import { i18nText } from '../../i18nKeys';
type ExpertListProps = {
data?: ExpertsData;
locale: string;
baseFilter: Filter;
pageSize: number;
basePath: string;
};
export const ExpertsList = ({
data,
locale,
baseFilter,
pageSize,
basePath
}: ExpertListProps) => {
const searchParams = useSearchParams();
const router = useRouter();
const [experts, setExperts] = useState<ExpertsData | undefined>();
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
const filter = {
...baseFilter,
...getObjectByFilter(searchParams),
...getObjectByAdditionalFilter(searchParams)
};
if (!isEqual(baseFilter, filter)) {
setLoading(true);
getExpertsList(locale, filter)
.then((experts) => {
setExperts(experts);
})
.finally(() => {
setLoading(false);
})
;
} else {
setLoading(false);
setExperts(data);
}
}, [searchParams]);
const onChangePage = (page: number) => {
const newFilter: GeneralFilter = {
...getObjectByFilter(searchParams),
...getObjectByAdditionalFilter(searchParams)
};
if (page !== 1) {
newFilter.page = page;
} else {
delete newFilter.page;
}
const search = getSearchParamsString(newFilter);
router.push(search ? `${basePath}?${search}#filter` : `${basePath}#filter`);
};
const currentPage = searchParams.has('page') ? Number(searchParams.get('page')) : baseFilter.page;
return !loading ? experts?.coaches && (
<>
<List
itemLayout="vertical"
size="large"
className="search-result"
dataSource={experts.coaches}
locale={{ emptyText: i18nText('notFound', locale) }}
renderItem={(item) => (
<List.Item key={item?.id} className="card-profile">
<List.Item.Meta
className="card-profile__header"
avatar={(
<div className="card-profile__header__portrait">
<Image src={item?.faceImageUrl || '/images/person.png'} width={100} height={100} alt="" />
</div>
)}
description={(
<div className="card-profile__header__inner">
<div>
<Link href={`/experts/${item?.id}` as any}>
<div className="card-profile__header__name">{`${item.name} ${item?.surname || ''}`}</div>
</Link>
<div className="card-profile__header__price">
{getPrice(item?.sessionCost)} <span>/ {getDuration(locale, item?.sessionDuration)}</span>
</div>
</div>
<div className="card-profile__header__lang">
{item?.coachLanguages?.map((lang) => (
<Tag key={lang} className="skills__list__item">{lang}</Tag>
))}
</div>
</div>
)}
/>
<div className="card-profile__skills">
<div className="skills__list">
{item?.tags?.slice(0, 2).map((skill) => <Tag key={skill?.id} className="skills__list__item">{skill?.name}</Tag>)}
{item?.tags?.length > 2
? (
<Tag className="skills__list__more">
<Link href={`/experts/${item?.id}` as any}>
{`+${item?.tags?.length - 2}`}
</Link>
</Tag>
) : null}
</div>
</div>
<div className="card-profile__title">{item?.speciality}</div>
<div className="card-profile__subtitle">{item?.specialityDesc}</div>
<div className="card-profile__desc">{item?.description}</div>
<div className="card-profile__footer">
<Link href={`/experts/${item?.id}` as any}>
{i18nText('details', locale)}
<RightOutlined style={{ fontSize: '10px', padding: '0 7px' }}/>
</Link>
</div>
</List.Item>
)}
/>
{experts.total > pageSize && (
<CustomPagination
total={experts.total}
pageSize={pageSize}
onChange={onChangePage}
current={currentPage}
/>)}
</>
) : <CustomSpin />;
};