bbuddy-ui/src/components/Account/sessions/SessionDetailsContent.tsx

302 lines
15 KiB
TypeScript

'use client'
import React, { useState } from 'react';
import { Button, Empty, notification, Tag } from 'antd';
import { LeftOutlined, PlusOutlined, RightOutlined } from '@ant-design/icons';
import Image from 'next/image';
import dayjs from 'dayjs';
import { Link, useRouter } from '../../../navigation';
import { i18nText } from '../../../i18nKeys';
import { getDuration, getPrice } from '../../../utils/expert';
import { PublicUser, Session, SessionState, SessionType } from '../../../types/sessions';
import { AUTH_TOKEN_KEY } from '../../../constants/common';
import { approveRequestedSession, finishSession } from '../../../actions/sessions';
import { useLocalStorage } from '../../../hooks/useLocalStorage';
import { DeclineSessionModal } from '../../Modals/DeclineSessionModal';
import { AddCommentModal } from '../../Modals/AddCommentModal';
type SessionDetailsContentProps = {
locale: string;
session: Session;
activeType: SessionType;
startSession: () => void;
refresh: () => void;
isCoach: boolean;
};
export const SessionDetailsContent = ({ session, locale, activeType, startSession, refresh, isCoach }: SessionDetailsContentProps) => {
const [jwt] = useLocalStorage(AUTH_TOKEN_KEY, '');
const [approveLoading, setApproveLoading] = useState<boolean>(false);
const [finishLoading, setFinishLoading] = useState<boolean>(false);
const [openDeclineModal, setOpenDeclineModal] = useState<boolean>(false);
const [openAddCommentModal, setOpenAddCommentModal] = useState<boolean>(false);
const router = useRouter();
const goBack = () => router.push(`/account/sessions/${activeType}`);
const onApproveSession = () => {
if (activeType === SessionType.REQUESTED) {
setApproveLoading(true);
approveRequestedSession(locale, jwt, session.id)
.then(() => {
goBack();
})
.catch((err) => {
notification.error({
message: i18nText('errors.approvingSession', locale),
description: err?.response?.data?.errMessage
});
})
.finally(() => {
setApproveLoading(false);
});
} else {
startSession();
}
};
const onFinishSession = () => {
if (isCoach) {
setFinishLoading(true);
finishSession(locale, jwt, session.id)
.then(() => {
goBack();
})
.catch((err) => {
notification.error({
message: i18nText('errors.finishingSession', locale),
description: err?.response?.data?.errMessage
});
})
.finally(() => {
setFinishLoading(false);
})
}
};
const startDate = session?.scheduledStartAtUtc ? dayjs(session?.scheduledStartAtUtc).locale(locale) : null;
const endDate = session?.scheduledEndAtUtc ? dayjs(session?.scheduledEndAtUtc).locale(locale) : null;
const today = startDate ? dayjs().format('YYYY-MM-DD') === startDate.format('YYYY-MM-DD') : false;
const CoachCard = (coach?: PublicUser) => coach ? (
<div className="card-detail__expert">
<div className="card-detail__portrait">
<Image src={coach?.faceImageUrl || '/images/person.png'} width={140} height={140} alt="" />
</div>
<div className="card-detail__inner">
<Link href={`/experts/${coach?.id}` as any} target="_blank">
<div className="card-detail__name">{`${coach?.name} ${coach?.surname || ''}`}</div>
</Link>
{/* <div className="card-detail__info">
<div className="card-profile__subtitle">{coach?.specialityDesc}</div>
<div className="card-detail__lang">
{coach?.coachLanguages?.map((lang) => (
<Tag key={lang} className="skills__list__item">{lang}</Tag>
))}
</div>
</div> */}
<div className="card-detail__cost">
{getPrice(session?.cost)} <span>/ {getDuration(locale, session?.totalDuration)}</span>
</div>
<div className={`card-detail__date${today ? ' chosen': ''}${activeType === SessionType.RECENT ? ' history' : ''}`}>
{today
? `${i18nText('today', locale)} ${startDate?.format('HH:mm')} - ${endDate?.format('HH:mm')}`
: `${startDate?.format('D MMMM')} ${startDate?.format('HH:mm')} - ${endDate?.format('HH:mm')}`}
</div>
<div className="card-detail__skills">
<div className="skills__list">
{session?.themesTags?.slice(0, 2).map((skill) => <Tag key={skill?.id} className="skills__list__item">{skill?.name}</Tag>)}
{session?.themesTags?.length > 2
? (
<Tag className="skills__list__more">
<Link href={`/experts/${coach?.id}` as any} target="_blank">
{`+${session?.themesTags?.length - 2}`}
</Link>
</Tag>
) : null }
</div>
</div>
{/* <div className="card-profile__desc">{coach?.description}</div> */}
<Link href={`/experts/${coach?.id}` as any} target="_blank" className="card-detail__more">
{i18nText('details', locale)}
<RightOutlined style={{ fontSize: '10px', padding: '0 7px' }}/>
</Link>
</div>
</div>
) : null;
const StudentCard = (student?: PublicUser | null) => student ? (
<div className="card-detail__expert">
<div className="card-detail__portrait">
<Image src={student?.faceImageUrl || '/images/person.png'} width={140} height={140} alt="" />
</div>
<div className="card-detail__inner">
<div className="card-detail__name">{`${student?.name} ${student?.surname || ''}`}</div>
<div className={`card-detail__date${today ? ' chosen': ''}${activeType === SessionType.RECENT ? ' history' : ''}`}>
{today
? `${i18nText('today', locale)} ${startDate?.format('HH:mm')} - ${endDate?.format('HH:mm')}`
: `${startDate?.format('D MMMM')} ${startDate?.format('HH:mm')} - ${endDate?.format('HH:mm')}`}
</div>
<div className="card-detail__skills">
<div className="skills__list">
<Tag className="skills__list__item">{session?.themesTagName}</Tag>
</div>
</div>
{/* <div className="card-profile__desc">{student?.description}</div> */}
{activeType === SessionType.REQUESTED && session?.clientComment && (
<div className="card-detail__comments">
<div className="card-detail__comments_item">
{session.clientComment}
</div>
</div>
)}
</div>
</div>
) : null;
const client = session?.clients?.length ? session?.clients[0] : null;
const Current = isCoach ? StudentCard(client) : CoachCard(session?.coach);
return (
<div className="card-detail">
<div>
<Button
className="card-detail__back"
type="link"
icon={<LeftOutlined />}
onClick={goBack}
>
{i18nText('back', locale)}
</Button>
</div>
{Current}
{(activeType === SessionType.UPCOMING || activeType === SessionType.REQUESTED) &&
(session?.state === SessionState.CREATED || session?.state === SessionState.PAID
|| session?.state === SessionState.COACH_APPROVED || session?.state === SessionState.STARTED) && (
<div className="card-detail__actions">
<Button
className="card-detail__apply"
onClick={onApproveSession}
loading={approveLoading}
disabled={finishLoading}
>
{activeType === SessionType.UPCOMING
? (session?.state === SessionState.STARTED ? i18nText('session.join', locale) : i18nText('session.start', locale))
: i18nText('session.confirm', locale)}
</Button>
{session?.state === SessionState.STARTED && isCoach && (
<Button
className="card-detail__decline"
onClick={onFinishSession}
loading={finishLoading}
>
{i18nText('session.finish', locale)}
</Button>
)}
{session?.id && session?.state !== SessionState.STARTED && (
<>
<Button
className="card-detail__decline"
onClick={() => setOpenDeclineModal(true)}
disabled={approveLoading}
>
{i18nText('session.decline', locale)}
</Button>
<DeclineSessionModal
open={openDeclineModal}
handleCancel={() => setOpenDeclineModal(false)}
activeType={activeType}
locale={locale}
sessionId={session.id}
success={goBack}
/>
</>
)}
</div>
)}
{activeType !== SessionType.REQUESTED && (
<>
{activeType === SessionType.RECENT && (
<>
<div className="card-detail__name">{i18nText('courseInfo', locale)}</div>
<div className="card-detail__inner">
{/* <div className="card-detail__info">
<div className="card-profile__subtitle">{current?.specialityDesc}</div>
<div className="card-detail__lang">
{current?.coachLanguages?.map((lang) => (
<Tag key={lang} className="skills__list__item">{lang}</Tag>
))}
</div>
</div> */}
<div className="card-detail__cost">
{getPrice(session?.cost)} <span>/ {getDuration(locale, session?.totalDuration)}</span>
</div>
<div className="card-detail__skills">
<div className="skills__list">
{session?.themesTags?.slice(0, 2).map((skill) => <Tag key={skill?.id} className="skills__list__item">{skill?.name}</Tag>)}
{session?.themesTags?.length > 2
? (
<Tag className="skills__list__more">
{`+${session?.themesTags?.length - 2}`}
</Tag>
) : null }
</div>
</div>
{/* <div className="card-profile__desc">{current?.description}</div> */}
</div>
</>
)}
<div className="card-detail__comments">
<div className="card-detail__comments_header">
<div className="card-detail__comments_title">
{session?.clientComments?.length === 0 && session?.coachComments?.length === 0
? i18nText('session.comments', locale)
: i18nText('session.myComments', locale)}
</div>
{activeType === SessionType.UPCOMING && (
<>
<Button
className="card-detail__comments_add"
type="link"
iconPosition="end"
icon={<PlusOutlined style={{ fontSize: 18 }} />}
onClick={() => setOpenAddCommentModal(true)}
>
{i18nText('session.addComment', locale)}
</Button>
<AddCommentModal
open={openAddCommentModal}
handleCancel={() => setOpenAddCommentModal(false)}
locale={locale}
sessionId={session.id}
refresh={refresh}
/>
</>
)}
</div>
{(session?.clientComments?.length > 0 || session?.coachComments?.length > 0) ? (
<>
{(isCoach ? session?.coachComments : session?.clientComments)?.map(({ id, comment }) => (
<div key={`my_${id}`} className="card-detail__comments_item">
{comment}
</div>
))}
{(isCoach ? session?.clientComments : session?.coachComments)?.length > 0 && (
<div className="card-detail__comments_title">
{isCoach ? 'Client Comments' : 'Coach Comments'}
</div>
)}
{(isCoach ? session?.clientComments : session?.coachComments)?.map(({ id , comment }) => (
<div key={`oth_${id}`} className="card-detail__comments_item">
{comment}
</div>
))}
</>
) : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
</div>
</>
)}
</div>
);
};