@mindly/ui-components 3.1.4 → 3.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/index.ts +88 -0
  2. package/dist/lib/AppHeader/AppHeader.style.ts +19 -0
  3. package/dist/lib/AppHeader/AppHeader.tsx +23 -0
  4. package/dist/lib/AppHeader/index.ts +1 -0
  5. package/dist/lib/Avatar/Avatar.style.ts +17 -0
  6. package/dist/lib/Avatar/Avatar.tsx +46 -0
  7. package/dist/lib/Avatar/index.ts +1 -0
  8. package/dist/lib/Container/Container.styled.ts +15 -0
  9. package/dist/lib/Container/Container.tsx +15 -0
  10. package/dist/lib/Container/index.ts +1 -0
  11. package/dist/lib/EntryNotFound/EntryNotFound.style.ts +14 -0
  12. package/dist/lib/EntryNotFound/EntryNotFound.tsx +21 -0
  13. package/dist/lib/EntryNotFound/calendar.svg +69 -0
  14. package/dist/lib/EntryNotFound/index.ts +1 -0
  15. package/dist/lib/Filters/ListSelect/ListSelect.style.ts +38 -0
  16. package/dist/lib/Filters/ListSelect/ListSelect.tsx +48 -0
  17. package/dist/lib/Filters/ListSelect/index.ts +1 -0
  18. package/dist/lib/Filters/Range/Range.style.ts +41 -0
  19. package/dist/lib/Filters/Range/Range.tsx +48 -0
  20. package/dist/lib/Filters/Range/index.ts +1 -0
  21. package/dist/lib/Filters/RowSelect/RowSelect.style.ts +30 -0
  22. package/dist/lib/Filters/RowSelect/RowSelect.tsx +38 -0
  23. package/dist/lib/Filters/RowSelect/index.ts +1 -0
  24. package/dist/lib/Filters/Toggle/Toggle.style.ts +14 -0
  25. package/dist/lib/Filters/Toggle/Toggle.tsx +26 -0
  26. package/dist/lib/Filters/Toggle/index.ts +1 -0
  27. package/dist/lib/HorisontalCalendar/HorizontalCalendar.styled.ts +117 -0
  28. package/dist/lib/HorisontalCalendar/HorizontalCalendar.tsx +213 -0
  29. package/dist/lib/HorisontalCalendar/index.ts +1 -0
  30. package/dist/lib/ImageWithFallback/ImageWithFallback.tsx +37 -0
  31. package/dist/lib/LetterAvatar/LetterAvatar.styled.ts +32 -0
  32. package/dist/lib/LetterAvatar/LetterAvatar.tsx +23 -0
  33. package/dist/lib/Modal/Modal.style.ts +12 -0
  34. package/dist/lib/Modal/Modal.tsx +30 -0
  35. package/dist/lib/Modal/index.ts +1 -0
  36. package/dist/lib/ModalCalendar/ModalCalendar.styled.ts +123 -0
  37. package/dist/lib/ModalCalendar/ModalCalendar.tsx +71 -0
  38. package/dist/lib/PersonDateTimeCard/PersonDateTimeCard.styled.ts +36 -0
  39. package/dist/lib/PersonDateTimeCard/PersonDateTimeCard.tsx +32 -0
  40. package/dist/lib/Segment/Segment.style.ts +14 -0
  41. package/dist/lib/Segment/Segment.tsx +29 -0
  42. package/dist/lib/Segment/index.ts +2 -0
  43. package/dist/lib/Segment/types.ts +4 -0
  44. package/dist/lib/SelectImpressionEmoji/ImpressionEmojiEnum.ts +9 -0
  45. package/dist/lib/SelectImpressionEmoji/SelectImpressionEmoji.styled.ts +28 -0
  46. package/dist/lib/SelectImpressionEmoji/SelectImpressionEmoji.tsx +56 -0
  47. package/dist/lib/SelectImpressionEmoji/SelectImpressionEmojiProps.ts +8 -0
  48. package/dist/lib/SelectImpressionEmoji/emojis.ts +9 -0
  49. package/dist/lib/SelectImpressionEmoji/index.tsx +14 -0
  50. package/dist/lib/Theme/global.css +251 -0
  51. package/dist/lib/Theme/mindly_constants.ts +23 -0
  52. package/dist/lib/UsersPsychologistScrollList/UserPsychologistScrollList.styled.ts +61 -0
  53. package/dist/lib/UsersPsychologistScrollList/UsersPsychologistScrollList.tsx +68 -0
  54. package/dist/lib/archived-consultation-card/ArchivedConsultation.test.tsx +9 -0
  55. package/dist/lib/archived-consultation-card/ArchivedConsultationCard.style.ts +72 -0
  56. package/dist/lib/archived-consultation-card/ArchivedConsultationCard.svg +3 -0
  57. package/dist/lib/archived-consultation-card/ArchivedConsultationCard.tsx +61 -0
  58. package/dist/lib/button/Button.style.ts +170 -0
  59. package/dist/lib/button/Button.test.tsx +39 -0
  60. package/dist/lib/button/Button.tsx +47 -0
  61. package/dist/lib/consultation-card/ConsultationCard.style.ts +119 -0
  62. package/dist/lib/consultation-card/ConsultationCard.test.tsx +65 -0
  63. package/dist/lib/consultation-card/ConsultationCard.tsx +155 -0
  64. package/dist/lib/consultation-card/ConsultationCardSkeleton.tsx +114 -0
  65. package/dist/lib/consultation-card/index.ts +2 -0
  66. package/dist/lib/content-card/ContentCard.style.ts +59 -0
  67. package/dist/lib/content-card/ContentCard.test.tsx +29 -0
  68. package/dist/lib/content-card/ContentCard.tsx +81 -0
  69. package/dist/lib/date-picker/DatePicker.style.ts +52 -0
  70. package/dist/lib/date-picker/DatePicker.test.tsx +9 -0
  71. package/dist/lib/date-picker/DatePicker.tsx +59 -0
  72. package/dist/lib/floating-button/FloatingButton.style.ts +21 -0
  73. package/dist/lib/floating-button/FloatingButton.test.tsx +9 -0
  74. package/dist/lib/floating-button/FloatingButton.tsx +29 -0
  75. package/dist/lib/floating-button/floating button.svg +6 -0
  76. package/dist/lib/footer-for-booking/FooterForBooking.style.ts +56 -0
  77. package/dist/lib/footer-for-booking/FooterForBooking.test.tsx +30 -0
  78. package/dist/lib/footer-for-booking/FooterForBooking.tsx +53 -0
  79. package/dist/lib/input/Input.style.ts +37 -0
  80. package/dist/lib/input/Input.test.tsx +21 -0
  81. package/dist/lib/input/Input.tsx +73 -0
  82. package/dist/lib/list-button/ListButton.style.ts +21 -0
  83. package/dist/lib/list-button/ListButton.test.tsx +26 -0
  84. package/dist/lib/list-button/ListButton.tsx +30 -0
  85. package/dist/lib/navigation-bar/NavigationBar.style.ts +81 -0
  86. package/dist/lib/navigation-bar/NavigationBar.test.tsx +15 -0
  87. package/dist/lib/navigation-bar/NavigationBar.tsx +31 -0
  88. package/dist/lib/no-internet-connection/NoInternetConnection.style.ts +26 -0
  89. package/dist/lib/no-internet-connection/NoInternetConnection.svg +10 -0
  90. package/dist/lib/no-internet-connection/NoInternetConnection.test.tsx +9 -0
  91. package/dist/lib/no-internet-connection/NoInternetConnection.tsx +30 -0
  92. package/dist/lib/notes-card-text/NotesCardText.style.ts +14 -0
  93. package/dist/lib/notes-card-text/NotesCardText.tsx +32 -0
  94. package/dist/lib/notes-card-text/index.ts +1 -0
  95. package/dist/lib/notes-editor/NotesEditor.styled.ts +24 -0
  96. package/dist/lib/notes-editor/NotesEditor.tsx +16 -0
  97. package/dist/lib/scroll-tabs/ScrollTabs.style.ts +19 -0
  98. package/dist/lib/scroll-tabs/ScrollTabs.test.tsx +9 -0
  99. package/dist/lib/scroll-tabs/ScrollTabs.tsx +42 -0
  100. package/dist/lib/tab-bar/TabBar.style.tsx +43 -0
  101. package/dist/lib/tab-bar/TabBar.tsx +11 -0
  102. package/dist/lib/therapist-card/TherapistCard.style.ts +104 -0
  103. package/dist/lib/therapist-card/TherapistCard.test.tsx +40 -0
  104. package/dist/lib/therapist-card/TherapistCard.tsx +96 -0
  105. package/dist/lib/therapist-information-component/TherapistInformationComponent.style.ts +40 -0
  106. package/dist/lib/therapist-information-component/TherapistInformationComponent.test.tsx +16 -0
  107. package/dist/lib/therapist-information-component/TherapistInformationComponent.tsx +51 -0
  108. package/dist/lib/toast/index.css +13 -0
  109. package/dist/lib/toast/toast.ts +17 -0
  110. package/dist/lib/userAppTypes.ts +261 -0
  111. package/dist/lib/your-local-time-block/YourLocalTimeBlock.styled.ts +28 -0
  112. package/dist/lib/your-local-time-block/YourLocalTimeBlock.tsx +26 -0
  113. package/dist/react-app-env.d.ts +1 -0
  114. package/dist/svg.d.ts +13 -0
  115. package/package.json +4 -17
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { ConsultationCard, DateTimeType } from './ConsultationCard';
4
+ import { DateTime } from 'luxon';
5
+
6
+ describe('Test consultation card', () => {
7
+ test('Smoke test', () => {
8
+ render(
9
+ <ConsultationCard
10
+ startConsultation={() => undefined}
11
+ handleReschedule={() => undefined}
12
+ handleRefund={() => undefined}
13
+ consultationWith="Елена Шимановская"
14
+ avatar=""
15
+ autorecord
16
+ userTimeZone="America/New_York"
17
+ consultationTime={
18
+ {
19
+ _seconds: DateTime.now().toSeconds(),
20
+ _nanoseconds: 0,
21
+ } as DateTimeType
22
+ }
23
+ />
24
+ );
25
+ });
26
+
27
+ test('Text all handle clicks', () => {
28
+ const startConsultation = jest.fn();
29
+ const handleRefund = jest.fn();
30
+
31
+ render(
32
+ <ConsultationCard
33
+ startConsultation={() => startConsultation()}
34
+ handleReschedule={() => undefined}
35
+ handleRefund={() => handleRefund()}
36
+ consultationWith="Елена Шимановская"
37
+ avatar=""
38
+ autorecord
39
+ userTimeZone="America/New_York"
40
+ consultationTime={
41
+ {
42
+ _seconds: DateTime.now().toSeconds(),
43
+ _nanoseconds: 0,
44
+ } as DateTimeType
45
+ }
46
+ />
47
+ );
48
+
49
+ const refundButton = screen.getByText('Відмінити');
50
+ const startConsultationButton = screen.getByText('Почати консультацію');
51
+ expect(startConsultation).toHaveBeenCalledTimes(0);
52
+ expect(handleRefund).toHaveBeenCalledTimes(0);
53
+
54
+ startConsultationButton.click();
55
+ expect(startConsultation).toHaveBeenCalledTimes(1);
56
+ expect(handleRefund).toHaveBeenCalledTimes(0);
57
+
58
+ expect(startConsultation).toHaveBeenCalledTimes(1);
59
+ expect(handleRefund).toHaveBeenCalledTimes(0);
60
+
61
+ refundButton.click();
62
+ expect(startConsultation).toHaveBeenCalledTimes(1);
63
+ expect(handleRefund).toHaveBeenCalledTimes(1);
64
+ });
65
+ });
@@ -0,0 +1,155 @@
1
+ import React from 'react';
2
+ import {
3
+ ButtonContainer,
4
+ ButtonsContainer,
5
+ Container,
6
+ DividersContainer,
7
+ InfoContainer,
8
+ TextInfo,
9
+ } from './ConsultationCard.style';
10
+ import { Button } from '../button/Button';
11
+ import '../Theme/global.css';
12
+ import { DateTime } from 'luxon';
13
+ import { Avatar } from '../Avatar';
14
+
15
+ export enum DayOfWeeks {
16
+ 'Понеділок' = 1,
17
+ 'Вівторок',
18
+ 'Середа',
19
+ 'Четверг',
20
+ "П'ятниця",
21
+ 'Субота',
22
+ 'Неділя',
23
+ }
24
+
25
+ export type DateTimeType = {
26
+ _nanoseconds: number;
27
+ _seconds: number;
28
+ };
29
+
30
+ export interface ConsultationCardProps {
31
+ /*
32
+ * Here you need to pass a function to start consultation
33
+ */
34
+ startConsultation: (props?: React.SyntheticEvent) => void;
35
+
36
+ /*
37
+ * Function for refund consultation
38
+ */
39
+ handleReschedule: (props?: React.SyntheticEvent) => void;
40
+
41
+ /*
42
+ * Function for refund consultation
43
+ */
44
+ handleRefund: (props?: React.SyntheticEvent) => void;
45
+ handleNotes?: (props?: React.SyntheticEvent) => void;
46
+
47
+ /*
48
+ * Psychologist name and last name
49
+ */
50
+ consultationWith: string;
51
+
52
+ consultationTime: DateTimeType;
53
+ userTimeZone: string;
54
+
55
+ /*
56
+ * Psychologist avatar link
57
+ */
58
+ avatar: string;
59
+ autorecord?: boolean;
60
+
61
+ ['data-container-testid']?: string;
62
+ ['data-start-testid']?: string;
63
+ ['data-reschedule-testid']?: string;
64
+ ['data-refund-testid']?: string;
65
+ }
66
+
67
+ export const ConsultationCard: React.FC<ConsultationCardProps> = ({
68
+ startConsultation,
69
+ handleReschedule,
70
+ handleRefund,
71
+ consultationWith,
72
+ consultationTime,
73
+ userTimeZone,
74
+ avatar,
75
+ autorecord = false,
76
+ ...props
77
+ }) => {
78
+ const time = DateTime.fromSeconds(consultationTime._seconds)
79
+ .setZone(userTimeZone)
80
+ .setLocale('uk-UK');
81
+ const finishedTime = DateTime.fromSeconds(consultationTime._seconds)
82
+ .setZone(userTimeZone)
83
+ .setLocale('uk-UK')
84
+ .plus({ minute: 50 });
85
+ const currentTime = DateTime.now().setZone(userTimeZone).setLocale('uk-UK');
86
+
87
+ return (
88
+ <Container data-testid={props['data-container-testid']}>
89
+ <InfoContainer>
90
+ <TextInfo>
91
+ <h3>Консультація з {consultationWith}</h3>
92
+ {autorecord && <span>Автозапис</span>}
93
+ <h2 className="time">
94
+ {currentTime.toSeconds() <= finishedTime.toSeconds() ? (
95
+ <>
96
+ {DayOfWeeks[time.weekday]}
97
+ <br />
98
+ </>
99
+ ) : (
100
+ <>
101
+ Відбулась <br />
102
+ </>
103
+ )}
104
+ {time.toLocaleString({
105
+ month: 'long',
106
+ day: 'numeric',
107
+ })}{' '}
108
+ о {time.toFormat('HH:mm')}
109
+ </h2>
110
+ </TextInfo>
111
+ <Avatar
112
+ src={avatar}
113
+ dimensions={104}
114
+ firstName={consultationWith}
115
+ className="person-avatar"
116
+ />
117
+ </InfoContainer>
118
+ {currentTime.toSeconds() <= finishedTime.toSeconds() && (
119
+ <ButtonsContainer>
120
+ <Button
121
+ buttonType="primary"
122
+ isDisabled={false}
123
+ data-testid={props['data-start-testid']}
124
+ onClick={startConsultation} // # skipcq JS-0411
125
+ >
126
+ Почати консультацію
127
+ </Button>
128
+ <DividersContainer>
129
+ <div className="divider" />
130
+ <h4>чи</h4>
131
+ <div className="divider" />
132
+ </DividersContainer>
133
+ <ButtonContainer>
134
+ <Button
135
+ buttonType="secondaryCancel"
136
+ isDisabled={false}
137
+ onClick={handleRefund}
138
+ data-testid={props['data-refund-testid']}
139
+ >
140
+ Відмінити
141
+ </Button>
142
+ <Button
143
+ buttonType="secondary"
144
+ isDisabled={false}
145
+ onClick={handleReschedule}
146
+ data-testid={props['data-refund-testid']}
147
+ >
148
+ Перенести
149
+ </Button>
150
+ </ButtonContainer>
151
+ </ButtonsContainer>
152
+ )}
153
+ </Container>
154
+ );
155
+ };
@@ -0,0 +1,114 @@
1
+ import React from 'react';
2
+ import { IonSkeletonText } from '@ionic/react';
3
+ import {
4
+ ButtonContainer,
5
+ Container,
6
+ InfoContainer,
7
+ TextInfo,
8
+ } from './ConsultationCard.style';
9
+
10
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
11
+ export const ConsultationCardSkeleton = () => {
12
+ return (
13
+ <Container>
14
+ <InfoContainer style={{ marginBottom: '16px' }}>
15
+ <TextInfo style={{ padding: '6px 0' }}>
16
+ <IonSkeletonText
17
+ animated
18
+ style={{
19
+ width: '159px',
20
+ height: '10px',
21
+ borderRadius: '4px',
22
+ margin: '0',
23
+ }}
24
+ />
25
+ <IonSkeletonText
26
+ animated
27
+ style={{
28
+ width: '69px',
29
+ height: '10px',
30
+ borderRadius: '4px',
31
+ margin: '0',
32
+ }}
33
+ />
34
+ <IonSkeletonText
35
+ animated
36
+ style={{
37
+ width: '74px',
38
+ height: '14px',
39
+ borderRadius: '4px',
40
+ margin: '0',
41
+ }}
42
+ />
43
+ <IonSkeletonText
44
+ animated
45
+ style={{
46
+ width: '57px',
47
+ height: '11px',
48
+ borderRadius: '4px',
49
+ margin: '0',
50
+ }}
51
+ />
52
+ <IonSkeletonText
53
+ animated
54
+ style={{
55
+ width: '118px',
56
+ height: '11px',
57
+ borderRadius: '4px',
58
+ margin: '0',
59
+ }}
60
+ />
61
+ </TextInfo>
62
+ <IonSkeletonText
63
+ animated
64
+ style={{
65
+ width: '104px',
66
+ height: '104px',
67
+ borderRadius: '8px',
68
+ margin: '0',
69
+ }}
70
+ />
71
+ </InfoContainer>
72
+ <IonSkeletonText
73
+ animated
74
+ style={{
75
+ width: '100%',
76
+ height: '40px',
77
+ borderRadius: '4px',
78
+ margin: '0 0 20px 0',
79
+ }}
80
+ />
81
+ <IonSkeletonText
82
+ animated
83
+ style={{
84
+ width: '100%',
85
+ height: '7px',
86
+ borderRadius: '4px',
87
+ margin: '0 0 17px 0',
88
+ }}
89
+ />
90
+ <ButtonContainer
91
+ style={{ justifyContent: 'space-around', paddingBottom: '13px' }}
92
+ >
93
+ <IonSkeletonText
94
+ animated
95
+ style={{
96
+ width: '68px',
97
+ height: '14px',
98
+ borderRadius: '4px',
99
+ margin: '0',
100
+ }}
101
+ />
102
+ <IonSkeletonText
103
+ animated
104
+ style={{
105
+ width: '76px',
106
+ height: '14px',
107
+ borderRadius: '4px',
108
+ margin: '0',
109
+ }}
110
+ />
111
+ </ButtonContainer>
112
+ </Container>
113
+ );
114
+ };
@@ -0,0 +1,2 @@
1
+ export * from './ConsultationCard';
2
+ export * from './ConsultationCardSkeleton';
@@ -0,0 +1,59 @@
1
+ import styled from 'styled-components';
2
+ import { colorConstants } from '../Theme/mindly_constants';
3
+ import { IonSkeletonText } from '@ionic/react';
4
+
5
+ export const Container = styled.div`
6
+ border: 1px solid ${colorConstants.StrokeGray};
7
+ box-shadow: 0 6px 8px rgba(0, 0, 0, 0.1);
8
+ border-radius: 8px;
9
+ position: relative;
10
+ display: flex;
11
+ flex-direction: column;
12
+ text-align: left;
13
+ `;
14
+
15
+ export const ContentArticle = styled.a`
16
+ width: 100%;
17
+ min-height: 192px;
18
+ max-height: 192px;
19
+ display: block;
20
+
21
+ img {
22
+ border-radius: 8px 8px 0 0;
23
+ width: 100%;
24
+ height: 192px;
25
+ }
26
+ `;
27
+
28
+ export const ContentVideo = styled.iframe`
29
+ width: 100%;
30
+ height: 192px;
31
+ margin: 0;
32
+ padding: 0;
33
+ border-radius: 8px 8px 0 0;
34
+ `;
35
+
36
+ export const Title = styled.h3`
37
+ padding: 16px !important;
38
+ height: 104px;
39
+ color: ${colorConstants.primaryTextColor};
40
+ `;
41
+
42
+ interface SkeletonProps {
43
+ isLoading: boolean;
44
+ }
45
+
46
+ export const SkeletonWrapper = styled.div<SkeletonProps>`
47
+ visibility: ${(props) => (props.isLoading ? 'visible' : 'hidden')};
48
+ position: absolute;
49
+ width: 100%;
50
+ top: 0;
51
+ `;
52
+
53
+ export const Skeleton = styled(IonSkeletonText)`
54
+ height: 192px;
55
+ border-radius: 4px 4px 0 0;
56
+ border: none;
57
+ margin: 0;
58
+ padding: 0;
59
+ `;
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import { ContentCard } from './ContentCard';
4
+
5
+ describe('Test content card', () => {
6
+ test('Smoke test video', () => {
7
+ render(
8
+ <ContentCard
9
+ contentVideo={{
10
+ title: 'КАК ВЫЙТИ ИЗ ДЕПРЕССИИ: СОВЕТЫ ПСИХОЛОГА',
11
+ url: 'watch?v=GnrkrxNL1Ek',
12
+ }}
13
+ />
14
+ );
15
+ });
16
+
17
+ test('Smoke test articles', () => {
18
+ render(
19
+ <ContentCard
20
+ contentArticle={{
21
+ link: 'https://ru.mindly.cc/our-thoughts-our-friends-or-enemies/',
22
+ photoURL:
23
+ 'https://ru.mindly.cc/content/images/size/w2000/2020/10/cover-prepared-1--2-.jpg',
24
+ title: 'Мысли - наши друзья или наши враги?',
25
+ }}
26
+ />
27
+ );
28
+ });
29
+ });
@@ -0,0 +1,81 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ Container,
4
+ ContentArticle,
5
+ ContentVideo,
6
+ Skeleton,
7
+ SkeletonWrapper,
8
+ Title,
9
+ } from './ContentCard.style';
10
+ import '../Theme/global.css';
11
+
12
+ export interface ContentCardProps {
13
+ /*
14
+ * We pass this object when we need to create a card with a video
15
+ * title: video title
16
+ * url: link to video
17
+ */
18
+ contentVideo?: {
19
+ title: string;
20
+ url: string;
21
+ };
22
+
23
+ /*
24
+ * We pass this object when we need to create a card with a article
25
+ * title: article title
26
+ * link: link to article
27
+ * photoURL: link to article preview
28
+ */
29
+ contentArticle?: {
30
+ link: string;
31
+ photoURL: string;
32
+ title: string;
33
+ };
34
+ ['data-testid']?: string;
35
+ }
36
+
37
+ export const ContentCard: React.FC<ContentCardProps> = (props) => {
38
+ const [isLoading, setIsLoading] = useState<boolean>(true);
39
+ const title = props.contentVideo?.title || props.contentArticle?.title;
40
+ const contentJSX = props.contentArticle ? (
41
+ <ContentArticle
42
+ data-testID={props['data-testid']}
43
+ href={props.contentArticle.link}
44
+ >
45
+ <img
46
+ src={props.contentArticle.photoURL}
47
+ alt="article-img"
48
+ onLoad={() => {
49
+ setIsLoading(false);
50
+ }}
51
+ />
52
+ </ContentArticle>
53
+ ) : (
54
+ <ContentVideo
55
+ data-testid={props['data-testid']}
56
+ src={`https://www.youtube.com/embed/${props.contentVideo?.url}`}
57
+ title="YouTube video player"
58
+ frameBorder="0"
59
+ onLoad={() => {
60
+ setIsLoading(false);
61
+ }}
62
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
63
+ allowFullScreen
64
+ />
65
+ );
66
+ return (
67
+ <Container>
68
+ {contentJSX}
69
+ <SkeletonWrapper isLoading={isLoading}>
70
+ <Skeleton animated />
71
+ </SkeletonWrapper>
72
+ <Title className="semiBold">
73
+ {' '}
74
+ {
75
+ // #skipcq
76
+ }
77
+ {title}
78
+ </Title>
79
+ </Container>
80
+ );
81
+ };
@@ -0,0 +1,52 @@
1
+ import styled from 'styled-components';
2
+ import { colorConstants } from '../Theme/mindly_constants';
3
+
4
+ interface ContainerProps {
5
+ isActive: boolean;
6
+ }
7
+
8
+ export const Container = styled.div<ContainerProps>`
9
+ padding: 16px 8px;
10
+ border-radius: 4px;
11
+ border: 1px solid;
12
+ width: 100%;
13
+ min-width: 86px;
14
+ max-height: 108px;
15
+ box-sizing: border-box;
16
+ border-color: ${(props) =>
17
+ props.isActive ? colorConstants.primaryColor : colorConstants.StrokeGray};
18
+ background: ${(props) =>
19
+ props.isActive ? colorConstants.secondaryColor : colorConstants.White};
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+ box-shadow: 0 5px 8px rgba(0, 0, 0, 0.04);
24
+
25
+ h4 {
26
+ margin-bottom: 4px;
27
+ color: ${(props) =>
28
+ props.isActive
29
+ ? colorConstants.primaryColor
30
+ : colorConstants.secondaryTextColor};
31
+ }
32
+
33
+ h1 {
34
+ color: ${(props) =>
35
+ props.isActive
36
+ ? colorConstants.primaryColor
37
+ : colorConstants.primaryTextColor};
38
+ }
39
+
40
+ h5 {
41
+ color: ${(props) =>
42
+ props.isActive
43
+ ? colorConstants.primaryColor
44
+ : colorConstants.secondaryTextColor};
45
+ }
46
+ `;
47
+
48
+ export const WeekDayH1 = styled.h1`
49
+ line-height: 76px;
50
+ font-weight: 700;
51
+ margin: 0;
52
+ `;
@@ -0,0 +1,9 @@
1
+ import { render } from '@testing-library/react';
2
+ import React from 'react';
3
+ import { DatePicker } from './DatePicker';
4
+
5
+ describe('Test date picker', () => {
6
+ test('Smoke test', () => {
7
+ render(<DatePicker day="monday" date="12" isActive month="jan" />);
8
+ });
9
+ });
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import { Container, WeekDayH1 } from './DatePicker.style';
3
+ import '../Theme/global.css';
4
+
5
+ export interface DatePickerProps {
6
+ /*
7
+ * Button type
8
+ */
9
+ type: 'date' | 'weekday';
10
+ /*
11
+ * Weekday. Example: "Пн"
12
+ */
13
+ weekday?: string;
14
+ /*
15
+ * Abbreviated to 2 letters day of week
16
+ */
17
+ day?: string;
18
+
19
+ /*
20
+ * Day of month
21
+ */
22
+ date?: string;
23
+
24
+ /*
25
+ * Abbreviated to 3 letters month name
26
+ */
27
+ month?: string;
28
+
29
+ /*
30
+ * Status defining condition (set isActive on click)
31
+ */
32
+ isActive: boolean;
33
+
34
+ /*
35
+ * Default react onClick
36
+ */
37
+ onClick: (props?: React.SyntheticEvent) => void;
38
+ ['data-testid']?: string;
39
+ }
40
+
41
+ export const DatePicker: React.FC<DatePickerProps> = (props) => {
42
+ return (
43
+ <Container
44
+ data-testid={props['data-testid']}
45
+ isActive={props.isActive}
46
+ onClick={() => props.onClick()}
47
+ >
48
+ {props.type === 'weekday' ? (
49
+ <WeekDayH1>{props.weekday}</WeekDayH1>
50
+ ) : (
51
+ <>
52
+ <h4>{props.day}</h4>
53
+ <h1 className="bold">{props.date}</h1>
54
+ <h5>{props.month}</h5>
55
+ </>
56
+ )}
57
+ </Container>
58
+ );
59
+ };
@@ -0,0 +1,21 @@
1
+ import styled from 'styled-components';
2
+
3
+ interface ContainerProps {
4
+ bottomHeight: number;
5
+ rightWidth: number;
6
+ }
7
+
8
+ export const Container = styled.a<ContainerProps>`
9
+ display: block;
10
+ width: 54px;
11
+ height: 54px;
12
+ position: fixed;
13
+ bottom: ${(props) => props.bottomHeight}px;
14
+ right: ${(props) => props.rightWidth}px;
15
+ z-index: 10000000000000;
16
+
17
+ img {
18
+ background: none;
19
+ border-radius: 50%;
20
+ }
21
+ `;
@@ -0,0 +1,9 @@
1
+ import { render } from '@testing-library/react';
2
+ import React from 'react';
3
+ import { FloatingButton } from './FloatingButton';
4
+
5
+ describe('Test floating button', () => {
6
+ test('Smoke test', () => {
7
+ render(<FloatingButton bottomHeight={20} rightWidth={20} />);
8
+ });
9
+ });
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { Container } from './FloatingButton.style';
3
+ import img from './floating button.svg';
4
+ import '../Theme/global.css';
5
+
6
+ export interface FloatingButtonType {
7
+ /*
8
+ * The position of the button relative to the bottom edge. Conveys a value in pixels
9
+ */
10
+ bottomHeight: number;
11
+
12
+ /*
13
+ * The position of the button relative to the right edge. Conveys a value in pixels
14
+ */
15
+ rightWidth: number;
16
+ ['data-testid']?: string;
17
+ }
18
+
19
+ export const FloatingButton: React.FC<FloatingButtonType> = (props) => {
20
+ return (
21
+ <Container
22
+ href="https://t.me/MindlySupport"
23
+ bottomHeight={props.bottomHeight}
24
+ rightWidth={props.rightWidth}
25
+ >
26
+ <img data-testid={props['data-testid']} src={img} alt="support mindly" />
27
+ </Container>
28
+ );
29
+ };