diff --git a/package-lock.json b/package-lock.json
index cfa03e5..4cbe0fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@ant-design/cssinjs": "^1.18.1",
"@ant-design/icons": "^5.2.6",
"@ant-design/nextjs-registry": "^1.0.0",
+ "agora-rtc-react": "^2.1.0",
"antd": "^5.12.1",
"antd-img-crop": "^4.21.0",
"axios": "^1.6.5",
@@ -873,6 +874,17 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/agora-rtc-react": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/agora-rtc-react/-/agora-rtc-react-2.1.0.tgz",
+ "integrity": "sha512-3FGteA7FG51oK5MusbYNgAcKZaAQK+4sbEz4F0DPzcpDxqNANpocJDqOsmXoUAj5yDBsBZelmagU3abd++6RGA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -5947,6 +5959,12 @@
"dev": true,
"requires": {}
},
+ "agora-rtc-react": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/agora-rtc-react/-/agora-rtc-react-2.1.0.tgz",
+ "integrity": "sha512-3FGteA7FG51oK5MusbYNgAcKZaAQK+4sbEz4F0DPzcpDxqNANpocJDqOsmXoUAj5yDBsBZelmagU3abd++6RGA==",
+ "requires": {}
+ },
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
diff --git a/package.json b/package.json
index 35d2112..8998103 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"@ant-design/cssinjs": "^1.18.1",
"@ant-design/icons": "^5.2.6",
"@ant-design/nextjs-registry": "^1.0.0",
+ "agora-rtc-react": "^2.1.0",
"antd": "^5.12.1",
"antd-img-crop": "^4.21.0",
"axios": "^1.6.5",
diff --git a/src/actions/profile.ts b/src/actions/profile.ts
index 53462bf..a3a98de 100644
--- a/src/actions/profile.ts
+++ b/src/actions/profile.ts
@@ -60,7 +60,7 @@ export const getRequestedSessions = (locale: string, jwt: string): Promise> => (
apiClient.post(
- '/home/historicalmeetings ',
+ '/home/historicalmeetings',
{
sessionType: 'session',
...(filter || {})
@@ -73,3 +73,16 @@ export const getRecentSessions = (locale: string, jwt: string, filter?: Sessions
}
)
);
+
+export const getSessionDetails = (locale: string, jwt: string, id: number): Promise> => (
+ apiClient.post(
+ '/home/session',
+ { id },
+ {
+ headers: {
+ 'X-User-Language': locale,
+ Authorization: `Bearer ${jwt}`
+ }
+ }
+ )
+);
diff --git a/src/app/[locale]/account/(account)/sessions/page.tsx b/src/app/[locale]/account/(account)/sessions/page.tsx
index 6262afe..c3ac0e5 100644
--- a/src/app/[locale]/account/(account)/sessions/page.tsx
+++ b/src/app/[locale]/account/(account)/sessions/page.tsx
@@ -1,7 +1,7 @@
import React, { Suspense } from 'react';
import type { Metadata } from 'next';
import { useTranslations } from 'next-intl';
-import { SessionsTabs } from '../../../../../components/Account';
+import { SessionsAll } from '../../../../../components/Account';
export const metadata: Metadata = {
title: 'Bbuddy - Account - Sessions',
@@ -13,9 +13,7 @@ export default function Sessions({ params: { locale } }: { params: { locale: str
return (
Loading...
}>
-
+
);
}
diff --git a/src/components/Account/AccountMenu.tsx b/src/components/Account/AccountMenu.tsx
index 8624fcb..5e4899f 100644
--- a/src/components/Account/AccountMenu.tsx
+++ b/src/components/Account/AccountMenu.tsx
@@ -1,6 +1,6 @@
'use client';
-import React from 'react';
+import React, { useState } from 'react';
import styled from 'styled-components';
import { Button } from 'antd';
import { useSelectedLayoutSegment, usePathname } from 'next/navigation';
@@ -8,6 +8,7 @@ import { Link } from '../../navigation';
import { AUTH_TOKEN_KEY, AUTH_USER } from '../../constants/common';
import { deleteStorageKey } from '../../hooks/useLocalStorage';
import { i18nText } from '../../i18nKeys';
+import { DeleteAccountModal } from '../Modals/DeleteAccountModal';
const Logout = styled(Button)`
width: 100%;
@@ -24,6 +25,7 @@ export const AccountMenu = ({ menu, locale }: { menu: { path: string, title: str
const selectedLayoutSegment = useSelectedLayoutSegment();
const pathname = selectedLayoutSegment || '';
const paths = usePathname();
+ const [showDeleteModal, setShowDeleteModal] = useState(false);
const onLogout = () => {
deleteStorageKey(AUTH_TOKEN_KEY);
@@ -31,9 +33,7 @@ export const AccountMenu = ({ menu, locale }: { menu: { path: string, title: str
window?.location?.replace(`/${paths.split('/')[1]}/`);
};
- const onDeleteAccount = () => {
- console.log('delete');
- };
+ const onDeleteAccount = () => setShowDeleteModal(true);
return (
@@ -62,6 +62,10 @@ export const AccountMenu = ({ menu, locale }: { menu: { path: string, title: str
>
{i18nText('deleteAcc', locale)}
+ setShowDeleteModal(false)}
+ />
);
diff --git a/src/components/Account/index.ts b/src/components/Account/index.ts
index 435b58a..8f56865 100644
--- a/src/components/Account/index.ts
+++ b/src/components/Account/index.ts
@@ -1,5 +1,5 @@
'use client'
export { AccountMenu } from './AccountMenu';
-export { SessionsTabs } from './SessionsTabs';
export { ProfileSettings } from './ProfileSettings';
+export * from './sessions';
diff --git a/src/components/Account/sessions/SessionDetails.tsx b/src/components/Account/sessions/SessionDetails.tsx
new file mode 100644
index 0000000..922c191
--- /dev/null
+++ b/src/components/Account/sessions/SessionDetails.tsx
@@ -0,0 +1,137 @@
+'use client'
+
+import React, { useCallback, useEffect, useState } from 'react';
+import { Tag } from 'antd';
+import { RightOutlined } from '@ant-design/icons';
+import Image from 'next/image';
+import dayjs from 'dayjs';
+import { Link } from '../../../navigation';
+import { i18nText } from '../../../i18nKeys';
+import { getDuration, getPrice } from '../../../utils/expert';
+import { Session } from '../../../types/sessions';
+import { AUTH_TOKEN_KEY, AUTH_USER } from '../../../constants/common';
+import { getSessionDetails } from '../../../actions/profile';
+import { useLocalStorage } from '../../../hooks/useLocalStorage';
+import { Loader } from '../../view/Loader';
+
+type SessionDetailsProps = {
+ locale: string;
+ sessionId: number;
+ goBack: () => void;
+};
+
+export const SessionDetails = ({ sessionId, locale, goBack }: SessionDetailsProps) => {
+ const [jwt] = useLocalStorage(AUTH_TOKEN_KEY, '');
+ const [userId] = useLocalStorage(AUTH_USER, '');
+ const [loading, setLoading] = useState(false);
+ const [errorData, setErrorData] = useState();
+ const [session, setSession] = useState();
+
+ const fetchData = useCallback(() => {
+ setLoading(true);
+ setErrorData(undefined);
+ setSession(undefined);
+
+ getSessionDetails(locale, jwt, sessionId)
+ .then(({ data }) => {
+ console.log(data);
+ setSession(data);
+ })
+ .catch((err) => {
+ setErrorData(err);
+ })
+ .finally(() => {
+ setLoading(false);
+ })
+ }, []);
+
+ useEffect(() => {
+ fetchData();
+ }, [sessionId]);
+
+ const client = session?.clients?.length ? session?.clients[0] : null;
+ const current = +userId !== client?.id ? client : session?.coach;
+ 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;
+
+ return (
+
+
+
+ back
+
+
+
+
+
+
+
+
{`${current?.name} ${current?.surname || ''}`}
+
+
+
+ {/* current?.coachLanguages?.map((lang) => (
+ {lang}
+ )) */}
+
+
+ {/*
{current?.speciality}
*/}
+
+ {getPrice(session?.cost)} / {getDuration(locale, session?.totalDuration)}
+
+
+ {today
+ ? `${i18nText('today', locale)} ${startDate.format('HH:mm')} - ${endDate.format('HH:mm')}`
+ : `${startDate.format('D MMMM')} ${startDate.format('HH:mm')} - ${endDate.format('HH:mm')}`}
+
+
+
+ {session?.themesTags?.slice(0, 2).map((skill) => {skill?.name} )}
+ {session?.themesTags?.length > 2
+ ? (
+
+
+ {`+${session?.themesTags?.length - 2}`}
+
+
+ ) : null }
+
+
+ {/*
{current?.specialityDesc}
+
{current?.description}
*/}
+
+ {i18nText('details', locale)}
+
+
+
+
+
+ Start Session
+ Decline Session
+
+
+
+
+ My Comments
+
+
Add new
+
+
+ Sed tincidunt finibus eros nec feugiat. Nulla facilisi. Nunc maximus magna et egestas tincidunt. Integer lobortis laoreet neque at sodales. Aenean eget risus pharetra, efficitur dolor ut, commodo lacus. Sed vitae nunc odio. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et velit et dolor rutrum euismod a pretium est.
+
+
+ Coach Comments
+
+
+ Sed tincidunt finibus eros nec feugiat. Nulla facilisi. Nunc maximus magna et egestas tincidunt. Integer lobortis laoreet neque at sodales. Aenean eget risus pharetra, efficitur dolor ut, commodo lacus. Sed vitae nunc odio. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et velit et dolor rutrum euismod a pretium est.
+
+
+
+
+ );
+};
diff --git a/src/components/Account/SessionsTabs.tsx b/src/components/Account/sessions/SessionsTabs.tsx
similarity index 87%
rename from src/components/Account/SessionsTabs.tsx
rename to src/components/Account/sessions/SessionsTabs.tsx
index 2132d27..97f40ec 100644
--- a/src/components/Account/SessionsTabs.tsx
+++ b/src/components/Account/sessions/SessionsTabs.tsx
@@ -1,6 +1,6 @@
'use client';
-import React, { useCallback, useEffect, useState } from 'react';
+import React, { useCallback, useEffect, useState, MouseEvent } from 'react';
import { Empty, Space } from 'antd';
import dayjs from 'dayjs';
import 'dayjs/locale/ru';
@@ -9,14 +9,19 @@ import 'dayjs/locale/de';
import 'dayjs/locale/it';
import 'dayjs/locale/fr';
import 'dayjs/locale/es';
-import { Loader } from '../view/Loader';
-import { useLocalStorage } from '../../hooks/useLocalStorage';
-import { AUTH_TOKEN_KEY, AUTH_USER } from '../../constants/common';
-import { getRecentSessions, getRequestedSessions, getUpcomingSessions } from '../../actions/profile';
-import { Session, Sessions, SessionType } from '../../types/sessions';
-import { i18nText } from '../../i18nKeys';
+import { Loader } from '../../view/Loader';
+import { useLocalStorage } from '../../../hooks/useLocalStorage';
+import { AUTH_TOKEN_KEY, AUTH_USER } from '../../../constants/common';
+import { getRecentSessions, getRequestedSessions, getUpcomingSessions } from '../../../actions/profile';
+import { Session, Sessions, SessionType } from '../../../types/sessions';
+import { i18nText } from '../../../i18nKeys';
-export const SessionsTabs = ({ locale }: { locale: string }) => {
+type SessionsTabsProps = {
+ locale: string;
+ updateSession: (val: number) => void;
+};
+
+export const SessionsTabs = ({ locale, updateSession }: SessionsTabsProps) => {
const [activeTab, setActiveTab] = useState(0);
const [sort, setSort] = useState();
const [sessions, setSessions] = useState();
@@ -56,6 +61,12 @@ export const SessionsTabs = ({ locale }: { locale: string }) => {
setSort(value);
}, [sort]);
+ const onClickSession = (event: MouseEvent, id: number) => {
+ event.stopPropagation();
+ event.preventDefault();
+ updateSession(id);
+ };
+
const getChildren = (list?: Session[]) => (
<>
{/*
@@ -82,7 +93,7 @@ export const SessionsTabs = ({ locale }: { locale: string }) => {
const today = dayjs().format('YYYY-MM-DD') === startDate.format('YYYY-MM-DD');
return (
-
+
) => onClickSession(e, id)}>
diff --git a/src/components/Account/sessions/index.tsx b/src/components/Account/sessions/index.tsx
new file mode 100644
index 0000000..264be30
--- /dev/null
+++ b/src/components/Account/sessions/index.tsx
@@ -0,0 +1,22 @@
+'use client'
+
+import React, { useState } from 'react';
+import { SessionDetails } from './SessionDetails';
+import { SessionsTabs } from './SessionsTabs';
+
+export const SessionsAll = ({ locale }: { locale: string }) => {
+ const [customSession, setCustomSession] = useState
();
+
+ return customSession ? (
+ setCustomSession(undefined)}
+ />
+ ) : (
+
+ );
+};
diff --git a/src/components/Experts/ExpertsList.tsx b/src/components/Experts/ExpertsList.tsx
index 59df305..a1f6054 100644
--- a/src/components/Experts/ExpertsList.tsx
+++ b/src/components/Experts/ExpertsList.tsx
@@ -9,6 +9,7 @@ import Image from 'next/image';
import { Link, useRouter } from '../../navigation';
import { ExpertsData, Filter, GeneralFilter } from '../../types/experts';
import { getObjectByFilter, getObjectByAdditionalFilter } from '../../utils/filter';
+import { getDuration, getPrice } from '../../utils/expert';
import { getExpertsList } from '../../actions/experts';
import { CustomPagination } from '../view/CustomPagination';
import { CustomSpin } from '../view/CustomSpin';
@@ -31,8 +32,6 @@ export const ExpertsList = ({
}: ExpertListProps) => {
const searchParams = useSearchParams();
const router = useRouter();
- const getDuration = (value?: any): string => `${value || 0}${locale === 'ru' ? 'мин' : 'min'}`;
- const getPrice = (value?: any): string => `${value || 0}€`;
const [experts, setExperts] = useState();
const [loading, setLoading] = useState(true);
@@ -102,7 +101,7 @@ export const ExpertsList = ({
{`${item.name} ${item?.surname || ''}`}
- {getPrice(item?.sessionCost)} / {getDuration(item?.sessionDuration)}
+ {getPrice(item?.sessionCost)} / {getDuration(locale, item?.sessionDuration)}
diff --git a/src/components/Modals/AuthModal.tsx b/src/components/Modals/AuthModal.tsx
index b2fb836..b7758a0 100644
--- a/src/components/Modals/AuthModal.tsx
+++ b/src/components/Modals/AuthModal.tsx
@@ -3,9 +3,8 @@
import React, { Dispatch, FC, SetStateAction, useEffect } from 'react';
import { usePathname } from 'next/navigation';
import Link from 'next/link';
-import { Modal as AntdModal, Form } from 'antd';
+import { Modal, Form } from 'antd';
import { CloseOutlined } from '@ant-design/icons';
-import { styled } from 'styled-components';
import { RegisterContent, ResetContent, FinishContent, EnterContent } from './authModalContent';
type AuthModalProps = {
@@ -16,25 +15,6 @@ type AuthModalProps = {
updateToken: string | Dispatch
> | undefined;
};
-const Modal = styled(AntdModal)`
- .ant-modal-content {
- border-radius: 24px !important;
- }
-
- .ant-modal-close {
- height: 64px !important;
- width: 64px !important;
- border-radius: 50% !important;
- background: #fff !important;
- top: -32px !important;
- inset-inline-end: -32px !important;
-
- &:active, &:hover {
- background: #fff !important;
- }
- }
-`;
-
export const AuthModal: FC = ({
open,
handleCancel,
@@ -63,6 +43,7 @@ export const AuthModal: FC = ({
return (
void;
+};
+
+export const DeleteAccountModal: FC = ({
+ open,
+ handleCancel
+}) => (
+ }
+ >
+
+
+ To delete your BBUDDY account, please send an email requesting account deletion to the following email address:
+
+
info@bbuddy.expert
+
+ Upon receiving the request, we will delete all existing data associated with your account within 24 hours.
+
+
+
+);
diff --git a/src/styles/_default.scss b/src/styles/_default.scss
index f97b78d..96f03bd 100644
--- a/src/styles/_default.scss
+++ b/src/styles/_default.scss
@@ -586,7 +586,6 @@ a {
line-height: 160%;
}
-//
.card-profile {
display: flex !important;
flex-direction: column;
@@ -598,6 +597,7 @@ a {
&.session {
&__item {
margin: 0 !important;
+ cursor: pointer;
}
}
diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss
new file mode 100644
index 0000000..7e551ed
--- /dev/null
+++ b/src/styles/_modal.scss
@@ -0,0 +1,24 @@
+.b-modal {
+ .ant-modal-content {
+ border-radius: 24px !important;
+ }
+
+ .ant-modal-close {
+ height: 64px !important;
+ width: 64px !important;
+ border-radius: 50% !important;
+ background: #fff !important;
+ top: -32px !important;
+ inset-inline-end: -32px !important;
+
+ &:active, &:hover {
+ background: #fff !important;
+ }
+ }
+
+ &__content {
+ p {
+ margin: 16px 0;
+ }
+ }
+}
diff --git a/src/styles/_pages.scss b/src/styles/_pages.scss
index 22fd774..d3ffa48 100644
--- a/src/styles/_pages.scss
+++ b/src/styles/_pages.scss
@@ -767,9 +767,9 @@
display: inline-flex;
align-items: center;
justify-content: center;
- padding: 6px 8px 4px 8px;
+ padding: 6px 8px 4px;
border-radius: 16px;
- background: #66A5AD;
+ background: #FFBD00;
color: $white;
@include rem(12);
font-style: normal;
diff --git a/src/styles/sessions/_details.scss b/src/styles/sessions/_details.scss
new file mode 100644
index 0000000..39e043b
--- /dev/null
+++ b/src/styles/sessions/_details.scss
@@ -0,0 +1,149 @@
+.card-detail {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+
+ &__expert {
+ border-block-end: 1px solid #C4DFE6;
+ display: flex;
+ gap: 16px;
+ padding: 0 0 16px;
+ }
+
+ &__portrait {
+ width: 140px;
+ height: 140px;
+ border-radius: 16px;
+ border: 2px solid #FFF;
+ background: lightgray 50%;
+ box-shadow: 0 8px 16px 0 rgba(102, 165, 173, 0.32);
+ overflow: hidden;
+ }
+
+ &__inner {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ flex: 1 0 0;
+ }
+
+ &__actions {
+ display: flex;
+ gap: 16px;
+ justify-content: flex-start;
+ }
+
+ &__comments {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+
+ &_header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ &_title {
+ color: #6FB98F;
+ @include rem(18);
+ font-weight: 600;
+ line-height: 150%;
+ }
+
+ &_item {
+ padding: 16px;
+ background: #E4F5FA;
+ border-radius: 0 16px 16px 16px;
+ color: #66A5AD;
+ @include rem(13);
+ font-weight: 500;
+ line-height: 133.333%;
+ }
+ }
+
+ &__header {
+ display: flex;
+ padding-bottom: 8px;
+ align-items: center !important;
+ gap: 16px;
+ align-self: stretch;
+ margin-block-end: 0 !important;
+
+ img {
+ object-fit: cover;
+ width: 100%;
+ height: 100%;
+ display: block;
+ border-radius: 16px;
+ }
+
+ &__name {
+ overflow: hidden;
+ color: #003B46;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ @include rem(18);
+ font-style: normal;
+ font-weight: 600;
+ line-height: 133.333%;
+ }
+
+ &__price {
+ color: #6FB98F;
+ @include rem(15);
+ font-style: normal;
+ font-weight: 600;
+ line-height: 120%;
+
+ span {
+ color: #B7B7B7;
+ }
+ }
+ }
+
+ &__title {
+ color: #003B46;
+ @include rem(18);
+ font-style: normal;
+ font-weight: 600;
+ line-height: 133.333%;
+ }
+
+ &__subtitle {
+ color: #003B46;
+ @include rem(15);
+ font-style: normal;
+ font-weight: 600;
+ line-height: 120%;
+ }
+
+ &__desc {
+ color: #66A5AD;
+ @include rem(13);
+ font-style: normal;
+ font-weight: 500;
+ line-height: 123.077%;
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ }
+
+ &__footer {
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+
+ a {
+ text-decoration: none;
+ color: #FF8A00 !important;
+ @include rem(15);
+ font-style: normal;
+ font-weight: 400;
+ line-height: 160%;
+ display: inline-flex;
+ align-items: center;
+ }
+ }
+}
diff --git a/src/styles/sessions/style.scss b/src/styles/sessions/style.scss
new file mode 100644
index 0000000..34589d5
--- /dev/null
+++ b/src/styles/sessions/style.scss
@@ -0,0 +1 @@
+@import "_details.scss";
diff --git a/src/styles/style.scss b/src/styles/style.scss
index 4f1303e..d00dbd2 100644
--- a/src/styles/style.scss
+++ b/src/styles/style.scss
@@ -14,8 +14,10 @@
@import "_form.scss";
@import "_message.scss";
@import "_auth-modal.scss";
+@import "_modal.scss";
@import "./view/style.scss";
+@import "./sessions/style.scss";
diff --git a/src/types/experts.ts b/src/types/experts.ts
index 20a7417..160db87 100644
--- a/src/types/experts.ts
+++ b/src/types/experts.ts
@@ -1,4 +1,4 @@
-import {Tag, ThemeGroups} from './tags';
+import { Tag, ThemeGroups } from './tags';
export type GeneralFilter = Filter & AdditionalFilter;
diff --git a/src/types/sessions.ts b/src/types/sessions.ts
index 9400c13..f6c507e 100644
--- a/src/types/sessions.ts
+++ b/src/types/sessions.ts
@@ -1,4 +1,6 @@
-type User = {
+import { Language } from './tags';
+
+type PublicUser = {
id: number;
login?: string;
name?: string;
@@ -6,6 +8,88 @@ type User = {
faceImageUrl?: string;
};
+// type User = {
+// "id": 0,
+// "login": "string",
+// "password": "string",
+// "role": "coach",
+// "name": "string",
+// "surname": "string",
+// "phone": "string",
+// "faceImageId": 0,
+// "createdAtUtc": "2024-05-15T14:26:19.310Z",
+// "practiceHours": 0,
+// "supervisionPerYearId": 0,
+// "sessionDuration": 0,
+// "sessionCost": 0,
+// "adminRoles": "admin",
+// "isCoachApproved": true,
+// "isBanned": true,
+// "faceImage": {
+// "id": 0,
+// "userId": 0,
+// "descriptor": "string",
+// "fileType": "string",
+// "contentLength": 0,
+// "state": "active",
+// "createdAtUtc": "2024-05-15T14:26:19.310Z",
+// "unusedSinceUtc": "2024-05-15T14:26:19.310Z"
+// },
+// "coachRating": 0,
+// "isTestMode": true,
+// "beneficiaryName": "string",
+// "beneficiaryIban": "string",
+// "beneficiaryBicOrSwift": "string",
+// "userThemesTags": [
+// {
+// "userId": 0,
+// "themesTagId": 0,
+// "themesTag": {
+// "id": 0,
+// "groupId": 0,
+// "name": "string",
+// "isActive": true,
+// "userId": 0,
+// "group": {
+// "id": 0,
+// "name": "string",
+// "isActive": true,
+// "userId": 0,
+// "tags": [
+// "string"
+// ],
+// "multilangs": [
+// {
+// "parentId": 0,
+// "languageCode": "string",
+// "name": "string"
+// }
+// ]
+// },
+// "userThemesTags": [
+// "string"
+// ],
+// "multilangs": [
+// {
+// "parentId": 0,
+// "languageCode": "string",
+// "name": "string"
+// }
+// ]
+// },
+// "user": "string"
+// }
+// ],
+// "languagesLinks": [
+// {
+// "userId": 0,
+// "languageId": 0,
+// "user": "string",
+// "language": Language
+// }
+// ]
+// };
+
type SessionTag = {
id: number;
groupId?: number;
@@ -21,6 +105,15 @@ export type SessionsFilter = {
endDate?: string;
};
+export type SessionComment = {
+ id: number;
+ createdAtUtc: string;
+ comment?: string;
+ author?: PublicUser;
+ authorId?: number;
+ sessionId?: number;
+};
+
export type Session = {
id: number;
scheduledStartAtUtc?: string;
@@ -37,11 +130,13 @@ export type Session = {
description?: string;
isNeedSupervisor?: boolean;
supervisorComment?: string;
- user?: User;
- coach?: User;
- supervisor?: User;
- clients?: User[];
- themesTags?: SessionTag[]
+ user?: PublicUser;
+ coach?: PublicUser;
+ supervisor?: PublicUser;
+ clients?: PublicUser[];
+ themesTags?: SessionTag[];
+ coachComments?: SessionComment[];
+ clientComments?: SessionComment[];
};
export enum SessionType {
diff --git a/src/utils/expert.ts b/src/utils/expert.ts
new file mode 100644
index 0000000..dd43b97
--- /dev/null
+++ b/src/utils/expert.ts
@@ -0,0 +1,3 @@
+export const getDuration = (locale: string, value?: any): string => `${value || 0}${locale === 'ru' ? 'мин' : 'min'}`;
+
+export const getPrice = (value?: any): string => `${value || 0}€`;