UNPKG

volto-advanced-variations

Version:
260 lines (247 loc) 8.9 kB
import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; import { flattenToAppURL } from '@plone/volto/helpers'; import { isInternalURL } from '@plone/volto/helpers/Url/Url'; import { Link } from 'react-router-dom'; import moment from 'moment'; import { useIntl } from 'react-intl'; import { getEventCard, getEventDate, getEventTime } from './sharedUtils'; import processItemsForRecurrence from './processItemsForRecurrence'; import RenderImage from './renderImage'; import messages from './messages'; const columnClassMap = { 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', }; const CommonItemRenderer = ({ items, showRecurrence, quote, showTitle: showTitle = true, eventCard, titleTag: TitleTag = 'h2', eventDate, eventTime, eventLocation, showDescription: showDescription = true, effectiveDate, expirationDate, isEditMode, imageSide: imageSide = 'up', imageWidth: imageWidth = 4, howManyColumns: howManyColumns = 1, fetchPriority, slidesToScroll: slidesToScroll = 1, autoPlay: autoPlay = true, autoplaySpeed: autoplaySpeed = 5, creatorauthor, readMore, }) => { const intl = useIntl(); // Process items based on recurrence setting const processedItems = useMemo(() => { if (showRecurrence) { return processItemsForRecurrence(items); // Sort by next recurrence date } return items.map(item => ({ ...item, url: flattenToAppURL(item['@id']), imageSrc: item.image_field ? `${flattenToAppURL(item['@id'])}/@@images/image` : null, })); }, [items, showRecurrence]); const renderMetadata = useMemo(() => { return item => ( <> {eventDate && <span className='start-date'>{getEventDate(item)}</span>} {eventTime && eventDate && <span> | </span>} {eventTime && ( <span className='start-time'> {getEventTime(item) === '12:00 AM - 11:59 PM' ? 'All Day' : getEventTime(item)} </span> )} </> ); }, [eventDate, eventTime]); const renderContent = item => ( <> {quote && ( <> <blockquote>{item.description}</blockquote> <div className='styled-slate right has--align--right align styled'> {item.title || item.id} </div> </> )} {eventCard && getEventCard(item)} {(eventDate || eventTime || eventLocation) && <div className='advancedDatetime'>{renderMetadata(item)}{eventLocation && <span className='location'> | {item.location}</span>}</div>} {showTitle && ( <TitleTag className='threelines'> {imageSide === 'background' ? ( item.title || item.id ) : ( !isEditMode ? ( <Link to={item.url}> {item.title ? item.title : item.id} </Link> ) : ( item.title || item.id ) )} </TitleTag> )} {effectiveDate && <p className='effectiveDate'>{moment(item.effective).format('L')}</p>} {creatorauthor && <p className='author'>{item.Creator}</p>} {expirationDate && <p>Expiration: {moment(item.expires).format('L')}</p>} {showDescription && item.description && <p>{item.description}</p>} {readMore && ( <div className='read-more'> {isInternalURL(item.url) ? ( <Link to={item.url} className='ui button basic' aria-label={intl.formatMessage(messages.readMoreLabel, { title: item.title, })} > {intl.formatMessage(messages.readMoreButton)} </Link> ) : ( <a href={item.url} className='ui button basic' aria-label={intl.formatMessage(messages.readMoreLabel, { title: item.title, })} > {intl.formatMessage(messages.readMoreButton)} </a> )} </div> )} </> ); return ( <div className='fade-in loaded'> {processedItems.map(item => ( <div key={item['@id']} className='ui one column grid advanced-item'> <div className={`column ${imageSide}`}> {imageSide === 'background' ? ( <div className='backgroundimage'> <Link to={item.url} condition={!isEditMode}> <div className='focuspoint'> {item.imageSrc ? ( <Link to={item.url}> <img src={`${item.url}/@@images/${item.image_field}/preview`} // sizes='(min-width: 768px) and (max-width: 991px) 171px, // (min-width: 992px) and (max-width: 1199px) 223px, // (min-width: 1200px) 272px' srcSet={` ${item.url}/@@images/${item.image_field}/mini 200w, ${item.url}/@@images/${item.image_field}/preview 400w, ${item.url}/@@images/${item.image_field}/teaser 500w, ${item.url}/@@images/${item.image_field}/large 700w, ${item.url}/@@images/${item.image_field}/larger 1000w, ${item.url}/@@images/${item.image_field}/great 1200w, ${item.url}/@@images/${item.image_field}/huge 1600w `} alt={item.title || ''} className='ui image listImage' loading={fetchPriority === 'high' ? 'eager' : 'lazy'} fetchpriority={fetchPriority} width='100%' height='auto' style={{ aspectRatio: '16/9' }} /> </Link> ) : ( <RenderImage item={item} isEditMode={isEditMode} howManyColumns={howManyColumns} fetchPriority={fetchPriority} /> )} </div> <div className='info-text'>{renderContent(item)}</div> </Link> </div> ) : ( <div className='ui grid'> {['up', 'left'].includes(imageSide) && ( <div className={`${['up', 'down'].includes(imageSide) ? 'twelve' : columnClassMap[imageWidth] } wide column advancedImage`}> <Link to={item.url}> <RenderImage item={item} isEditMode={isEditMode} howManyColumns={howManyColumns} fetchPriority={fetchPriority} /> </Link> </div> )} <div className={`${['up', 'down'].includes(imageSide) || !['left', 'right'].includes(imageSide) ? 'twelve' : columnClassMap[12 - imageWidth] } wide column`}> {renderContent(item)} </div> {['right', 'down'].includes(imageSide) && ( <div className={`${['up', 'down'].includes(imageSide) ? 'twelve' : columnClassMap[imageWidth] } wide column advancedImage`}> <Link to={item.url}> <RenderImage item={item} isEditMode={isEditMode} howManyColumns={howManyColumns} fetchPriority={fetchPriority} /> </Link> </div> )} </div> )} </div> </div> ))} </div> ); }; CommonItemRenderer.propTypes = { items: PropTypes.arrayOf(PropTypes.object).isRequired, showRecurrence: PropTypes.bool, quote: PropTypes.bool, showTitle: PropTypes.bool, eventCard: PropTypes.bool, titleTag: PropTypes.string, eventDate: PropTypes.bool, eventTime: PropTypes.bool, eventLocation: PropTypes.bool, showDescription: PropTypes.bool, effectiveDate: PropTypes.bool, expirationDate: PropTypes.bool, isEditMode: PropTypes.bool, imageSide: PropTypes.string, imageWidth: PropTypes.number, howManyColumns: PropTypes.number, fetchPriority: PropTypes.string, slidesToScroll: PropTypes.number, autoPlay: PropTypes.bool, autoplaySpeed: PropTypes.number, creatorauthor: PropTypes.bool, readMore: PropTypes.bool, }; export default CommonItemRenderer;