Commit 298a4aad authored by Jon Moore's avatar Jon Moore
Browse files

Master

parent 8a9cfa88
ALIAS=zenhub
INTERNAL_VIP=10.128.46.132
ACCESS_TOKEN=sNF3SnNWu6RMAtpzybcOqkHKUlMnEUwrNre0OlD9G8UERroN
PUBLIC_URL=https://live-zengenti-zenhub.cloud.contensis.com/
PROJECT=zengenti
ALIAS=workshops-cte-master
INTERNAL_VIP=10.128.21.82
ACCESS_TOKEN=AfTWtGox8aKdgO85rXXSJrWUXa97BA1aXP4fwaIrliDSvWNz
PUBLIC_URL=https://live-workshops-cte-master.cloud.contensis.com
PROJECT=website
CONTENSIS_VERSION=14
ALIAS=-workshops-cte-master
INTERNAL_VIP=10.128.21.82
ACCESS_TOKEN=AfTWtGox8aKdgO85rXXSJrWUXa97BA1aXP4fwaIrliDSvWNz
PUBLIC_URL=https://live-workshops-cte-master.cloud.contensis.com
PROJECT=website
CONTENSIS_VERSION=14
......@@ -13,10 +13,10 @@ export default [
}),
},
{
contentTypeID: 'exampleCT',
contentTypeID: 'blogPost',
component: Loadable({
loader: () => {
return import('~/pages/Examples/ExamplePage');
return import('~/pages/Blogs/BlogPost');
},
loading: Loading,
}),
......
......@@ -10,10 +10,10 @@ export default [
component: Homepage,
},
{
path: '/example-listing',
path: '/blog-listing',
exact: true,
component: Loadable({
loader: () => import('~/pages/Listings/ExampleListing.page'),
loader: () => import('~/pages/Listings/BlogListing.page'),
loading: Loading,
}),
},
......
import styled, { css } from 'styled-components';
const ExampleCardStyled = styled.article`
const BlogCardStyled = styled.article`
${() => {
return css`
display: block;
......@@ -30,4 +30,4 @@ const ExampleCardStyled = styled.article`
}};
`;
export default ExampleCardStyled;
export default BlogCardStyled;
import styled, { css } from 'styled-components';
import getIn from '~/utils/getIn';
import validateProps from '~/utils/validateProps';
const TreatmentsFiltersStyled = styled.div`
${({ theme, filtersVisible }) => {
const mqLarge = getIn(['layout', 'mediaQueries', 'large'], theme);
const visuallyHidden = getIn(['patterns', 'visuallyHidden'], theme);
validateProps('TreatmentsFiltersStyled', { mqLarge, visuallyHidden });
const BlogFiltersStyled = styled.div`
${() => {
return css`
@media only screen and (min-width: ${mqLarge}) {
@media only screen and (min-width: 1024px) {
padding-right: 32px;
}
......@@ -26,7 +19,7 @@ const TreatmentsFiltersStyled = styled.div`
}
.feLabel {
${visuallyHidden}
display: none;
}
.feToggle {
......@@ -59,7 +52,7 @@ const TreatmentsFiltersStyled = styled.div`
.toggleFiltersWrap {
text-align: right;
@media only screen and (min-width: ${mqLarge}) {
@media only screen and (min-width: 1024px) {
display: none;
}
}
......@@ -79,17 +72,9 @@ const TreatmentsFiltersStyled = styled.div`
background-image: url('/static/img/icons/chevron_down_green.svg');
width: 8px;
height: 5px;
${filtersVisible && 'transform:rotate(180deg)'}
}
}
${!filtersVisible && '.filterGroup:nth-child(1n+4) {display:none}'};
@media only screen and (min-width: ${mqLarge}) {
${!filtersVisible && '.filterGroup:nth-child(1n+4) {display:block}'};
}
.feList {
border-top: 1px solid #fff;
list-style: none;
......@@ -104,7 +89,7 @@ const TreatmentsFiltersStyled = styled.div`
}
.feItemInput {
${visuallyHidden};
display: none;
}
.feItemInput:checked + .feItemLabel {
......@@ -114,4 +99,4 @@ const TreatmentsFiltersStyled = styled.div`
}};
`;
export default TreatmentsFiltersStyled;
export default BlogFiltersStyled;
import styled, { css } from 'styled-components';
const ExampleListingStyled = styled.div`
const BlogListingStyled = styled.div`
${() => {
return css`
display: flex;
......@@ -8,6 +8,10 @@ const ExampleListingStyled = styled.div`
width: 100%;
max-width: 1200px;
margin: 30px auto;
.resultsInfo {
width: 100%;
margin-bottom: 30px;
}
a {
text-decoration: none;
width: 100%;
......@@ -41,4 +45,4 @@ const ExampleListingStyled = styled.div`
}};
`;
export default ExampleListingStyled;
export default BlogListingStyled;
import styled, { css } from 'styled-components';
const ExampleRecordStyled = styled.div`
const BlogRecordStyled = styled.div`
${() => {
return css`
display: flex;
......@@ -35,4 +35,4 @@ const ExampleRecordStyled = styled.div`
}};
`;
export default ExampleRecordStyled;
export default BlogRecordStyled;
......@@ -2,12 +2,12 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import ExampleCardStyled from '../components.styled/EventCard.styled';
import BlogCardStyled from '../components.styled/BlogCard.styled';
const ExampleCard = ({ title, description, image, uri, className }) => {
const BlogCard = ({ title, description, image, uri, className }) => {
return (
<Link to={uri}>
<ExampleCardStyled className={className}>
<BlogCardStyled className={className}>
{image && (
<img
src={`${image.asset.sys.uri}?width=500&height=300&fit=crop`}
......@@ -18,12 +18,12 @@ const ExampleCard = ({ title, description, image, uri, className }) => {
<h3>{title}</h3>
{description && <p>{description}</p>}
</ExampleCardStyled>
</BlogCardStyled>
</Link>
);
};
ExampleCard.propTypes = {
BlogCard.propTypes = {
className: PropTypes.string,
title: PropTypes.string,
description: PropTypes.string,
......@@ -31,4 +31,4 @@ ExampleCard.propTypes = {
uri: PropTypes.string,
};
export default ExampleCard;
export default BlogCard;
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import ExampleFiltersStyled from '../components.styled/EventFilters.styled';
import BlogFiltersStyled from '../components.styled/BlogFilters.styled';
import FilterEntryDropdown from '~/features/listings/components/FilterEntryDropdown';
const ExampleFilters = ({ className, filters, updateFilters }) => {
const BlogFilters = ({ className, filters, updateFilters }) => {
const [filtersVisible, toggleFilters] = useState(false);
const renderFilter = filterGroup => {
......@@ -41,7 +41,7 @@ const ExampleFilters = ({ className, filters, updateFilters }) => {
};
return (
<ExampleFiltersStyled className={className} filtersVisible={filtersVisible}>
<BlogFiltersStyled className={className} filtersVisible={filtersVisible}>
<div className="tfInner">
{filters &&
filters.map((filterGroup, idx) => {
......@@ -60,15 +60,15 @@ const ExampleFilters = ({ className, filters, updateFilters }) => {
</button>
</div>
</div>
</ExampleFiltersStyled>
</BlogFiltersStyled>
);
};
ExampleFilters.propTypes = {
BlogFilters.propTypes = {
className: PropTypes.string,
clearFilters: PropTypes.func,
filters: PropTypes.array,
updateFilters: PropTypes.func,
};
export default ExampleFilters;
export default BlogFilters;
......@@ -6,14 +6,14 @@ import { selectVersionStatus } from '~/core/redux/selectors';
import { Op, Query } from 'contensis-delivery-api';
import { cachedSearch } from '~/core/util/ContensisDeliveryApi';
import ExampleListingStyled from '../components.styled/ExampleListing.styled';
import ExampleCard from './ExampleCard';
import BlogListingStyled from '../components.styled/BlogListing.styled';
import BlogCard from './BlogCard';
const fetchEntries = async versionStatus => {
const triggerSearch = async versionStatus => {
try {
let query = new Query(
Op.equalTo('sys.contentTypeId', 'exampleCT'),
Op.equalTo('sys.contentTypeId', 'blogPost'),
Op.equalTo('sys.versionStatus', versionStatus)
);
query.pageSize = 3;
......@@ -27,19 +27,19 @@ const fetchEntries = async versionStatus => {
return entries;
};
const ExampleListing = ({ className }) => {
const BlogListing = ({ className }) => {
const [results, setResults] = useState();
const versionStatus = useSelector(selectVersionStatus);
//const versionStatus = 'latest';
useEffect(() => {
fetchEntries(versionStatus).then(entries => {
setResults(entries.items);
fetchEntries(versionStatus).then(results => {
setResults(results);
});
}, [versionStatus]);
let resultsInfo = null;
if (results && results.totalCount > 1) {
if (results && results.totalCount > 0) {
const start = results.pageIndex * results.pageSize + 1;
let end = results.pageSize;
if (end > results.totalCount) end = results.totalCount;
......@@ -48,7 +48,7 @@ const ExampleListing = ({ className }) => {
}
return (
<ExampleListingStyled className={className}>
<BlogListingStyled className={className}>
{resultsInfo && (
<div
className="resultsInfo"
......@@ -57,9 +57,10 @@ const ExampleListing = ({ className }) => {
)}
{results &&
results.map((entry, idx) => {
results.items &&
results.items.map((entry, idx) => {
return (
<ExampleCard
<BlogCard
title={entry.title}
description={entry.summary}
image={entry.image}
......@@ -69,12 +70,12 @@ const ExampleListing = ({ className }) => {
);
})}
{!results || (results.length < 1 && <p>No results found.</p>)}
</ExampleListingStyled>
</BlogListingStyled>
);
};
ExampleListing.propTypes = {
BlogListing.propTypes = {
className: PropTypes.string,
};
export default ExampleListing;
export default BlogListing;
import React from 'react';
import PropTypes from 'prop-types';
import ExampleRecordStyled from '../components.styled/EventRecord.styled';
import BlogRecordStyled from '../components.styled/BlogRecord.styled';
import ContentComposer from '~/features/composer/components/Composer';
const EventRecord = ({ className, entry }) => {
const BlogRecord = ({ className, entry }) => {
if (!entry) return null;
return (
<ExampleRecordStyled className={className}>
<BlogRecordStyled className={className}>
<div className="container">
{entry.image && (
<img src={entry.image.asset.sys.uri} alt={entry.image.altText} />
......@@ -17,16 +17,16 @@ const EventRecord = ({ className, entry }) => {
<div className="eventContent">
<h1 className="pageTitle">{entry.entryTitle}</h1>
{entry.content && <ContentComposer composer={entry.content} />}
{entry.content && <ContentComposer composer={entry.postContent} />}
</div>
</div>
</ExampleRecordStyled>
</BlogRecordStyled>
);
};
EventRecord.propTypes = {
BlogRecord.propTypes = {
className: PropTypes.string,
entry: PropTypes.object,
};
export default EventRecord;
export default BlogRecord;
import React from 'react';
import { storiesOf } from '@storybook/react';
import { text } from '@storybook/addon-knobs';
import ExampleCard from '~/features/exampleListing/components/ExampleCard';
import BlogCard from '~/features/blogListing/components/BlogCard';
storiesOf('Features | Listings', module).add(
'Example card',
'Blog card',
() => {
return (
<ExampleCard
<BlogCard
title={text('Title', 'Example Title')}
description={text('Title', 'Example description')}
uri="/example-content/example-article"
uri="/blog/example-post"
/>
);
},
......
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
const ExtSvg = styled(({ className }) => {
return (
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
title="(opens new window)"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
strokeLinecap="square"
strokeLinejoin="arcs"
>
<g fill="none" fillRule="evenodd">
<path d="M18 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h5M15 3h6v6M10 14L20.2 3.8" />
</g>
</svg>
);
})`
${({ theme: { swatch } }) => `
position: relative;
top: 2px;
margin-left: 4px;
stroke: ${swatch.link.initial};
stroke-width: 2px;
`};
`;
ExtSvg.propTypes = {
className: PropTypes.string,
};
ExtSvg.defaultProps = {};
export default ExtSvg;
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import ExtSvg from './ExtSvg';
const RoutedLink = styled(
({
text,
path,
titleattr,
target,
onClick,
onBlur,
children,
srHidden,
tabIndex,
noIcon,
style,
// staticLink,
className,
}) => {
let setTarget = '';
let targetAuto = false;
let manaulExtIcon = false;
if (target) {
if (target.toLowerCase() === 'new window') {
manaulExtIcon = true;
setTarget = '_blank';
} else if (target.toLowerCase() === 'none') {
setTarget = '';
} else if (target.toLowerCase() === 'auto detect') {
targetAuto = true;
} else {
setTarget = target;
}
}
if (process.env.NODE_ENV === 'development') {
if (!path) {
return (
<a className={className} href="#no-location-set">
<span className="no-location">No location set - </span>
{text}
{children && children}
</a>
);
}
}
// if (staticLink) {
// return (
// <a
// href={path}
// className={className}
// style={style}
// aria-hidden={srHidden}
// tabIndex={tabIndex}
// onClick={onClick}
// onBlur={onBlur}
// title={titleattr}
// target={setTarget}
// >
// {text}
// {children && children}
// </a>
// );
// }
if (
path &&
(path.includes('https://www.canterbury.ac.uk') ||
path.includes('http://www.canterbury.ac.uk') ||
path.includes('www.canterbury.ac.uk') ||
path.includes('canterbury.ac.uk'))
) {
return (
<a
href={path}
className={className}
style={style}
aria-hidden={srHidden}
tabIndex={tabIndex}
onClick={onClick}
onBlur={onBlur}
title={titleattr}
target={setTarget}
>
{text}
{children && children}
</a>
);
} else if (
path &&
(path.includes('.pdf') ||
path.includes('.xlsx') ||
path.includes('.doc') ||
path.includes('.xml') ||
path.includes('.csv') ||
path.includes('.zip') ||
path.includes('.ics'))
) {
return (
<a
href={path}
className={className}
rel="noopener noreferrer"
target={target && !targetAuto ? setTarget : '_blank'}
style={style}
aria-hidden={srHidden}
tabIndex={tabIndex}
onClick={onClick}
onBlur={onBlur}
title={titleattr}
>
{text}
{children && children}
</a>
);
} else if (
path &&
(path.includes('facebook.com') ||
path.includes('twitter.com') ||
path.includes('youtube.com') ||
path.includes('linkedin.com'))
) {
return (
<a
href={path}
className={className}
rel="noopener noreferrer"
target={target && !targetAuto ? setTarget : '_blank'}
style={style}
aria-hidden={srHidden}
tabIndex={tabIndex}
onClick={onClick}
onBlur={onBlur}
title={titleattr}
>
{text}
{children && children}
</a>
);
} else if (
path &&
(path.includes('http://') ||
path.includes('https://') ||
path.includes('wwww.'))
) {
return (
<a
href={path}
className={className}
rel="noopener noreferrer"
target={target && !targetAuto ? setTarget : '_blank'}
style={style}
aria-hidden={srHidden}
tabIndex={tabIndex}
onClick={onClick}
onBlur={onBlur}