@plusscommunities/pluss-core-web 1.0.5 → 1.0.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 (62) hide show
  1. package/dist/index.cjs.js +7349 -1360
  2. package/dist/index.esm.js +7341 -1358
  3. package/dist/index.umd.js +7346 -1364
  4. package/package.json +5 -3
  5. package/src/actions/AuthActions.js +83 -0
  6. package/src/actions/UsersActions.js +65 -0
  7. package/src/actions/index.js +2 -2
  8. package/src/actions/types.js +9 -9
  9. package/src/analytics.js +73 -0
  10. package/src/apis/analyticsActions.js +49 -0
  11. package/src/apis/authActions.js +58 -0
  12. package/src/apis/fileActions.js +92 -94
  13. package/src/apis/index.js +7 -0
  14. package/src/apis/profileActions.js +133 -0
  15. package/src/apis/stringActions.js +25 -0
  16. package/src/apis/typeActions.js +186 -0
  17. package/src/apis/userActions.js +128 -0
  18. package/src/apis/utilityActions.js +35 -0
  19. package/src/colours.js +16 -16
  20. package/src/components/AnalyticsFilter.js +110 -0
  21. package/src/components/AudienceIncluder.js +174 -0
  22. package/src/components/AudienceSelector.js +549 -0
  23. package/src/components/CheckBox.js +77 -0
  24. package/src/components/DatePicker.js +268 -0
  25. package/src/components/DropdownInput.js +223 -0
  26. package/src/components/FileInput.js +314 -0
  27. package/src/components/ImageInput.js +971 -0
  28. package/src/components/MakerPopup.js +300 -0
  29. package/src/components/OptionsSection.js +64 -0
  30. package/src/components/P60Icon.js +40 -0
  31. package/src/components/ProfilePic.js +35 -0
  32. package/src/components/Reactions.js +77 -0
  33. package/src/components/Tag.js +62 -0
  34. package/src/components/TextFormatPopup.js +54 -0
  35. package/src/components/TimePicker.js +205 -0
  36. package/src/components/UserListing.js +64 -0
  37. package/src/components/index.js +23 -7
  38. package/src/components/svg-icons.json +6 -0
  39. package/src/config.js +10 -0
  40. package/src/helper/HelpDeskWidget.js +52 -0
  41. package/src/helper/api/getUrl.js +15 -0
  42. package/src/helper/api/getUrlParams.js +9 -0
  43. package/src/helper/api/safeReadParams.js +6 -0
  44. package/src/helper/colours.js/getAppColourFromState.js +10 -0
  45. package/src/helper/files/canvasImageUploader.js +159 -0
  46. package/src/helper/files/get1400.js +28 -0
  47. package/src/helper/files/getExtension.js +9 -0
  48. package/src/helper/files/getFileName.js +13 -0
  49. package/src/helper/files/getThumb300.js +32 -0
  50. package/src/helper/files/isVideo.js +8 -0
  51. package/src/{helper.js → helper/helper.js} +19 -130
  52. package/src/helper/index.js +29 -0
  53. package/src/helper/site/getSiteName.js +16 -0
  54. package/src/helper/site/getSiteNameFromRoles.js +12 -0
  55. package/src/helper/storage/readJSONFromStorage.js +9 -0
  56. package/src/helper/storage/setLocalStorage.js +5 -0
  57. package/src/helper/strings/isEmail.js +11 -0
  58. package/src/helper/strings/onlyAlphanumeric.js +8 -0
  59. package/src/helper/strings/randomString.js +10 -0
  60. package/src/helper/strings/toParagraphed.js +17 -0
  61. package/src/index.js +2 -1
  62. package/src/session.js +107 -107
@@ -0,0 +1,300 @@
1
+ import React, { Component } from 'react';
2
+ import { connect } from 'react-redux';
3
+ import { Lottie } from '@crello/react-lottie';
4
+ import _ from 'lodash';
5
+ import { unauthedFunction } from '../session';
6
+ import { Popup } from './Popup';
7
+ import { GenericInput } from './GenericInput';
8
+ import { Text } from './';
9
+ import { Button } from './Button';
10
+ import { DropdownInput } from './DropdownInput';
11
+ import { typeActions, utilityActions } from '../apis';
12
+ import Config from '../config';
13
+ import { COLOUR_BRANDING_APP } from '../colours';
14
+ import { getPluralOptions } from '../helper';
15
+
16
+ class MakerPopup extends Component {
17
+ constructor(props) {
18
+ super(props);
19
+
20
+ this.sizes = [
21
+ { Key: 'A3', Title: 'A3' },
22
+ { Key: 'A4', Title: 'A4' },
23
+ { Key: 'A5', Title: 'A5' },
24
+ ];
25
+ this.formats = [
26
+ { Key: 'pdf', Title: 'PDF' },
27
+ { Key: 'png', Title: 'PNG' },
28
+ { Key: 'jpg', Title: 'JPEG' },
29
+ ];
30
+
31
+ this.state = {
32
+ ...this.props.initialData,
33
+ logo: null,
34
+ colour: null,
35
+ submitting: false,
36
+ loadingBranding: true,
37
+ asset: null,
38
+ selectedSize: 'A4',
39
+ selectedFormat: 'pdf',
40
+ lottieConfig: {
41
+ path: 'https://pluss-prd-media.s3-ap-southeast-2.amazonaws.com/assets/lottie-layout.json',
42
+ loop: true,
43
+ name: 'lottie-layout',
44
+ },
45
+ };
46
+ }
47
+
48
+ componentDidMount() {
49
+ this.getBranding();
50
+ this.getLottieConfig();
51
+ }
52
+
53
+ getBranding() {
54
+ typeActions.getSiteBranding(this.props.auth.site).then((res) => {
55
+ console.log(res.data);
56
+ this.setState({
57
+ loadingBranding: false,
58
+ siteName: res.data.Name,
59
+ colour: res.data.MainBrandingColour || COLOUR_BRANDING_APP,
60
+ logo: res.data.Logo || Config.env.logo,
61
+ headerType: res.data.HeaderType || 'white',
62
+ });
63
+ });
64
+ }
65
+
66
+ getLottieConfig() {
67
+ unauthedFunction({
68
+ method: 'GET',
69
+ url: this.state.lottieConfig.path,
70
+ }).then((res) => {
71
+ this.setState({
72
+ lottieConfig: {
73
+ ...this.state.lottieConfig,
74
+ path: undefined,
75
+ animationData: res.data,
76
+ },
77
+ });
78
+ });
79
+ }
80
+
81
+ handleChange(key, value) {
82
+ this.setState({ [key]: value });
83
+ }
84
+
85
+ selectSize = (size) => {
86
+ this.setState({
87
+ selectedSize: size,
88
+ });
89
+ };
90
+
91
+ getSelectedSizeTitle = () => {
92
+ return _.find(this.sizes, (f) => {
93
+ return f.Key === this.state.selectedSize;
94
+ }).Title;
95
+ };
96
+
97
+ selectFormat = (format) => {
98
+ this.setState({
99
+ selectedFormat: format,
100
+ });
101
+ };
102
+
103
+ getSelectedFormatTitle = () => {
104
+ return _.find(this.formats, (f) => {
105
+ return f.Key === this.state.selectedFormat;
106
+ }).Title;
107
+ };
108
+
109
+ compileData = () => {
110
+ const result = {};
111
+ this.props.inputs.forEach((input) => {
112
+ result[input.key] = this.state[input.key];
113
+ });
114
+ result.colour = this.state.colour;
115
+ result.logo = this.state.logo;
116
+ result.headerType = this.state.headerType;
117
+ return { ...result, ...this.props.requestData };
118
+ };
119
+
120
+ compileRequestData = () => {
121
+ const result = {};
122
+
123
+ if (!this.props.hideFormat) {
124
+ result.format = this.state.selectedFormat;
125
+ }
126
+ if (!this.props.hideSize) {
127
+ result.size = this.state.selectedSize;
128
+ }
129
+ return { ...result, ...this.props.requestData, data: this.compileData() };
130
+ };
131
+
132
+ isReadyToSubmit = () => {
133
+ if (this.state.loadingBranding) {
134
+ return false;
135
+ }
136
+ if (this.state.submitting) {
137
+ return false;
138
+ }
139
+ return true;
140
+ };
141
+
142
+ onGenerateAsset = () => {
143
+ if (!this.isReadyToSubmit()) {
144
+ return;
145
+ }
146
+ const data = this.compileRequestData();
147
+ this.setState({
148
+ submitting: true,
149
+ });
150
+
151
+ utilityActions
152
+ .generateMake(this.props.templateId, data)
153
+ .then((res) => {
154
+ this.setState({
155
+ submitting: false,
156
+ asset: res.data.resultUrl,
157
+ });
158
+ })
159
+ .catch((err) => {
160
+ this.setState({
161
+ submitting: false,
162
+ });
163
+ });
164
+ };
165
+
166
+ downloadAsset = () => {
167
+ window.open(this.state.asset, '_blank');
168
+ };
169
+
170
+ getButtons() {
171
+ if (this.state.submitting) {
172
+ return [];
173
+ }
174
+ if (this.state.asset) {
175
+ return [
176
+ {
177
+ type: 'tertiary',
178
+ onClick: this.props.onClose,
179
+ isActive: true,
180
+ text: 'Done',
181
+ },
182
+ ];
183
+ }
184
+ return [
185
+ {
186
+ type: 'primary',
187
+ onClick: this.onGenerateAsset,
188
+ isActive: this.isReadyToSubmit(),
189
+ text: 'Create',
190
+ },
191
+ {
192
+ type: 'tertiary',
193
+ onClick: this.props.onClose,
194
+ isActive: true,
195
+ text: 'Cancel',
196
+ },
197
+ ];
198
+ }
199
+
200
+ renderInput(input) {
201
+ if (input.type === 'array') {
202
+ return (
203
+ <div className="marginTop-16">
204
+ <Text type="formLabel">{input.title}</Text>
205
+ <Text type="body">
206
+ {this.state[input.key].length} {getPluralOptions(this.state[input.key].length, 'entry', 'entries')}
207
+ </Text>
208
+ </div>
209
+ );
210
+ }
211
+ return (
212
+ <GenericInput
213
+ key={input.key}
214
+ id={`maker_${input.key}`}
215
+ type={input.type}
216
+ label={input.title}
217
+ value={this.state[input.key]}
218
+ onChange={(e) => this.setState({ [input.key]: e.target.value })}
219
+ alwaysShowLabel
220
+ disabled={input.readOnly}
221
+ placeholder={input.placeholder}
222
+ />
223
+ );
224
+ }
225
+
226
+ renderContent() {
227
+ if (this.state.submitting) {
228
+ return (
229
+ <div className="flex flex-column flex-center">
230
+ <Lottie key="lottie-layout" height="260px" width="260px" config={this.state.lottieConfig} />
231
+ <Text type="h3" className="marginTop-16">
232
+ Generating
233
+ </Text>
234
+ </div>
235
+ );
236
+ }
237
+ if (this.state.asset) {
238
+ return (
239
+ <div>
240
+ <Text type="h4">Your file is ready</Text>
241
+ <Button leftIcon="download" buttonType="primary" onClick={this.downloadAsset} isActive className="marginTop-16">
242
+ Download
243
+ </Button>
244
+ </div>
245
+ );
246
+ }
247
+ return (
248
+ <div>
249
+ {!this.props.hideSize && (
250
+ <DropdownInput
251
+ id="size"
252
+ label="Size"
253
+ placeholder="Size"
254
+ value={this.getSelectedSizeTitle()}
255
+ options={this.sizes}
256
+ onSelect={this.selectSize}
257
+ />
258
+ )}
259
+ {!this.props.hideFormat && (
260
+ <DropdownInput
261
+ id="format"
262
+ label="Format"
263
+ placeholder="Format"
264
+ value={this.getSelectedFormatTitle()}
265
+ options={this.formats}
266
+ onSelect={this.selectFormat}
267
+ />
268
+ )}
269
+ {this.props.inputs.map((input) => {
270
+ return this.renderInput(input);
271
+ })}
272
+ </div>
273
+ );
274
+ }
275
+
276
+ render() {
277
+ return (
278
+ <Popup
279
+ title={this.props.title}
280
+ buttons={this.getButtons()}
281
+ onClose={this.props.onClose}
282
+ hasPadding
283
+ minWidth={this.props.minWidth}
284
+ maxWidth={this.props.maxWidth}
285
+ minHeight={this.props.minHeight}
286
+ maxHeight={this.props.maxHeight}
287
+ >
288
+ {this.renderContent()}
289
+ </Popup>
290
+ );
291
+ }
292
+ }
293
+
294
+ const mapStateToProps = (state) => {
295
+ return { auth: state.auth };
296
+ };
297
+
298
+ let exportObj = connect(mapStateToProps, {})(MakerPopup);
299
+
300
+ export { exportObj as MakerPopup };
@@ -0,0 +1,64 @@
1
+ import React, { Component } from 'react';
2
+ import _ from 'lodash';
3
+ import { COLOUR_BRANDING_MAIN } from '../colours';
4
+ import { SVGIcon } from './SVGIcon';
5
+ import { Text } from './';
6
+
7
+ class OptionsSection extends Component {
8
+ getTitle() {
9
+ const selectedOption = _.find(this.props.options, (o) => this.props.selected === o.key);
10
+ if (!selectedOption) {
11
+ return '';
12
+ }
13
+ return selectedOption.text;
14
+ }
15
+
16
+ renderOptionButton(o) {
17
+ const isSelected = this.props.selected === o.key;
18
+ return (
19
+ <div
20
+ className={`optionsButton${isSelected ? ' optionsButton-selected' : ''}`}
21
+ key={o.key}
22
+ onClick={() => {
23
+ this.props.selectOption(o.key);
24
+ }}
25
+ >
26
+ <div className="optionsButton_iconContainer">
27
+ <SVGIcon icon={o.icon} colour={isSelected ? '#fff' : COLOUR_BRANDING_MAIN} />
28
+ </div>
29
+ <Text type="formLabelSmall" className="optionsButton_text">
30
+ {o.text}
31
+ </Text>
32
+ </div>
33
+ );
34
+ }
35
+
36
+ render() {
37
+ return (
38
+ <div className={`optionsSection${this.props.overflowButtons ? ' optionsSection-overflowButtons' : ''}`}>
39
+ <div className="optionsSection_banner">
40
+ <div className="optionsSection_banner_top">
41
+ <Text type="formTitleMedium" className="optionsSection_banner_top_title">
42
+ More Options
43
+ </Text>
44
+ </div>
45
+ <div className="optionsSection_banner_buttonSection">
46
+ {this.props.options.map((o) => {
47
+ return this.renderOptionButton(o);
48
+ })}
49
+ </div>
50
+ </div>
51
+ <div className="optionsContent">
52
+ <div className="optionsContent_box">
53
+ <div className="optionsContent_box_top">
54
+ <Text type="formTitleSmall">{this.getTitle()}</Text>
55
+ </div>
56
+ {this.props.children}
57
+ </div>
58
+ </div>
59
+ </div>
60
+ );
61
+ }
62
+ }
63
+
64
+ export { OptionsSection };
@@ -0,0 +1,40 @@
1
+ import React, { Component } from 'react';
2
+ import _ from 'lodash';
3
+
4
+ class P60Icon extends Component {
5
+ state = {
6
+ doublePaths: ['add-image', 'add-circle', 'facility', 'news'],
7
+ triplePaths: [],
8
+ };
9
+
10
+ renderIconPaths() {
11
+ if (_.includes(this.state.doublePaths, this.props.icon)) {
12
+ return (
13
+ <span>
14
+ <span className="path1" />
15
+ <span className={`path2${this.props.icon !== 'add-image' ? ' text-white' : ''}`} />
16
+ </span>
17
+ );
18
+ }
19
+ if (_.includes(this.state.triplePaths, this.props.icon)) {
20
+ return (
21
+ <span>
22
+ <span className="path1" />
23
+ <span className="path2" />
24
+ <span className="path3" />
25
+ </span>
26
+ );
27
+ }
28
+ return null;
29
+ }
30
+
31
+ render() {
32
+ return (
33
+ <div {...this.props} className={`${this.props.className} p60icon-${this.props.icon}`}>
34
+ {this.renderIconPaths()}
35
+ </div>
36
+ );
37
+ }
38
+ }
39
+
40
+ export { P60Icon };
@@ -0,0 +1,35 @@
1
+ import React, { Component } from 'react';
2
+ import _ from 'lodash';
3
+ import { connect } from 'react-redux';
4
+ import Config from '../config';
5
+ import getAppColourFromState from '../helper/colours.js/getAppColourFromState';
6
+
7
+ class ProfilePicComponent extends Component {
8
+ render() {
9
+ return (
10
+ <div
11
+ className={this.props.className}
12
+ style={{
13
+ width: this.props.size || 30,
14
+ height: this.props.size || 30,
15
+ borderRadius: this.props.size / 2 || 15,
16
+ backgroundColor: this.props.colourBrandingApp,
17
+ backgroundSize: 'cover',
18
+ backgroundPosition: 'center',
19
+ backgroundImage: `url(${!_.isEmpty(this.props.image) ? this.props.image : Config.env.defaultProfileImage})`,
20
+ ...this.props.style,
21
+ }}
22
+ alt="Profile Pic"
23
+ ></div>
24
+ );
25
+ }
26
+ }
27
+
28
+ const mapStateToProps = (state) => {
29
+ return {
30
+ colourBrandingApp: getAppColourFromState(state),
31
+ };
32
+ };
33
+
34
+ const ProfilePic = connect(mapStateToProps, {})(ProfilePicComponent);
35
+ export { ProfilePic };
@@ -0,0 +1,77 @@
1
+ import React, { Component } from 'react';
2
+ import { Text } from './Text';
3
+
4
+ const getReactions = () => {
5
+ return [
6
+ {
7
+ key: 'heart',
8
+ icon: 'https://pluss60-demo-media.s3-ap-southeast-2.amazonaws.com/assets/emojis/heart.png',
9
+ },
10
+ {
11
+ key: 'smile',
12
+ icon: 'https://pluss60-demo-media.s3-ap-southeast-2.amazonaws.com/assets/emojis/smile.png',
13
+ },
14
+ {
15
+ key: 'sad',
16
+ icon: 'https://pluss60-demo-media.s3-ap-southeast-2.amazonaws.com/assets/emojis/sad.png',
17
+ },
18
+ {
19
+ key: 'party',
20
+ icon: 'https://pluss60-demo-media.s3-ap-southeast-2.amazonaws.com/assets/emojis/party.png',
21
+ },
22
+ ];
23
+ };
24
+
25
+ class Reactions extends Component {
26
+ state = {
27
+ reactions: getReactions(),
28
+ };
29
+
30
+ getReaction(key) {
31
+ if (this.props.reactions) {
32
+ if (!this.props.reactions[key]) {
33
+ return 0;
34
+ }
35
+ return this.props.reactions[key];
36
+ }
37
+ if (!this.props.entity) {
38
+ return 0;
39
+ }
40
+ if (!this.props.entity.Reactions) {
41
+ return 0;
42
+ }
43
+ if (!this.props.entity.Reactions[key]) {
44
+ return 0;
45
+ }
46
+ return Object.keys(this.props.entity.Reactions[key]).length;
47
+ }
48
+
49
+ renderReactions() {
50
+ return this.state.reactions.map((r, i) => {
51
+ return (
52
+ <div className="polloverview_section" key={r.key}>
53
+ <img src={r.icon} className="polloverview_iconImage" alt={r.key} />
54
+ <div className="polloverview_right">
55
+ <p className="polloverview_count">{this.getReaction(r.key)}</p>
56
+ </div>
57
+ </div>
58
+ );
59
+ });
60
+ }
61
+
62
+ render() {
63
+ if (this.props.compact) {
64
+ return <div className="compactreactions">{this.renderReactions()}</div>;
65
+ }
66
+ return (
67
+ <div>
68
+ <Text type="formTitleSmall" className="marginBottom-16">
69
+ Reactions
70
+ </Text>
71
+ <div className="polloverview">{this.renderReactions()}</div>
72
+ </div>
73
+ );
74
+ }
75
+ }
76
+
77
+ export { Reactions };