From 376d875b5cd739ff634df53b4ea64fddf13791db Mon Sep 17 00:00:00 2001 From: Alexander Neumann <140883099+Molochem@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:30:02 +0100 Subject: [PATCH] Revert "Add vlt" --- frontend/package.json | 4 +- .../src/addons/volto-plonede/package.json | 6 +- .../src/components/theme/Style.jsx | 12 + .../src/components/theme/ThemeSwitcher.jsx | 23 + .../theme/EventDetails/EventDetails.jsx | 144 ++ .../volto/components/theme/Footer/Footer.jsx | 159 ++ .../volto/components/theme/Header/Header.jsx | 70 + .../volto/components/theme/Logo/Logo.jsx | 59 + .../volto/components/theme/Logo/Logo.svg | 3 + .../theme/Navigation/Navigation.jsx | 234 +++ .../volto/components/theme/Search/Search.jsx | 382 +++++ .../theme/SearchWidget/SearchWidget.jsx | 92 ++ .../volto/components/theme/View/EventView.jsx | 115 ++ .../src/addons/volto-plonede/src/index.js | 1 - .../volto-plonede/src/theme/custom.less | 3 + .../src/theme/extras/custom.less | 3 + frontend/theme/elements/container.variables | 2 + frontend/theme/extras/blocks.less | 1383 +++++++++++++++++ frontend/theme/extras/custom.less | 609 ++++++++ frontend/theme/extras/custom.overrides | 9 + frontend/theme/theme.config | 2 +- frontend/yarn.lock | 18 - 22 files changed, 3305 insertions(+), 28 deletions(-) create mode 100644 frontend/src/addons/volto-plonede/src/components/theme/Style.jsx create mode 100644 frontend/src/addons/volto-plonede/src/components/theme/ThemeSwitcher.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Footer/Footer.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Header/Header.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.svg create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Navigation/Navigation.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Search/Search.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/SearchWidget/SearchWidget.jsx create mode 100644 frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/View/EventView.jsx create mode 100644 frontend/src/addons/volto-plonede/src/theme/custom.less create mode 100644 frontend/src/addons/volto-plonede/src/theme/extras/custom.less create mode 100644 frontend/theme/elements/container.variables create mode 100644 frontend/theme/extras/blocks.less create mode 100644 frontend/theme/extras/custom.less create mode 100644 frontend/theme/extras/custom.overrides diff --git a/frontend/package.json b/frontend/package.json index c7a7efab..afbeaffe 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -148,7 +148,6 @@ "@kitconcept/volto-export": "1.1.0", "@kitconcept/volto-heading-block": "2.4.0", "@kitconcept/volto-introduction-block": "1.0.0", - "@kitconcept/volto-light-theme": "3.0.0-alpha.1", "@kitconcept/volto-separator-block": "4.0.0", "@kitconcept/volto-slider-block": "5.1.1", "@plone-collective/volto-authomatic": "1.3.0", @@ -178,6 +177,5 @@ "volta": { "node": "16.20.0", "yarn": "3.5.1" - }, - "theme": "@kitconcept/volto-light-theme" + } } diff --git a/frontend/src/addons/volto-plonede/package.json b/frontend/src/addons/volto-plonede/package.json index e831d532..b65123bb 100644 --- a/frontend/src/addons/volto-plonede/package.json +++ b/frontend/src/addons/volto-plonede/package.json @@ -13,11 +13,7 @@ "scripts": { "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon" }, - "addons": [ - "@kitconcept/volto-light-theme" - ], "dependencies": { - "@plone/scripts": "*", - "@kitconcept/volto-light-theme":"3.0.0-alpha.1" + "@plone/scripts": "*" } } diff --git a/frontend/src/addons/volto-plonede/src/components/theme/Style.jsx b/frontend/src/addons/volto-plonede/src/components/theme/Style.jsx new file mode 100644 index 00000000..15e2f3ba --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/components/theme/Style.jsx @@ -0,0 +1,12 @@ +// import React from 'react'; +// import ThemeSwitcher from './ThemeSwitcher'; + +// const Style = () => { +// return ( +// <> +// +// +// ); +// }; + +// export default Style; diff --git a/frontend/src/addons/volto-plonede/src/components/theme/ThemeSwitcher.jsx b/frontend/src/addons/volto-plonede/src/components/theme/ThemeSwitcher.jsx new file mode 100644 index 00000000..ff84a795 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/components/theme/ThemeSwitcher.jsx @@ -0,0 +1,23 @@ +// import { useState } from 'react'; +// import { BodyClass } from '@plone/volto/helpers'; +// import { Icon } from '@plone/volto/components'; +// import Logo from '../../icons/logo.svg'; + +// const themeSwitcher = () => { +// const [darkMode, setDarkMode] = useState(false); +// return ( +// <> +// +//
+// +//
+// +// ); +// }; + +// export default themeSwitcher; diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx new file mode 100644 index 00000000..6089bab8 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx @@ -0,0 +1,144 @@ +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; +import { Segment, Header, List } from 'semantic-ui-react'; +import { + When, + Recurrence, +} from '@plone/volto/components/theme/View/EventDatesInfo'; + +const messages = defineMessages({ + what: { + id: 'event_what', + defaultMessage: 'What', + }, + when: { + id: 'event_when', + defaultMessage: 'When', + }, + allDates: { + id: 'event_alldates', + defaultMessage: 'All dates', + }, + downloadEvent: { + id: 'Download Event', + defaultMessage: 'Download Event', + }, + where: { + id: 'event_where', + defaultMessage: 'Where', + }, + contactName: { + id: 'event_contactname', + defaultMessage: 'Contact Name', + }, + contactPhone: { + id: 'event_contactphone', + defaultMessage: 'Contact Phone', + }, + attendees: { + id: 'event_attendees', + defaultMessage: 'Attendees', + }, + website: { + id: 'event_website', + defaultMessage: 'Website', + }, + visitWebsite: { + id: 'visit_external_website', + defaultMessage: 'Visit external website', + }, +}); + +const EventDetails = ({ content, display_as = 'aside' }) => { + const intl = useIntl(); + return ( + + {content.subjects?.length > 0 && ( + <> +
+ {intl.formatMessage(messages.what)} +
+ + + )} +
+ {intl.formatMessage(messages.when)} +
+ + {content.recurrence && ( + <> +
+ {intl.formatMessage(messages.allDates)} +
+ + + )} + {content.location && ( + <> +
+ {intl.formatMessage(messages.where)} +
+

{content.location}

+ + )} + {content.contact_name && ( + <> +
+ {intl.formatMessage(messages.contactName)} +
+

+ {content.contact_email ? ( + + {content.contact_name} + + ) : ( + content.contact_name + )} +

+ + )} + {content.contact_phone && ( + <> +
+ {intl.formatMessage(messages.contactPhone)} +
+

{content.contact_phone}

+ + )} + {content.attendees?.length > 0 && ( + <> +
+ {intl.formatMessage(messages.attendees)} +
+ + + )} + {content.event_url && ( + <> +
+ {intl.formatMessage(messages.website)} +
+

+ + {intl.formatMessage(messages.visitWebsite)} + +

+ + )} +
+ ); +}; + +export default EventDetails; diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Footer/Footer.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Footer/Footer.jsx new file mode 100644 index 00000000..1ea270d9 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Footer/Footer.jsx @@ -0,0 +1,159 @@ +/** + * Footer component. + * @module components/theme/Footer/Footer + */ + +import React from 'react'; +import { Container, List, Segment } from 'semantic-ui-react'; + +import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; +import { useSelector } from 'react-redux'; +import { UniversalLink, Logo } from '@plone/volto/components'; +import config from '@plone/volto/registry'; + +const messages = defineMessages({ + copyright: { + id: 'Copyright', + defaultMessage: 'Copyright', + }, +}); + +/** + * Component to display the footer. + * @function Footer + * @param {Object} intl Intl object + * @returns {string} Markup of the component + */ +const Footer = ({ intl }) => { + const { settings } = config; + const lang = useSelector((state) => state.intl.locale); + return ( + + + + ® }} + /> + ), + copyright: ( + © + ), + current_year: new Date().getFullYear(), + plonefoundation: ( + + + + ), + }} + />{' '} + + + + ), + }} + /> + + + {/* wrap in div for a11y reasons: listitem role cannot be on the element directly */} +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+
+
+ ); +}; + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +Footer.propTypes = { + /** + * i18n object + */ +}; + +export default injectIntl(Footer); diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Header/Header.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Header/Header.jsx new file mode 100644 index 00000000..a3456dac --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Header/Header.jsx @@ -0,0 +1,70 @@ +/** + * Header component. + * @module components/theme/Header/Header + */ + +import React, { Component } from 'react'; +import { Container, Segment } from 'semantic-ui-react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; + +import { Logo, Navigation, SearchWidget } from '@plone/volto/components'; + +/** + * Header component class. + * @class Header + * @extends Component + */ +class Header extends Component { + /** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ + static propTypes = { + token: PropTypes.string, + pathname: PropTypes.string.isRequired, + }; + + /** + * Default properties. + * @property {Object} defaultProps Default properties. + * @static + */ + static defaultProps = { + token: null, + }; + + /** + * Render method. + * @method render + * @returns {string} Markup for the component. + */ + render() { + return ( + + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+ ); + } +} + +export default connect((state) => ({ + token: state.userSession.token, +}))(Header); diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.jsx new file mode 100644 index 00000000..ef987c75 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.jsx @@ -0,0 +1,59 @@ +/** + * Logo component. + * @module components/theme/Logo/Logo + */ +import { useEffect } from 'react'; +import { Image } from 'semantic-ui-react'; +import { ConditionalLink } from '@plone/volto/components'; +import LogoImage from '@plone/volto/components/theme/Logo/Logo.svg'; +import { useSelector, useDispatch } from 'react-redux'; +import { getNavroot } from '@plone/volto/actions'; +import { + flattenToAppURL, + hasApiExpander, + getBaseUrl, + toPublicURL, +} from '@plone/volto/helpers'; + +/** + * Logo component class. + * @function Logo + * @param {Object} intl Intl object + * @returns {string} Markup of the component. + */ +const Logo = () => { + const pathname = useSelector((state) => state.router.location.pathname); + const site = useSelector((state) => state.site.data); + const navroot = useSelector((state) => state.navroot.data); + const dispatch = useDispatch(); + + useEffect(() => { + if (pathname && !hasApiExpander('navroot', getBaseUrl(pathname))) { + dispatch(getNavroot(getBaseUrl(pathname))); + } + }, [dispatch, pathname]); + + // remove trailing slash + const currentURL = toPublicURL(pathname).replace(/\/$/, ''); + + return ( + + {navroot?.navroot?.title} + + ); +}; + +export default Logo; diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.svg b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.svg new file mode 100644 index 00000000..d3677de1 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Logo/Logo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Navigation/Navigation.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Navigation/Navigation.jsx new file mode 100644 index 00000000..c3ba553a --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Navigation/Navigation.jsx @@ -0,0 +1,234 @@ +/** + * Navigation components. + * @module components/theme/Navigation/Navigation + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { NavLink } from 'react-router-dom'; +import { defineMessages, injectIntl } from 'react-intl'; +import { Menu } from 'semantic-ui-react'; +import cx from 'classnames'; +import { BodyClass, getBaseUrl, hasApiExpander } from '@plone/volto/helpers'; +import config from '@plone/volto/registry'; +import { getNavigation } from '@plone/volto/actions'; +import { CSSTransition } from 'react-transition-group'; +import NavItems from '@plone/volto/components/theme/Navigation/NavItems'; + +const messages = defineMessages({ + closeMobileMenu: { + id: 'Close menu', + defaultMessage: 'Close menu', + }, + openMobileMenu: { + id: 'Open menu', + defaultMessage: 'Open menu', + }, +}); + +/** + * Navigation container class. + * @class Navigation + * @extends Component + */ +class Navigation extends Component { + /** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ + static propTypes = { + getNavigation: PropTypes.func.isRequired, + pathname: PropTypes.string.isRequired, + items: PropTypes.arrayOf( + PropTypes.shape({ + title: PropTypes.string, + url: PropTypes.string, + }), + ).isRequired, + lang: PropTypes.string.isRequired, + }; + + static defaultProps = { + token: null, + }; + + /** + * Constructor + * @method constructor + * @param {Object} props Component properties + * @constructs Navigation + */ + constructor(props) { + super(props); + this.toggleMobileMenu = this.toggleMobileMenu.bind(this); + this.closeMobileMenu = this.closeMobileMenu.bind(this); + this.state = { + isMobileMenuOpen: false, + }; + } + + componentDidMount() { + const { settings } = config; + if (!hasApiExpander('navigation', getBaseUrl(this.props.pathname))) { + this.props.getNavigation( + getBaseUrl(this.props.pathname), + settings.navDepth, + ); + } + } + + /** + * Component will receive props + * @method componentWillReceiveProps + * @param {Object} nextProps Next properties + * @returns {undefined} + */ + UNSAFE_componentWillReceiveProps(nextProps) { + const { settings } = config; + if ( + nextProps.pathname !== this.props.pathname || + nextProps.token !== this.props.token + ) { + if (!hasApiExpander('navigation', getBaseUrl(this.props.pathname))) { + this.props.getNavigation( + getBaseUrl(nextProps.pathname), + settings.navDepth, + ); + } + } + } + + /** + * Toggle mobile menu's open state + * @method toggleMobileMenu + * @returns {undefined} + */ + toggleMobileMenu() { + this.setState({ isMobileMenuOpen: !this.state.isMobileMenuOpen }); + } + + /** + * Close mobile menu + * @method closeMobileMenu + * @returns {undefined} + */ + closeMobileMenu() { + if (!this.state.isMobileMenuOpen) { + return; + } + this.setState({ isMobileMenuOpen: false }); + } + + // hoverExtendedNavigation = () => { + // this.setState({ isExtendedNavigationOpen: true }); + // }; + // leaveExtendedNavigation = () => { + // this.setState({ isExtendedNavigationOpen: false }); + // }; + + /** + * Render method. + * @method render + * @returns {string} Markup for the component. + */ + render() { + return ( + + ); + } +} + +export default compose( + injectIntl, + connect( + (state) => ({ + token: state.userSession.token, + items: state.navigation.items, + lang: state.intl.locale, + }), + { getNavigation }, + ), +)(Navigation); diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Search/Search.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Search/Search.jsx new file mode 100644 index 00000000..4f0acfbb --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/Search/Search.jsx @@ -0,0 +1,382 @@ +/** + * Search component. + * @module components/theme/Search/Search + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { UniversalLink } from '@plone/volto/components'; +import { asyncConnect } from '@plone/volto/helpers'; +import { FormattedMessage } from 'react-intl'; +import { Portal } from 'react-portal'; +import { + Button, + Container, + Pagination, + Header, + Input, + Form, + Dropdown, +} from 'semantic-ui-react'; +import qs from 'query-string'; +import classNames from 'classnames'; +import { defineMessages, injectIntl } from 'react-intl'; +import config from '@plone/volto/registry'; +import { Helmet } from '@plone/volto/helpers'; +import { searchContent } from '@plone/volto/actions'; +import { Toolbar, Icon } from '@plone/volto/components'; + +import paginationLeftSVG from '@plone/volto/icons/left-key.svg'; +import paginationRightSVG from '@plone/volto/icons/right-key.svg'; +import loupeSVG from '@plone/volto/icons/zoom.svg'; + +const messages = defineMessages({ + search: { + id: 'Search', + defaultMessage: 'Search', + }, + searchSite: { + id: 'Search Site', + defaultMessage: 'Search Site', + }, + sortBy: { + id: 'Sort By', + defineMessage: 'Sort By', + }, + relevance: { + id: 'Relevance', + defineMessage: 'Relevance', + }, + alphabetically: { + id: 'Alphabetically', + defineMessage: 'Alphabetically', + }, + dateNewestFirst: { + id: 'Date (newest first)', + defaultMessage: 'Date (newest first)', + }, +}); + +/** + * Search class. + * @class SearchComponent + * @extends Component + */ +class Search extends Component { + /** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ + static propTypes = { + searchContent: PropTypes.func.isRequired, + searchableText: PropTypes.string, + subject: PropTypes.string, + path: PropTypes.string, + items: PropTypes.arrayOf( + PropTypes.shape({ + '@id': PropTypes.string, + '@type': PropTypes.string, + title: PropTypes.string, + description: PropTypes.string, + }), + ), + pathname: PropTypes.string.isRequired, + }; + + /** + * Default properties. + * @property {Object} defaultProps Default properties. + * @static + */ + static defaultProps = { + items: [], + searchableText: null, + subject: null, + path: null, + }; + + constructor(props) { + super(props); + this.state = { currentPage: 1, isClient: false, active: 'relevance' }; + } + + /** + * Component did mount + * @method componentDidMount + * @returns {undefined} + */ + componentDidMount() { + this.doSearch(); + this.setState({ isClient: true }); + } + + /** + * Component will receive props + * @method componentWillReceiveProps + * @param {Object} nextProps Next properties + * @returns {undefined} + */ + UNSAFE_componentWillReceiveProps = (nextProps) => { + if (this.props.location.search !== nextProps.location.search) { + this.doSearch(); + } + }; + + /** + * Search based on the given searchableText, subject and path. + * @method doSearch + * @param {string} searchableText The searchable text string + * @param {string} subject The subject (tag) + * @param {string} path The path to restrict the search to + * @returns {undefined} + */ + + doSearch = () => { + const options = qs.parse(this.props.history.location.search); + this.setState({ currentPage: 1 }); + options['use_site_search_settings'] = 1; + this.props.searchContent('', options); + }; + + handleQueryPaginationChange = (e, { activePage }) => { + const { settings } = config; + window.scrollTo(0, 0); + let options = qs.parse(this.props.history.location.search); + options['use_site_search_settings'] = 1; + + this.setState({ currentPage: activePage }, () => { + this.props.searchContent('', { + ...options, + b_start: (this.state.currentPage - 1) * settings.defaultPageSize, + }); + }); + }; + + onSortChange = (sort_on, sort_order) => { + let options = qs.parse(this.props.history.location.search); + options.sort_on = sort_on; + options.sort_order = sort_order || 'ascending'; + if (sort_on === 'relevance') { + delete options.sort_on; + delete options.sort_order; + } + let searchParams = qs.stringify(options); + this.setState({ currentPage: 1, active: sort_on }, () => { + // eslint-disable-next-line no-restricted-globals + this.props.history.replace({ + search: searchParams, + }); + }); + }; + + /** + * Render method. + * @method render + * @returns {string} Markup for the component. + */ + render() { + const { settings } = config; + return ( + + +
+
+
+
+ + + + +
+
+ + + + { + this.onSortChange('relevance'); + }} + text={this.props.intl.formatMessage(messages.relevance)} + size="tiny" + className={classNames('button-sort', { + 'button-active': this.state.active === 'relevance', + })} + /> + + { + this.onSortChange('sortable_title'); + }} + text={this.props.intl.formatMessage( + messages.alphabetically, + )} + size="tiny" + className={classNames('button-sort', { + 'button-active': + this.state.active === 'sortable_title', + })} + /> + + { + this.onSortChange('effective', 'reverse'); + }} + text={this.props.intl.formatMessage( + messages.dateNewestFirst, + )} + size="tiny" + className={classNames('button-sort', { + 'button-active': this.state.active === 'effective', + })} + /> + + + +
+ {this.props.search?.items_total > 0 ? ( +
+ {this.props.search.items_total}{' '} + +
+ ) : ( +
+ +
+ )} +
+
+ {this.props.items.map((item) => ( +
+

+ + {item.title} + +

+ {item.description && ( +
+ {item.description} +
+ )} +
+ + + +
+
+
+ ))} + + {this.props.search?.batching && ( +
+ , + icon: true, + 'aria-disabled': !this.props.search.batching.prev, + className: !this.props.search.batching.prev + ? 'disabled' + : null, + }} + nextItem={{ + content: , + icon: true, + 'aria-disabled': !this.props.search.batching.next, + className: !this.props.search.batching.next + ? 'disabled' + : null, + }} + /> +
+ )} +
+
+
+ {this.state.isClient && ( + + } + /> + + )} +
+ ); + } +} + +export const __test__ = compose( + injectIntl, + connect( + (state, props) => ({ + items: state.search.items, + searchableText: qs.parse(props.history.location.search).SearchableText, + pathname: props.history.location.pathname, + }), + { searchContent }, + ), +)(Search); + +export default compose( + injectIntl, + connect( + (state, props) => ({ + items: state.search.items, + searchableText: qs.parse(props.history.location.search).SearchableText, + pathname: props.location.pathname, + }), + { searchContent }, + ), + asyncConnect([ + { + key: 'search', + promise: ({ location, store: { dispatch } }) => + dispatch( + searchContent('', { + ...qs.parse(location.search), + use_site_search_settings: 1, + }), + ), + }, + ]), +)(Search); diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/SearchWidget/SearchWidget.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/SearchWidget/SearchWidget.jsx new file mode 100644 index 00000000..a04e9897 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/SearchWidget/SearchWidget.jsx @@ -0,0 +1,92 @@ +/** + * Search widget component. + * @module components/theme/SearchWidget/SearchWidget + */ + +import React, { Component } from 'react'; +import { withRouter } from 'react-router-dom'; +import { Form } from 'semantic-ui-react'; +import { compose } from 'redux'; +import { PropTypes } from 'prop-types'; +import { injectIntl } from 'react-intl'; + +import { Icon } from '@plone/volto/components'; +import zoomSVG from '@plone/volto/icons/zoom.svg'; + +/** + * SearchWidget component class. + * @class SearchWidget + * @extends Component + */ +class SearchWidget extends Component { + /** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ + static propTypes = { + pathname: PropTypes.string, + }; + + /** + * Constructor + * @method constructor + * @param {Object} props Component properties + * @constructs WysiwygEditor + */ + constructor(props) { + super(props); + this.onChangeText = this.onChangeText.bind(this); + this.onSubmit = this.onSubmit.bind(this); + this.state = { + text: '', + }; + } + + /** + * On change text + * @method onChangeText + * @param {object} event Event object. + * @param {string} value Text value. + * @returns {undefined} + */ + onChangeText(event, { value }) { + this.setState({ + text: value, + }); + } + + /** + * Submit handler + * @method onSubmit + * @param {event} event Event object. + * @returns {undefined} + */ + onSubmit(event) { + this.props.history.push(`/search`); + // reset input value + this.setState({ + text: '', + }); + event.preventDefault(); + } + + /** + * Render method. + * @method render + * @returns {string} Markup for the component. + */ + render() { + return ( +
+ + + +
+ ); + } +} + +export default compose(withRouter, injectIntl)(SearchWidget); diff --git a/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/View/EventView.jsx b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/View/EventView.jsx new file mode 100644 index 00000000..ccec7c5f --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/customizations/volto/components/theme/View/EventView.jsx @@ -0,0 +1,115 @@ +/** + * EventView view component. + * @module components/theme/View/EventView + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import { hasBlocksData, flattenHTMLToAppURL } from '@plone/volto/helpers'; +import { Image } from 'semantic-ui-react'; +import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks'; +import { EventDetails } from '@plone/volto/components'; + +const EventTextfieldView = ({ content }) => ( + + {content.title &&

{content.title}

} + {content.description && ( +

{content.description}

+ )} + {content.image && ( + + )} + {content.text && ( +
+ )} + +); + +/** + * EventView view component class. + * @function EventView + * @params {object} content Content object. + * @returns {string} Markup of the component. + */ +const EventView = (props) => { + const { content } = props; + + return ( +
+
+ +
+
+ {hasBlocksData(content) ? ( + + ) : ( + + )} +
+
+ {hasBlocksData(content) ? ( + <> + + + + + ) : ( + + )} +
+
+ ); +}; + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +EventView.propTypes = { + content: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + text: PropTypes.shape({ + data: PropTypes.string, + }), + attendees: PropTypes.arrayOf(PropTypes.string).isRequired, + contact_email: PropTypes.string, + contact_name: PropTypes.string, + contact_phone: PropTypes.string, + end: PropTypes.string.isRequired, + event_url: PropTypes.string, + location: PropTypes.string, + open_end: PropTypes.bool, + recurrence: PropTypes.any, + start: PropTypes.string.isRequired, + subjects: PropTypes.arrayOf(PropTypes.string).isRequired, + whole_day: PropTypes.bool, + }).isRequired, +}; + +export default EventView; diff --git a/frontend/src/addons/volto-plonede/src/index.js b/frontend/src/addons/volto-plonede/src/index.js index 8f08000f..fc6dd80a 100644 --- a/frontend/src/addons/volto-plonede/src/index.js +++ b/frontend/src/addons/volto-plonede/src/index.js @@ -57,7 +57,6 @@ const applyConfig = (config) => { navDepth: 2, matomoSiteId: '11', matomoUrlBase: 'https://stats.plone.de/', - enableFatMenu: false, }; /* Teaser Block */ diff --git a/frontend/src/addons/volto-plonede/src/theme/custom.less b/frontend/src/addons/volto-plonede/src/theme/custom.less new file mode 100644 index 00000000..41eaabd5 --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/theme/custom.less @@ -0,0 +1,3 @@ +#navigation .item { + border: 2px solid blue; +} diff --git a/frontend/src/addons/volto-plonede/src/theme/extras/custom.less b/frontend/src/addons/volto-plonede/src/theme/extras/custom.less new file mode 100644 index 00000000..2b89fe6a --- /dev/null +++ b/frontend/src/addons/volto-plonede/src/theme/extras/custom.less @@ -0,0 +1,3 @@ +#navigation .item { + color: red; +} diff --git a/frontend/theme/elements/container.variables b/frontend/theme/elements/container.variables new file mode 100644 index 00000000..1724a933 --- /dev/null +++ b/frontend/theme/elements/container.variables @@ -0,0 +1,2 @@ +@computerWidth: 940px; +@largeMonitorWidth: 1440px; diff --git a/frontend/theme/extras/blocks.less b/frontend/theme/extras/blocks.less new file mode 100644 index 00000000..b4194fc7 --- /dev/null +++ b/frontend/theme/extras/blocks.less @@ -0,0 +1,1383 @@ +#page-document .block.next--is--same--block-type:not(.slate) { + padding-bottom: 0 !important; + margin-bottom: -1rem; +} + +#page-document .block.has--backgroundColor--grey:not(.slate):not(.separator) { + padding-bottom: 25px; + margin-bottom: 0 !important; +} + +.block:not(.has--backgroundColor--grey):not(.slider):not(.slate):not(.separator) { + padding-bottom: 0 !important; + margin-bottom: 25px; +} + +.public-DraftEditor-content[contenteditable='true'] { + caret-color: var(--primary-black); +} + +/* Slate Block */ + +#page-document .ui.container .event-view .block.slate p { + max-width: var(--text-container-width); +} + +#page-document > .block.slate { + margin-bottom: 0; +} + +#page-document .block.slate p, +#page-document .block.slate ol li, +#page-document .block.slate ul li { + max-width: var(--text-container-width); + margin-right: auto; + margin-left: auto; + color: var(--primary-grey); + font-weight: 300; + + &::marker { + color: @plone-blue; + } +} + +#page-document .block.slate.has--backgroundColor--grey p, +#page-document .block.slate.has--backgroundColor--grey ol, +#page-document .block.slate.has--backgroundColor--grey ul { + padding-bottom: 25px; + margin-top: 0; + margin-bottom: 0; +} + +b, +strong { + color: var(--primary-black); + font-weight: 600; +} + +.block-editor-slate p, +.block-editor-slate ol li, +.block-editor-slate ul li { + max-width: var(--text-container-width); + margin-right: auto; + margin-left: auto; + color: var(--primary-grey); + + &::marker { + color: @plone-blue; + } +} + +/* Heading */ +#page-document .block.slate.has--backgroundColor--grey h2, +#page-document .block.slate.has--backgroundColor--grey h3 { + max-width: var(--text-container-width); + padding-top: 50px; + padding-bottom: 25px; + margin: 0 auto 0 auto; +} + +#page-document .block.slate:not(.has--backgroundColor--grey) h2, +#page-document .block.slate:not(.has--backgroundColor--grey) h3 { + max-width: var(--text-container-width); + margin-top: 50px; + margin-right: auto; + margin-bottom: 25px; + margin-left: auto; +} + +h2, +h3:not(.listing-body h3) { + font-weight: 600; +} + +h2 { + font-size: 2.2rem; + font-style: normal; + line-height: 36px; +} + +h3 { + font-size: 1.8rem; + font-style: normal; + line-height: 30px; +} + +h1 a.anchor svg, +h2 a.anchor svg, +h3 a.anchor svg, +h4 a.anchor svg { + width: 1ch; + padding-bottom: 100%; +} + +.block-editor-slate h2, +.block-editor-slate h3 { + max-width: var(--text-container-width); + margin-right: auto !important; + margin-left: auto !important; +} + +/* Blockquote */ +blockquote { + position: relative; + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + color: var(--primary-grey); + font-size: 29px; + font-style: italic; + font-weight: 300; + line-height: 1.5; +} + +/* Headings */ + +/* Document Heading */ +#page-document h1.documentFirstHeading { + max-width: var(--full-container-width); + margin-right: auto; + margin-left: auto; +} + +.documentFirstHeading, +.documentFirstHeading::before { + border-bottom: none; +} + +.documentFirstHeading { + margin-bottom: 55px; + font-size: 4rem; + font-style: normal; + font-weight: 600; + -webkit-hyphens: auto; + hyphens: auto; + line-height: 72px; + overflow-wrap: break-word; + word-break: break-word; + word-wrap: break-word; + + @media only screen and (max-width: @largestTabletScreen) { + margin-bottom: 50px; + font-size: 3.2rem; + line-height: 58px; + } +} + +/* Heading Block*/ +.block.heading { + margin-bottom: 0; + + &.align-left { + .heading-wrapper { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + h2.heading { + padding-top: 100px; + padding-bottom: 75px; + margin: 0; + color: #000; + font-size: 2.5rem; + font-style: normal; + font-weight: 300; + line-height: 3rem; + text-align: left; + + @media only screen and (max-width: @largestMobileScreen) { + padding-top: 75px; + padding-bottom: 50px; + margin: 0; + font-size: 2rem; + line-height: 2.5rem; + } + } + } + } + + &.align-center { + .heading-wrapper { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + h2 { + padding-top: 100px; + padding-bottom: 75px; + margin: 0; + font-size: 2.5rem; + font-style: normal; + font-weight: 300; + line-height: 3rem; + text-align: center; + + @media only screen and (max-width: @largestMobileScreen) { + padding-top: 75px; + padding-bottom: 50px; + margin: 0; + font-size: 2rem; + line-height: 2.5rem; + } + } + } + } + + &.align-right { + .heading-wrapper { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + h2 { + padding-top: 100px; + padding-bottom: 75px; + margin: 0; + font-size: 2.5rem; + font-style: normal; + font-weight: 300; + line-height: 3rem; + text-align: right; + + @media only screen and (max-width: @largestMobileScreen) { + padding-top: 75px; + padding-bottom: 50px; + margin: 0; + font-size: 2rem; + line-height: 2.5rem; + } + } + } + } +} + +.block-editor-heading h2, +.block-editor-heading h2.heading { + padding-top: 100px; + padding-bottom: 75px; + margin: 0 !important; + font-size: 2.5rem; + font-style: normal; + font-weight: 300; + line-height: 3rem; +} + +/* Button Block */ + +.block.__button .ui.button { + margin: 0; +} + +.block.__button .align-left { + text-align: left; +} + +.block.__button .align-right { + text-align: right; +} + +.block.__button .align-center { + text-align: center; +} + +.block.__button .align-full button { + width: 100%; +} + +.block.__button { + text-align: unset; + + &.has--align--center { + .container { + max-width: var(--text-container-width); + margin-right: auto; + margin-left: auto; + } + } + + &.has--align--wide { + .container { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + } + } +} + +.block.__button:not(.has--backgroundColor--grey) .button.container { + margin-top: 75px; + margin-bottom: 100px; +} + +.block.__button.has--backgroundColor--grey { + padding-bottom: 0 !important; +} + +.block.__button.has--backgroundColor--grey .button.container { + padding-top: 75px; + padding-bottom: 100px; +} + +/* Hero Block */ + +.block.hero .hero-body { + display: block; + background: transparent; + + @media only screen and (max-width: @largestMobileScreen) { + padding: 1rem; + } + + h1 { + color: var(--primary-black); + } + + p { + color: var(--primary-grey); + } + + button { + margin: 1rem 0 0; + } +} + +.block.hero .hero-image { + @media only screen and (max-width: @largestMobileScreen) { + width: 100%; + max-width: 620px; + margin: auto; + } +} + +.block.hero { + z-index: 0; + + &.align-left { + .block-inner-wrapper { + flex-direction: row; + } + } + + &.align-right { + .block-inner-wrapper { + flex-direction: row-reverse; + } + } + + .block-inner-wrapper { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + background-color: #ececec; + + @media only screen and (max-width: @largestMobileScreen) { + display: flex; + flex-direction: column !important; + } + } +} + +.block-editor-hero .hero-body { + display: block; + background: transparent; + + .description-editor { + color: var(--primary-grey); + } +} + +.block-editor-hero .hero-image { + object-fit: cover; +} + +.block-editor-hero .align-right .toolbar { + left: 75%; +} + +.block-editor-hero .align-right .block-inner-wrapper { + flex-direction: row-reverse; +} + +/* Image Block */ + +.block.image { + margin: 0; + + &.align.left, + &.align.right { + max-width: var(--default-container-width); + margin: 50px auto 0 auto; + + &.medium { + max-width: var(--text-container-width); + } + + &.small { + max-width: var(--text-container-width); + } + } + + &.align.left.has--backgroundColor--grey, + &.align.right.has--backgroundColor--grey { + margin-top: 0; + + figure { + padding-top: 50px - 25px; + } + } + + figure { + img { + max-width: 100% !important; + height: auto; + object-fit: contain; + } + + &.right { + margin-bottom: 16px; + margin-left: 2rem; + float: right; + + img { + margin-right: 0 !important; + margin-bottom: 0px; + margin-left: 0 !important; + float: none; + object-fit: contain; + object-position: right; + } + } + + &.left { + margin-right: 2rem; + margin-bottom: 16px; + float: left; + + img { + margin-right: 0 !important; + margin-bottom: 0px; + float: none; + object-fit: contain; + object-position: left; + } + } + + &.left, + &.right { + &.large { + width: 50%; + height: auto; + + @media only screen and (max-width: 768px) { + width: 100%; + } + } + + &.medium { + width: 50%; + height: auto; + @media only screen and (max-width: 768px) { + width: 100%; + } + } + + &.small { + width: 25%; + height: auto; + @media only screen and (max-width: 768px) { + width: 100%; + } + } + } + + &.center { + max-width: var(--text-container-width) !important; + margin-right: auto; + margin-left: auto; + object-fit: cover; + + img { + height: auto; + margin-right: initial; + margin-left: initial; + } + + &.large { + figcaption { + text-align: start; + } + } + } + + &.wide { + max-width: 940px !important; + margin-right: auto; + margin-left: auto; + object-fit: cover; + + img { + height: auto; + margin-right: initial; + margin-left: initial; + } + + &.large { + figcaption { + text-align: start; + } + } + } + } + + img { + max-width: 100% !important; + height: auto; + } +} + +/* figure */ +figure { + display: flex; + flex-direction: column; + margin: 0; +} + +/* image/video captions */ +figcaption { + margin: 0 0 9px 0; + color: var(--primary-grey); + font-size: 14px; + font-weight: 300; + line-height: 18px; + text-align: left; + white-space: initial; + + .title { + margin-top: 25px; + margin-bottom: 10px; + color: var(--primary-black); + font-weight: 700; + } + + .credits { + margin-bottom: 10px; + -webkit-font-smoothing: anitaliased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + + p { + display: inline; + color: inherit; + line-height: inherit; + } + + a { + color: @plone-blue; + } + } +} + +/* Video Block */ + +#page-document .block.video.align.left, +.block.video.align.left, +#page-document .block.video.align.right, +.block.video.align.right { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +#page-document .block.video.align.center figure, +.block.video.align.center figure { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +.block.video { + .figure { + width: 100%; + } + + &.align.left.has--backgroundColor--grey figure, + &.align.right.has--backgroundColor--grey figure { + padding-top: 25px; + } + + &.align.left.has--backgroundColor--grey, + &.align.right.has--backgroundColor--grey { + margin-top: 0px; + margin-bottom: 0px; + } + + &.align.left, + &.align.right { + margin-top: 50px; + + figure.video-inner { + @media only screen and (max-width: @tabletBreakpoint) { + width: 100%; + } + } + + img { + margin: 0 !important; + } + } +} + +.block.video, +.block.imageslider, +.block.maps { + .ui.message.cookie-consent-buttons { + position: absolute; + z-index: 10; + bottom: 0; + display: flex; + height: 100%; + flex-direction: row; + align-items: flex-end; + background: transparent; + + background: linear-gradient( + 180deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.99) 100% + ); + @media only screen and (max-width: @tabletBreakpoint) { + flex-flow: column; + align-items: flex-end; + justify-content: space-between; + background-color: @black; + } + + p { + width: 70%; + padding-right: 15px; + margin-bottom: 0; + color: @white; + text-align: left; + @media only screen and (max-width: @tabletBreakpoint) { + width: 100%; + padding-right: 0px; + font-size: 14px; + line-height: 20px; + } + + a { + color: @white; + text-decoration: underline; + + &[href^="https://"]:not([href^="https://plone"]):after + { + content: '' + url("data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='external-link-alt' class='svg-inline--fa fa-external-link-alt fa-w-16' role='img' xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 512 512'%3E%3Cpath fill='white' d='M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z'%3E%3C/path%3E%3C/svg%3E"); + } + } + } + + .ui.button { + width: 30%; + // border: 1px solid @black; + background: @white; + border-radius: 0; + color: var(--primary-black); + font-size: 14px; + @media only screen and (max-width: @tabletBreakpoint) { + width: 50%; + font-size: 12px; + } + } + } + + .cookie-consent-overlay { + position: relative; + height: 100%; + + img { + display: block; + width: 100%; + } + } +} + +/* Maps Block */ + +.block.maps.align.left .maps-inner, +.block.maps.align.right .maps-inner, +.block.maps.align.center .maps-inner { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +.block.maps.align { + &.left, + &.right { + iframe { + width: 472px; + height: 265px; + + @media only screen and (max-width: @tabletBreakpoint) { + width: 100%; + height: 100%; + } + } + } + + &.full { + height: 45vh; + + .maps-inner.full-width { + left: 0; + max-width: var(--full-container-width) !important; + margin-right: auto !important; + margin-left: auto !important; + } + } +} + +/* Introduction */ + +.block.introduction:not(.has--backgroundColor--grey) { + margin-top: 25px; +} + +.block.introduction.has--backgroundColor--grey { + padding-top: 25px; +} + +.block.introduction .block-container { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + p { + max-width: var(--default-container-width); + margin-right: auto; + margin-bottom: 0; + margin-left: auto; + font-size: 24px; + font-weight: 300; + line-height: 34px; + } +} + +.block-editor-introduction .block.introduction { + p { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + font-size: 24px; + font-weight: 300; + line-height: 34px; + } +} + +/* Quote Block */ + +.block.quote { + .inner-wrapper { + max-width: 940px; + min-height: 200px; + padding: 1rem; + padding-top: calc(100px + 1em); + margin-right: auto; + margin-left: auto; + } + + &.align-left { + border-top: none; + + .inner-wrapper { + display: flex; + padding: 4.572rem 3rem 4.144rem; + + .quote-image-wrapper { + width: unset; + margin-right: 2rem; + + img.quote-image { + width: 180px; + height: 180px; + margin-top: 0; + } + } + + .quotation { + max-width: 1000px; + margin-top: 0; + margin-left: 0; + + .quote-text { + font-size: 1.66667em; + } + } + } + + &.white { + border-top: 1px solid #d5dde2; + border-bottom: 1px solid #d5dde2; + } + } + + &.no-image { + .inner-wrapper { + padding: 1rem; + } + } + + &.lightGrey .inner-wrapper { + background: #d5dde2; + } + + &.white { + background: #fff; + + .quotation .quote-text { + .quotation-mark { + color: #d5dde2; + } + } + } + + .quote-image-wrapper { + width: 100%; + text-align: center; + + .quote-image { + width: 150px; + height: 150px; + margin-top: -75px; + border-radius: 50%; + object-fit: cover; + } + } + + .quotation { + max-width: 940px; + margin: 20px auto 0; + + .quote-text { + // color: var(--primary-black); + font-family: 'Roboto Slab'; + font-size: 2em; + + .quotation-mark { + height: 70px; + margin-right: 20px; + float: left; + } + } + + .author { + font-size: 18px; + font-weight: 300; + + span.person { + font-weight: 700; + } + } + } + + &.white .inner-wrapper { + border-top: 1px solid #d5dde2; + + .quotation { + max-width: 1000px; + } + } +} + +/* Separator Block */ + +.block.separator { + top: unset; + display: block; + height: unset; + border: none; + margin: 0; + clear: both; + + .line { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + &::after { + position: relative; + top: 50%; + display: block; + border-top: 1px solid var(--secondary-black); + margin-top: -1px; + content: ''; + } + } + + &.has--align--center .line { + max-width: var(--text-container-width); + } + + &.has--align--left .line { + max-width: var(--text-container-width); + margin-right: auto; + margin-left: auto; + + &::after { + width: 165px; + } + } + + &.has--noLine--true { + .line::after { + display: none; + } + } +} + +.block-editor-separator { + margin-right: auto; + margin-left: auto; + clear: both; + + &.has--align--center .line { + max-width: var(--text-container-width); + margin-right: auto; + margin-left: auto; + } + + &.has--align--left .block.separator .line { + max-width: var(--text-container-width); + margin-right: auto; + margin-left: auto; + + &::after { + width: 165px; + } + } + + &.has--noLine--true .line::after { + display: none; + } +} + +/* Teaser Block */ + +#page-document > .block.teaser:not(.has--backgroundColor--grey) { + margin-bottom: 25px; +} + +#page-document > .block.teaser .grid-teaser-item.default { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +.block.teaser .teaser-item { + display: block; + + &.default .image-wrapper { + margin: 0; + } +} + +.block.teaser .teaser-item.default { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + .content { + width: 100%; + + h2 { + padding: 0 20px 0 0; + margin: 0 0 15px; + color: var(--primary-black); + font-size: 30px; + font-style: normal; + font-weight: 600; + line-height: 36px; + word-break: break-word; + word-wrap: break-word; + } + + p { + margin: 0; + color: var(--primary-grey); + font-weight: 300; + } + } +} + +#page-edit .block-editor-teaser .teaser-item.default, +#page-edit .block-editor-teaser .grid-teaser-item.default { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +/* Grid Block */ + +#page-document > .block.__grid .ui.grid { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +.block.__grid h2.headline, +.block-editor-teaserGrid h2.headline, +.block-editor-imagesGrid h2.headline { + padding-top: 100px; + padding-bottom: 50px; + margin: 0 auto 0 auto; + .default-heading-size(); +} + +.block.__grid .grid-image-wrapper img.object-fit { + height: auto; + + &.cover { + object-fit: cover; + } + + &.contain { + object-fit: contain; + } +} + +.block.__grid .block.image figure img { + height: auto; +} + +.block.__grid .grid-block-slate .slate, +.block-editor-__grid .block.__grid .slate-editor { + padding: 20px; + margin: 0; + background: #ececec; + + ol, + ul { + padding-left: 15px; + margin: 0; + + li { + color: var(--primary-grey); + font-weight: 300; + + &::marker { + color: @plone-blue; + } + } + } + + p { + margin: 0; + color: var(--primary-grey); + font-weight: 300; + } +} + +.block.__grid.has--backgroundColor--grey .block.teaser .grid-teaser-item, +.block-editor-teaserGrid.has--backgroundColor--grey + .block.teaser + .grid-teaser-item { + background: var(--primary-white); + + .grid-image-wrapper { + margin-bottom: 0; + } + + .content { + padding: 25px; + } +} + +.block.__grid.has--backgroundColor--grey .grid-block-slate .slate, +.block-editor-__grid.has--backgroundColor--grey .block.__grid .slate-editor { + background: var(--primary-white); +} + +.block.__grid > .ui.grid .column { + padding-top: 1rem; + padding-right: 0.5rem; + padding-bottom: 1rem; + padding-left: 0.5rem; +} + +#page-edit .block-editor-__grid .ui.grid, +#page-edit .block-editor-teaserGrid .ui.grid, +#page-edit .block-editor-imagesGrid .ui.grid { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +/* Slider Block */ + +.block.slider .teaser-item { + display: block; +} + +.block.slider .grid-teaser-item.top { + display: block; +} + +.highlight-image-wrapper.gradient { + width: 100%; +} + +.block.slider .teaser-item.link { + display: flex; + width: 100%; + + &.right { + align-items: end; + } +} + +.block.slider .highlight-image-wrapper img { + -o-object-position: unset; + object-position: unset; +} + +.block.slider .teaser-item-title { + position: absolute; + top: 50%; + width: 530px; + padding: 40px; + background-color: rgba(0, 134, 195, 0.8); + transform: translateY(-50%); + + @media only screen and (max-width: @largestMobileScreen) { + position: static; + width: 100%; + padding: 20px; + transform: none; + } + + .title { + margin-bottom: 60px; + + @media only screen and (max-width: @largestMobileScreen) { + margin-bottom: 30px; + } + + .supertitle { + color: var(--primary-white); + font-size: 30px; + font-style: normal; + font-weight: 300; + line-height: 36px; + + @media only screen and (max-width: @largestMobileScreen) { + font-size: 14px; + line-height: 18px; + } + } + + h2 { + margin: 15px 0 0 0; + color: var(--primary-white); + font-size: 48px; + font-style: normal; + font-weight: 500; + line-height: 54px; + overflow-wrap: break-word; + word-break: break-word; + word-wrap: break-word; + + @media only screen and (max-width: @largestMobileScreen) { + font-size: 30px; + line-height: 36px; + } + } + } + + .body p { + color: @white !important; + } + + button { + padding: 11px 29px; + border: 2px solid #fff; + background: transparent; + color: var(--primary-white); + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 30px; + } +} + +/* Slick slider */ +.block.slider .slick-arrow, +.block.slider .slick-arrow { + color: var(--primary-black); + + @media only screen and (max-width: @largestMobileScreen) { + display: none; + visibility: hidden; + } +} + +.block.slider .slick-dots { + position: unset; + + li { + width: 55px; + height: 7px; + background-color: #b2b2b2; + + button { + width: 55px; + height: auto; + border: 0; + + &::before { + content: none; + } + } + + &.slick-active { + background-color: var(--primary-black); + } + } +} + +/* Slider Edit */ +.block-editor-slider .teaser-item.top { + display: flex; + + &.right { + justify-content: right; + } +} + +.block-editor-slider { + max-width: 1440px; + + &.has--backgroundColor--grey + .block.slider:not(.inner):not([role='presentation']) { + padding-bottom: 25px !important; + margin-bottom: 25px; + } +} + +/* Listing Block */ + +.block.listing .headline, +.block.listing .listing-wrapper { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +.block.listing .items { + display: flex; + flex-wrap: wrap; + justify-content: space-between; +} + +.block.listing .listing-item { + display: block; + max-width: 458px; + border: 1px solid #cdcdcd; + background: var(--primary-white); + border-radius: 8px; + + @media only screen and (max-width: @largestMobileScreen) { + width: 100%; + max-width: none; + } + + .listing-image { + width: 100%; + height: 150px; + border-radius: 8px 8px 0 0; + object-fit: cover; + } +} + +.block.listing .listing-body { + padding: 20px; + + h3 { + width: fit-content; + margin-top: 0; + } + + p { + color: var(--primary-grey); + } +} + +.block.listing .listing-body .event-when-where { + display: flex; + flex-direction: row; + + .dates { + color: var(--primary-black); + } +} + +/* Search Block */ + +.block.search .row { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + .wide.column { + padding: 0; + } +} + +.block.search .search-wrapper .ui.input input { + padding-left: 20px; + border: 0; + background-color: #ececec; + border-radius: 0; + font-size: 32px; + font-style: normal; + font-weight: 200; + line-height: 38px; +} + +.block.search .search-wrapper .ui.button { + margin: 15px; +} + +.block.search .search-wrapper svg { + width: unset !important; + height: 38px !important; +} + +.block.search .search-wrapper .divider { + border-right: none; +} + +.block.search .listing-item { + border-bottom: 1px solid #525252; + + .image-wrapper { + width: 300px; + height: 180px; + margin-right: 20px; + margin-bottom: 40px; + + img { + width: 300px; + height: 180px; + margin: 0; + object-fit: cover; + } + } + + .listing-body h3 { + font-size: 30px; + font-style: normal; + font-weight: 500; + line-height: 36px; + } +} diff --git a/frontend/theme/extras/custom.less b/frontend/theme/extras/custom.less new file mode 100644 index 00000000..40864288 --- /dev/null +++ b/frontend/theme/extras/custom.less @@ -0,0 +1,609 @@ +:root { + /* White */ + --primary-white: #fff; + --secondary-white: #fafafa; + + /* Grey / Lightgrey*/ + --primary-grey: #525252; + --secondary-grey: #ececec; + + --primary-lightGrey: #cdcdcd; + + /* Black */ + --primary-black: #181818; + --secondary-black: #000; + + /* Container widths */ + --text-container-width: 620px; + --default-container-width: 940px; + --full-container-width: 1440px; +} + +@plone-blue: #0086c3; +@white: #fff; + +.has--backgroundColor--transparent { + background: transparent; +} + +.has--backgroundColor--grey { + background: var(--secondary-grey); +} + +.default-heading-size() { + max-width: 940px !important; + color: #000; + font-size: 2.5rem; + font-style: normal; + font-weight: 300; + line-height: 3rem; +} +.small-heading-size() { + max-width: 940px !important; + cursor: text; + font-size: 2rem; + font-weight: 300; + line-height: 1.5rem; +} + +.button-blue() { + &.blue { + border: 1px solid @plone-blue; + background: linear-gradient(to right, transparent 50%, @plone-blue 50%); + background-position: right; + background-size: calc(200% + 1px) 100%; + color: @white; + + &:hover { + background-position: left; + color: @plone-blue; + } + } +} +.button-white() { + &.white { + border: 1px solid @white; + background: linear-gradient(to right, transparent 50%, @white 50%); + background-position: right; + background-size: calc(200% + 1px) 100%; + color: @plone-blue; + + &:hover { + background-position: left; + color: @white; + } + } +} + +.siteroot { + .ui.secondary.vertical.segment.breadcrumbs { + display: none; + } +} + +body.section-search { + .ui.secondary.vertical.segment.breadcrumbs { + visibility: hidden; + } + + #page-search.ui.container { + h2 { + max-width: var(--default-container-width); + } + } +} + +#toolbar .toolbar-content.show { + z-index: 999; +} + +body.cms-ui .ui.basic.segment.content-area { + cursor: default; +} + +//Header +.ui.basic.segment.header-wrapper { + position: fixed !important; + z-index: 10; + width: 100%; + height: 69px; + padding: 0; + border-bottom: 1px solid #cdcdcd; + background-color: @white; + + .ui.container { + max-width: var(--full-container-width); + margin-right: auto; + margin-left: auto; + + .header { + height: 69px; + flex-direction: row; + + a { + color: var(--primary-black); + } + + .logo-nav-wrapper { + position: relative; + height: 69px; + + .logo-wrapper { + display: flex; + width: 155px; + height: 40px; + } + + .nav-search-wrapper { + display: flex; + width: 100%; + flex-direction: row; + + .navigation { + #navigation.navigation { + .ui.pointing.secondary.stackable.computer.large.screen.widescreen.only.menu { + .desktop-menu { + display: flex; + + .nav-menu-wrapper { + .item { + padding: auto; + padding-bottom: 21px; + color: var(--primary-black); + text-transform: none; + + &:hover { + border-color: var(--primary-black); + } + } + + .item.active { + padding-bottom: 21px; + border-color: var(--primary-black); + color: var(--primary-black); + } + + .sub-menu-wrapper { + opacity: 0; + transform: translateY(0); + transition: transform 0.5s, opacity 0.5s; + } + + &:hover { + .sub-menu-wrapper { + left: calc(-50vw + 50%); + width: 100%; + padding-top: 14px; + background-color: @white; + box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; + opacity: 1; + transform: translateY(0); + + .sub-menu { + width: 100%; + max-width: var(--full-container-width); + padding: 0; + margin: 0; + margin-right: auto; + margin-left: auto; + list-style-type: none; + + .sub-item { + margin-bottom: 14px; + opacity: 1; + + a { + color: #595959; + + &:hover { + color: var(--primary-black); + } + } + } + } + + .divider { + border-bottom: 1px solid #cdcdcd; + margin: 0 20px 14px 20px; + } + } + } + } + + .sub-menu-wrapper { + position: absolute; + opacity: 0; + transition: visibility 0s, opacity 0.5s linear; + visibility: hidden; + } + } + } + } + } + + .search { + margin-top: auto; + margin-bottom: auto; + margin-left: auto; + + .ui.form { + .field.search-icon { + button { + border: 0 solid transparent; + background-color: transparent; + cursor: pointer; + + .icon { + height: 24px; + fill: @plone-blue !important; + } + } + } + } + } + } + } + } + } +} +//Breadcrumbs +.ui.secondary.vertical.segment.breadcrumbs { + padding: 0; + border-top: 0 solid transparent; + border-bottom: 0 solid transparent; + margin-top: 68px; + background-color: @white; + + .ui.container { + max-width: var(--full-container-width); + margin-right: auto; + margin-left: auto; + + .ui.breadcrumb { + margin-top: 10px; + + .section { + width: auto; + margin-top: auto; + margin-bottom: auto; + color: var(--primary-black); + text-align: center; + } + + .divider { + color: var(--primary-black); + } + } + } +} +//Content-area +.ui.basic.segment.content-area { + padding-top: 69px; + margin: 0; + + //Page-search + #page-search .ui.container { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; + + .container { + .ui.form { + .field.searchbox { + height: 40px; + justify-content: space-between; + padding-left: 0; + border-left: 0; + + .ui.transparent.input { + width: 100%; + border-bottom: 1px solid #c7d5d8; + margin-right: 20px; + } + + .search-button { + width: 84px; + min-height: 1em; + background-color: @plone-blue; + border-radius: 4px; + color: @white; + font-weight: bold; + text-align: center; + } + } + } + + .ui.header { + .content.header-content { + //Dropdown + .ui.inline.dropdown { + color: #3c4048; + + .item { + .ui.tiny.button { + background-color: transparent; + font-size: 14px; + } + } + + .menu { + padding-top: 9px; + padding-bottom: 9px; + } + } + } + } + } + } +} + +#page-document .event-details aside { + border: none; + border-left: 1px solid #cdcdcd; + box-shadow: none; +} + +#footer { + padding: 0 0 25px; + border-top: 1px solid #cdcdcd; + margin-top: 150px; + background-color: @white; + + .ui.container { + max-width: 1440px; + margin-right: auto; + margin-left: auto; + color: var(--primary-grey); + + .discreet { + background-color: @white; + } + } +} + +.ui.inverted.segment .inverted.segment { + color: var(--primary-black); + + a { + color: @plone-blue; + } +} + +.ui.inverted.list .item a:not(.ui), +.ui.inverted.list .item a:not(.ui):hover { + color: @plone-blue !important; +} + +img.ui.image:not(.logo) { + display: inline; + margin-bottom: 14px; +} + +body #page-sitemap .ui.container { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +#page-document .ui.container, +#page-edit .ui.container, +#contact-form .ui.container { + max-width: var(--full-container-width); + margin-right: auto; + margin-left: auto; +} + +//Blocks +//Message +.block + :not(.__grid) + :not(.image) + :not(.video) + :not(.teaserGrid) + :not(.imagesGrid) + :not(.imagesGrid .block.image) + :not(.hero) + :not(.maps) + :not(.toc) + .ui.message { + max-width: 940px; + flex-direction: row; + border: 2px solid var(--primary-grey); + margin: auto; + + button { + padding: 0; + border: none; + margin: 0; + background-color: transparent; + color: #ff2222; + text-decoration: underline; + } + + b { + text-transform: uppercase; + } +} + +/* Page Search */ + +#page-search #content { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +#page-search #content .ui.form .searchbox { + padding: 20px 0 20px 20px; + border: none; + background-color: #ececec; +} + +#page-search #content .ui.form input { + border: 0; + font-size: 32px; + font-style: normal; + font-weight: 200; + line-height: 38px; +} + +#page-search #content .ui.form .searchbox button { + padding-right: 15px; + color: var(--primary-grey); +} + +/* @media queries */ + +/* Mobile */ +@media only screen and (max-width: @largestMobileScreen) { + #main { + .ui.basic.segment.header-wrapper { + .ui.container { + .header { + .logo-nav-wrapper { + .logo-wrapper { + margin: auto; + } + + .nav-search-wrapper { + display: flex; + flex-direction: row-reverse; + + .navigation { + margin-top: auto; + margin-bottom: auto; + + .navigation { + padding-top: 10px; + + .hamburger-wrapper { + height: fit-content; + padding: 0 15px 15px 15px; + } + + .ui.secondary.pointing.menu .active.item { + border-color: var(--primary-black); + } + } + } + + .search { + .ui.form { + .field.search-icon { + button { + padding: 0; + + .icon { + height: 36px; + } + } + } + } + } + } + } + } + } + } + } +} + +/* Tablet */ +@media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) { + #main { + .ui.basic.segment.header-wrapper { + .ui.container { + .header { + .logo-nav-wrapper { + .logo-wrapper { + margin: auto; + } + + .nav-search-wrapper { + display: flex; + flex-direction: row-reverse; + + .navigation { + margin-top: auto; + margin-bottom: auto; + + .navigation { + padding-top: 10px; + + .hamburger-wrapper { + height: fit-content; + padding: 0 15px 15px 15px; + } + + .mobile-menu .mobile-menu-nav { + .ui.secondary.pointing.menu { + flex-direction: column; + + .item { + align-self: center; + } + + .item.active { + border-color: var(--primary-black); + } + } + } + } + } + + .search { + .ui.form { + .field.search-icon { + button { + padding: 0; + + .icon { + height: 36px; + } + } + } + } + } + } + } + } + } + } + } +} + +/* Small Monitor */ +@media only screen and (min-width: @computerBreakpoint) and (max-width: @largeMonitorWidth) { + body:not(.has-toolbar):not(.has-sidebar):not(.has-toolbar-collapsed):not(.has-sidebar-collapsed) + .header-wrapper + .ui.container { + width: unset; + margin-right: auto; + margin-left: auto; + } + + body:not(.has-toolbar):not(.has-sidebar):not(.has-toolbar-collapsed):not(.has-sidebar-collapsed) + #page-document.ui.container { + width: unset; + margin-right: auto; + margin-left: auto; + } +} + +/* Large Monitor */ +@media only screen and (min-width: @largeMonitorBreakpoint) { + body:not(.has-toolbar):not(.has-sidebar):not(.has-toolbar-collapsed):not(.has-sidebar-collapsed) + .header-wrapper + .ui.container { + width: var(--full-container-width); + margin-right: auto; + margin-left: auto; + } + + body:not(.has-toolbar):not(.has-sidebar):not(.has-toolbar-collapsed):not(.has-sidebar-collapsed) + #page-document.ui.container { + width: var(--full-container-width); + margin-right: auto; + margin-left: auto; + } +} diff --git a/frontend/theme/extras/custom.overrides b/frontend/theme/extras/custom.overrides new file mode 100644 index 00000000..616c2e78 --- /dev/null +++ b/frontend/theme/extras/custom.overrides @@ -0,0 +1,9 @@ +/* Blocks */ + +@import 'blocks'; + +/* Document */ + +@import 'custom'; + +@import 'utils'; diff --git a/frontend/theme/theme.config b/frontend/theme/theme.config index d934dc88..3956b769 100644 --- a/frontend/theme/theme.config +++ b/frontend/theme/theme.config @@ -69,7 +69,7 @@ *******************************/ /* Path to theme packages */ -@themesFolder : '~volto-themes'; +@themesFolder : '../../node_modules/@plone/volto/theme/themes'; /* Path to site override folder */ @siteFolder : "../../theme"; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 68d6442f..1357f550 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2749,23 +2749,6 @@ __metadata: languageName: node linkType: hard -"@kitconcept/volto-light-theme@npm:3.0.0-alpha.1": - version: 3.0.0-alpha.1 - resolution: "@kitconcept/volto-light-theme@npm:3.0.0-alpha.1" - peerDependencies: - "@eeacms/volto-accordion-block": ^10.4.0 - "@kitconcept/volto-button-block": ^2.3.1 - "@kitconcept/volto-dsgvo-banner": ^1.3.0 - "@kitconcept/volto-heading-block": ^2.4.0 - "@kitconcept/volto-highlight-block": ^3.0.0 - "@kitconcept/volto-introduction-block": ^1.0.0 - "@kitconcept/volto-separator-block": ^4.0.0 - "@kitconcept/volto-slider-block": ^6.1.0 - "@plone/volto": ^17.8.0 - checksum: 81a4c8a66f439a16878d1584bd471086135ed2bd280d6da79eb254021694814a9bfbcba5b18440b2a193e116bdf361cfafbc9acfa81e15914ed94d1559cd8c12 - languageName: node - linkType: hard - "@kitconcept/volto-separator-block@npm:4.0.0": version: 4.0.0 resolution: "@kitconcept/volto-separator-block@npm:4.0.0" @@ -12165,7 +12148,6 @@ __metadata: "@kitconcept/volto-export": 1.1.0 "@kitconcept/volto-heading-block": 2.4.0 "@kitconcept/volto-introduction-block": 1.0.0 - "@kitconcept/volto-light-theme": 3.0.0-alpha.1 "@kitconcept/volto-separator-block": 4.0.0 "@kitconcept/volto-slider-block": 5.1.1 "@plone-collective/volto-authomatic": 1.3.0