@kitconcept/volto-light-theme 1.0.0-rc.5 → 1.0.0-rc.7

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.
@@ -0,0 +1,301 @@
1
+ /**
2
+ * EventView view component.
3
+ * @module components/theme/View/EventView
4
+ */
5
+
6
+ import React from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import {
9
+ hasBlocksData,
10
+ flattenHTMLToAppURL,
11
+ expandToBackendURL,
12
+ getBlocksFieldname,
13
+ getBlocksLayoutFieldname,
14
+ getBaseUrl,
15
+ } from '@plone/volto/helpers';
16
+ import { Image, Grid, Button } from 'semantic-ui-react';
17
+ import { FormattedDate } from '@plone/volto/components';
18
+ import config from '@plone/volto/registry';
19
+ import { map } from 'lodash';
20
+ import { UniversalLink } from '@plone/volto/components';
21
+ import { FormattedMessage, injectIntl } from 'react-intl';
22
+
23
+ const EventTextfieldView = ({ content }) => (
24
+ <React.Fragment>
25
+ {content.title && <h1 className="documentFirstHeading">{content.title}</h1>}
26
+ {content.description && (
27
+ <p className="documentDescription">{content.description}</p>
28
+ )}
29
+ {content.image && (
30
+ <Image
31
+ className="document-image"
32
+ src={content.image.scales.thumb.download}
33
+ floated="right"
34
+ />
35
+ )}
36
+ {content.text && (
37
+ <div
38
+ dangerouslySetInnerHTML={{
39
+ __html: flattenHTMLToAppURL(content.text.data),
40
+ }}
41
+ />
42
+ )}
43
+ </React.Fragment>
44
+ );
45
+
46
+ /**
47
+ * EventView view component class.
48
+ * @function EventView
49
+ * @params {object} content Content object.
50
+ * @returns {string} Markup of the component.
51
+ */
52
+ const EventView = (props) => {
53
+ const { content } = props;
54
+ const dateOptions = {
55
+ year: 'numeric',
56
+ month: 'long',
57
+ day: 'numeric',
58
+ hour: 'numeric',
59
+ minute: 'numeric',
60
+ };
61
+
62
+ const blocksFieldname = getBlocksFieldname(content);
63
+ const blocksLayoutFieldname = getBlocksLayoutFieldname(content);
64
+
65
+ return (
66
+ <div id="page-document" className="view-wrapper event-view">
67
+ <Grid>
68
+ <Grid.Column width={12}>
69
+ <div>
70
+ <div className="dates">
71
+ {content?.start ? (
72
+ <span className="day">
73
+ <FormattedDate date={content?.start} format={dateOptions} />{' '}
74
+ {props.intl.locale === 'de' ? ' Uhr' : ''}
75
+ </span>
76
+ ) : (
77
+ <span className="day">
78
+ <FormattedMessage id="No date" defaultMessage="No date" />
79
+ </span>
80
+ )}{' '}
81
+ &mdash;&nbsp;
82
+ {content?.end ? (
83
+ <span className="day">
84
+ <FormattedDate date={content?.end} format={dateOptions} />{' '}
85
+ {props.intl.locale === 'de' ? ' Uhr' : ''}
86
+ </span>
87
+ ) : (
88
+ <span className="day">
89
+ <FormattedMessage id="No date" defaultMessage="No date" />
90
+ </span>
91
+ )}
92
+ </div>
93
+ </div>
94
+ {hasBlocksData(content) ? (
95
+ <div>
96
+ {map(content[blocksLayoutFieldname].items, (block) => {
97
+ const Block =
98
+ config.blocks.blocksConfig[
99
+ content[blocksFieldname]?.[block]?.['@type']
100
+ ]?.['view'] || null;
101
+ if (
102
+ config.blocks.blocksConfig[
103
+ content[blocksFieldname]?.[block]?.['@type']
104
+ ]?.['id'] === 'title'
105
+ ) {
106
+ return (
107
+ <>
108
+ <Block
109
+ key={block}
110
+ id={block}
111
+ properties={content}
112
+ data={content[blocksFieldname][block]}
113
+ path={getBaseUrl(props.location?.pathname || '')}
114
+ />
115
+ <Grid>
116
+ <Grid.Row columns={2}>
117
+ <Grid.Column>
118
+ <div>
119
+ <div className="event-title">
120
+ <span className="event-heading">
121
+ <FormattedMessage
122
+ id="Start"
123
+ defaultMessage="Start"
124
+ />
125
+ </span>
126
+ <div className="event-detail">
127
+ {' '}
128
+ <FormattedDate
129
+ date={content?.start}
130
+ format={dateOptions}
131
+ />{' '}
132
+ {props.intl.locale === 'de' ? ' Uhr' : ''}
133
+ </div>
134
+ <div className="separator"></div>
135
+ </div>
136
+ <div className="event-title">
137
+ <span className="event-heading">
138
+ {' '}
139
+ <FormattedMessage
140
+ id="End"
141
+ defaultMessage="End"
142
+ />
143
+ </span>
144
+ <div className="event-detail">
145
+ {' '}
146
+ <FormattedDate
147
+ date={content?.end}
148
+ format={dateOptions}
149
+ />{' '}
150
+ {props.intl.locale === 'de' ? ' Uhr' : ''}
151
+ </div>
152
+ <div className="separator"></div>
153
+ </div>
154
+ <div className="event-title">
155
+ <span className="event-heading">
156
+ {' '}
157
+ <FormattedMessage
158
+ id="Location"
159
+ defaultMessage="Location"
160
+ />
161
+ </span>
162
+ <div className="event-detail">
163
+ {content?.location}
164
+ </div>
165
+ </div>
166
+ </div>
167
+ </Grid.Column>
168
+ <Grid.Column>
169
+ <div>
170
+ <div className="event-title">
171
+ <span className="event-heading">
172
+ <FormattedMessage
173
+ id="Website"
174
+ defaultMessage="Website"
175
+ />
176
+ </span>
177
+ <div className="event-detail">
178
+ <UniversalLink
179
+ className="event-url"
180
+ href={content.event_url}
181
+ >
182
+ {content.event_url}
183
+ </UniversalLink>
184
+ </div>
185
+ <div className="separator"></div>
186
+ </div>
187
+ <div className="event-title">
188
+ <span className="event-heading">
189
+ <FormattedMessage
190
+ id="Contact"
191
+ defaultMessage="Contact"
192
+ />
193
+ </span>
194
+ <div className="event-detail">
195
+ <div>
196
+ {content?.contact_name && (
197
+ <p>{content.contact_name}</p>
198
+ )}
199
+ {content?.contact_email && (
200
+ <p>
201
+ <a
202
+ href={`mailto:${content.contact_email}`}
203
+ >
204
+ {content.contact_email}
205
+ </a>
206
+ </p>
207
+ )}
208
+ {content?.contact_phone && (
209
+ <p>
210
+ <FormattedMessage
211
+ id="Phone"
212
+ defaultMessage="Phone"
213
+ />{' '}
214
+ <a
215
+ href={`tel:${content.contact_phone}`}
216
+ >
217
+ {content.contact_phone}
218
+ </a>
219
+ </p>
220
+ )}
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </Grid.Column>
226
+ <div className="event-button">
227
+ <Button className="event-btn">
228
+ <a
229
+ className="ics-download"
230
+ target="_blank"
231
+ rel="noreferrer"
232
+ href={`${expandToBackendURL(
233
+ content['@id'],
234
+ )}/ics_view`}
235
+ >
236
+ <FormattedMessage
237
+ id="ICS-Download"
238
+ defaultMessage="ICS Download"
239
+ />
240
+ </a>
241
+ </Button>
242
+ </div>
243
+ </Grid.Row>
244
+ </Grid>
245
+ </>
246
+ );
247
+ }
248
+ return Block !== null ? (
249
+ <Block
250
+ key={block}
251
+ id={block}
252
+ properties={content}
253
+ data={content[blocksFieldname][block]}
254
+ path={getBaseUrl(props.location?.pathname || '')}
255
+ />
256
+ ) : (
257
+ <div key={block}>
258
+ <FormattedMessage
259
+ id="Unknown block"
260
+ defaultMessage="Unknown block"
261
+ />
262
+ </div>
263
+ );
264
+ })}
265
+ </div>
266
+ ) : (
267
+ <EventTextfieldView {...props} />
268
+ )}
269
+ </Grid.Column>
270
+ </Grid>
271
+ </div>
272
+ );
273
+ };
274
+
275
+ /**
276
+ * Property types.
277
+ * @property {Object} propTypes Property types.
278
+ * @static
279
+ */
280
+ EventView.propTypes = {
281
+ content: PropTypes.shape({
282
+ title: PropTypes.string,
283
+ description: PropTypes.string,
284
+ text: PropTypes.shape({
285
+ data: PropTypes.string,
286
+ }),
287
+ attendees: PropTypes.arrayOf(PropTypes.string).isRequired,
288
+ contact_email: PropTypes.string,
289
+ contact_name: PropTypes.string,
290
+ contact_phone: PropTypes.string,
291
+ end: PropTypes.string.isRequired,
292
+ event_url: PropTypes.string,
293
+ location: PropTypes.string,
294
+ open_end: PropTypes.bool,
295
+ recurrence: PropTypes.any,
296
+ start: PropTypes.string.isRequired,
297
+ subjects: PropTypes.arrayOf(PropTypes.string).isRequired,
298
+ whole_day: PropTypes.bool,
299
+ }).isRequired,
300
+ };
301
+ export default injectIntl(EventView);
@@ -0,0 +1,132 @@
1
+ /**
2
+ * OVERRIDE FileView.jsx
3
+ * REASON: BFS theme
4
+ * DATE: 2023-07-11
5
+ * DEVELOPER: @iRohitSingh
6
+ */
7
+
8
+ /**
9
+ * File view component.
10
+ * @module components/theme/View/FileView
11
+ */
12
+
13
+ import React from 'react';
14
+ import PropTypes from 'prop-types';
15
+ import { Container } from 'semantic-ui-react';
16
+
17
+ import { flattenToAppURL } from '@plone/volto/helpers';
18
+
19
+ /**
20
+ * File view component class.
21
+ * @function FileView
22
+ * @params {object} content Content object.
23
+ * @returns {string} Markup of the component.
24
+ */
25
+ const FileView = ({ content }) => (
26
+ <Container className="view-wrapper">
27
+ <h1 className="documentFirstHeading">
28
+ {content.title}
29
+ {content.subtitle && ` - ${content.subtitle}`}
30
+ </h1>
31
+ <div className="file-detail">
32
+ {content.description && (
33
+ <p className="documentDescription">{content.description}iRohitSingh</p>
34
+ )}
35
+ {content.file?.download && (
36
+ <>
37
+ <a href={flattenToAppURL(content.file.download)}>
38
+ {content.file.filename}
39
+ </a>{' '}
40
+ <span>
41
+ (
42
+ {(() => {
43
+ switch (content?.file['content-type']) {
44
+ case 'image/jpeg':
45
+ return 'JPEG';
46
+ case 'image/png':
47
+ return 'PNG';
48
+ case 'image/svg+xml':
49
+ return 'SVG';
50
+ case 'image/gif':
51
+ return 'GIF';
52
+ case 'application/pdf':
53
+ return 'PDF';
54
+ case 'application/msexcel':
55
+ return 'XLS';
56
+ case 'application/vnd.ms-excel':
57
+ return 'XLS';
58
+ case 'application/msword':
59
+ return 'DOC';
60
+ case 'application/mspowerpoint':
61
+ return 'PPT';
62
+ case 'audio/mp4':
63
+ return 'MP4';
64
+ case 'application/zip':
65
+ return 'ZIP';
66
+ case 'video/webm':
67
+ return 'WEBM';
68
+ case 'video/x-msvideo':
69
+ return 'AVI';
70
+ case 'video/x-sgi-movie':
71
+ return 'MOVIE';
72
+ case 'text/xml':
73
+ return 'XML';
74
+ case 'text/plain':
75
+ return 'TXT';
76
+ case 'text/calendar':
77
+ return 'ICS';
78
+ case 'image/x-icon':
79
+ return 'ICO';
80
+ case 'image/bmp':
81
+ return 'BMP';
82
+ case 'audio/mpeg':
83
+ return 'MP3';
84
+ case 'audio/wav':
85
+ return 'WAV';
86
+ case 'application/json':
87
+ return 'JSON';
88
+ case 'application/postscript':
89
+ return 'PS';
90
+ case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
91
+ return 'XLSX';
92
+ case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
93
+ return 'DOCX';
94
+ case 'application/xml':
95
+ return 'XML';
96
+ case 'application/mshelp':
97
+ return 'HLP';
98
+ case 'application/gzip':
99
+ return 'GZ';
100
+ default:
101
+ return '';
102
+ }
103
+ })()}{' '}
104
+ /{' '}
105
+ {content.file?.size < 1000000
106
+ ? Math.round(content.file.size / 1000)
107
+ : Math.round(content.file.size / 1000000)}
108
+ {content.file?.size < 1000000 ? 'KB' : 'MB'})
109
+ </span>
110
+ </>
111
+ )}
112
+ </div>
113
+ </Container>
114
+ );
115
+
116
+ /**
117
+ * Property types.
118
+ * @property {Object} propTypes Property types.
119
+ * @static
120
+ */
121
+ FileView.propTypes = {
122
+ content: PropTypes.shape({
123
+ title: PropTypes.string,
124
+ description: PropTypes.string,
125
+ file: PropTypes.shape({
126
+ download: PropTypes.string,
127
+ filename: PropTypes.string,
128
+ }),
129
+ }).isRequired,
130
+ };
131
+
132
+ export default FileView;
package/src/index.js CHANGED
@@ -16,6 +16,7 @@ import { AccordionSchemaEnhancer } from './components/Blocks/Accordion/schema';
16
16
 
17
17
  import gridSVG from './icons/block_icn_grid.svg';
18
18
  import accordionSVG from './icons/block_icn_accordion.svg';
19
+ import EventView from './components/Theme/EventView';
19
20
 
20
21
  const BG_COLORS = [
21
22
  { name: 'transparent', label: 'Transparent' },
@@ -251,6 +252,7 @@ const applyConfig = (config) => {
251
252
  },
252
253
  ],
253
254
  };
255
+ config.views.contentTypesViews.Event = EventView;
254
256
 
255
257
  return config;
256
258
  };
@@ -7,7 +7,7 @@ body.view-contentsview {
7
7
  }
8
8
 
9
9
  #main .breadcrumbs {
10
- padding: 2em 0;
10
+ padding: 20px 0;
11
11
  background-color: $lightgrey;
12
12
 
13
13
  .breadcrumb {
@@ -26,6 +26,10 @@ body.view-contentsview {
26
26
 
27
27
  .home {
28
28
  margin-right: 0.5em;
29
+
30
+ svg {
31
+ margin-bottom: -4px;
32
+ }
29
33
  }
30
34
 
31
35
  .section {
@@ -31,8 +31,117 @@
31
31
  }
32
32
  }
33
33
 
34
+ // Event content type
35
+
36
+ .contenttype-event {
37
+ .documentFirstHeading {
38
+ margin-top: 0px;
39
+ @include default-container-width();
40
+ }
41
+ .blocks-group-wrapper {
42
+ padding-top: 0px;
43
+ }
44
+ .dates {
45
+ margin-top: 40px;
46
+ margin-bottom: 40px;
47
+ @include default-container-width();
48
+
49
+ .day {
50
+ font-size: 18px;
51
+
52
+ font-weight: 700;
53
+ letter-spacing: 1px;
54
+ line-height: 24px;
55
+ text-transform: uppercase;
56
+ }
57
+ }
58
+
59
+ .two.column.row {
60
+ @include default-container-width();
61
+ margin-bottom: 50px;
62
+ }
63
+ }
64
+ .event-title {
65
+ margin-bottom: 25px;
66
+ .event-heading {
67
+ font-family: Inter;
68
+ font-size: 12px;
69
+ font-style: normal;
70
+ font-weight: 700;
71
+ letter-spacing: 1px;
72
+ line-height: 16px;
73
+ text-transform: uppercase;
74
+ }
75
+ .event-detail {
76
+ margin-top: 10px;
77
+ font-size: 24px;
78
+ font-style: normal;
79
+ font-weight: 300;
80
+ line-height: 33px;
81
+ p,
82
+ a {
83
+ margin-top: 10px;
84
+ margin-bottom: 10px;
85
+ font-size: 24px;
86
+ font-style: normal;
87
+ font-weight: 300;
88
+ line-height: 33px;
89
+ }
90
+ }
91
+ .separator {
92
+ width: 170px;
93
+ height: 30px;
94
+ border-right: none;
95
+ border-bottom: 1px solid #000;
96
+ }
97
+ }
98
+
99
+ .event-button {
100
+ display: flex;
101
+ flex-shrink: 0;
102
+ align-items: flex-start;
103
+ padding-top: 50px;
104
+ gap: 10px;
105
+ .button.event-btn {
106
+ padding: 8px 20px;
107
+ border: 1px solid #000;
108
+ background-color: transparent;
109
+ color: #000;
110
+ font-size: 16px;
111
+ font-weight: 900;
112
+ line-height: 20px;
113
+ a {
114
+ color: #000;
115
+ font-size: 16px;
116
+ font-weight: 900;
117
+ line-height: 20px;
118
+ }
119
+ }
120
+ }
121
+
34
122
  .contenttype-file {
35
- .content-area a {
36
- text-decoration: underline;
123
+ .content-area {
124
+ .documentFirstHeading {
125
+ max-width: var(--default-container-width) !important;
126
+ margin-right: auto;
127
+ margin-left: auto;
128
+ }
129
+ .file-detail {
130
+ max-width: var(--narrow-container-width) !important;
131
+ margin-right: auto;
132
+ margin-left: auto;
133
+ .documentDescription {
134
+ padding-top: 40px;
135
+ padding-bottom: 40px;
136
+ margin-bottom: 0;
137
+ }
138
+
139
+ a {
140
+ text-decoration: underline;
141
+ }
142
+ span {
143
+ color: #808080;
144
+ }
145
+ }
37
146
  }
38
147
  }