Added CacheStore server side, working with blog on client side more.

This commit is contained in:
2018-10-31 21:01:03 +11:00
parent 2ca45b154c
commit 5b4be02593
10 changed files with 294 additions and 9 deletions

View File

@ -0,0 +1,50 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import { PageBoundary } from '@components/page/Page';
import Section from '@sections/Section';
import ArticleThumbnail from '@objects/blog/article/ArticleThumbnail';
import Styles from './ArticleGridSection.scss';
export default props => {
let { className, articles } = props;
articles = articles || [];
return (
<Section className={`c-article-grid ${className||""}`}>
<PageBoundary className="c-article-grid__grid">
{ articles.map((article,index) => {
return <ArticleThumbnail
key={index} article={article} index={index}
className="c-article-grid__article"
/>
}) }
</PageBoundary>
</Section>
);
}

View File

@ -0,0 +1,33 @@
/*
* Article Grid Section
* Styles for the Article Grid Section, aligns sets of articles out in a nice
* grid with some additional styling depending on the count etc.
*
* Version:
* 1.0.0 - 2018/10/31
*/
@import '~@styles/global';
.c-article-grid {
&__grid {
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
&__article {
width: 100%;
}
@include t-media-query($s-xsmall-up) {
&__article {
width: 50%;
}
}
@include t-media-query($s-small-up) {
&__article {
width: (100%/3);
}
}
}

View File

@ -22,8 +22,9 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import { NavLink } from 'react-router-dom';
import { withLanguage } from '@public/language/Language';
import BannerImageSection from '@sections/image/banner/BannerImageSection';
import { PageBoundary } from '@components/page/Page';
@ -34,8 +35,8 @@ import { Title, Paragraph } from '@objects/typography/Typography';
import Styles from './FeaturedArticleSection.scss';
export default props => {
let { article } = props;
export default withLanguage(props => {
let { article, lang } = props;
return (
<BannerImageSection
@ -46,17 +47,18 @@ export default props => {
<ContentBox box className="c-featured-article__header">
<Title className="c-featured-article__title">
{ article.title }
<NavLink to={ article.url } children={ article.title} />
</Title>
</ContentBox>
<ContentBox box className="c-featured-article__body">
<Paragraph className="c-featured-article__description">
{ article.shortDescription }
{ article.shortDescription }&nbsp;
<NavLink to={ article.url } children={ lang.blog.article.readMore } />
</Paragraph>
</ContentBox>
</PageBoundary>
</BannerImageSection>
);
};
});

View File

@ -22,12 +22,13 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import Styles from './ImageSection.scss';
import { NavLink } from 'react-router-dom';
import Section from './../Section';
import Image from '@objects/image/Image';
import Styles from './ImageSection.scss';
export default props => {
let sectionProps = {...props};
let imageProps = {...props};
@ -35,6 +36,7 @@ export default props => {
let { image, background, children, className, imageClassName } = props;
["children", "background", "loadable", "imageClassName"].forEach(e => delete sectionProps[e]);
["image", "full", "children", "background", "imageClassName"].forEach(e => delete imageProps[e]);
let clazz = "c-image-section";
@ -49,6 +51,7 @@ export default props => {
{ image }
<div className="c-image-section__content">
<div className="c-image-section__content-inner">
<a href="//google.com" className="c-image-section__content-link" />
{ children }
</div>
</div>

View File

@ -24,6 +24,12 @@ export default {
}
},
"blog": {
"article": {
"readMore": "Read More"
}
},
"pages": {
"home": {
"banner": {

View File

@ -0,0 +1,78 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import { NavLink } from 'react-router-dom';
import { withLanguage } from '@public/language/Language';
import Image from '@objects/image/Image';
import ContentBox from '@objects/content/box/ContentBox';
import FloatingContentBox from '@objects/content/box/FloatingContentBox';
import { Heading2, Paragraph } from '@objects/typography/Typography';
import Styles from './ArticleThumbnail.scss';
export default withLanguage(props => {
let { className, article, lang, index } = props;
index = (index || 0)%4;
let pos = "";
if(index/2.0 == Math.round(index/2)) {
pos += "top";
pos += index == 2 ? " left" : " right";
} else {
pos += "bottom";
pos += index == 1 ? " left" : " right";
}
return (
<article className={`o-article-thumbnail ${className||""}`}>
<NavLink to={article.url} className="o-article-thumbnail__header">
{/* Image */}
<Image
src={article.image} alt={article.title} loadable
className="o-article-thumbnail__image"
maxWidth="250"
/>
{/* Title */}
<FloatingContentBox box position={pos} className="o-article-thumbnail__title-box">
<Heading2 className="o-article-thumbnail__title">
{ article.title }
</Heading2>
</FloatingContentBox>
</NavLink>
<ContentBox className="o-article-thumbnail__content">
<Paragraph>
{ article.shortDescription }
</Paragraph>
<NavLink to={ article.url }>
{ lang.blog.article.readMore }
</NavLink>
</ContentBox>
</article>
);
});

View File

@ -0,0 +1,40 @@
/*
* Article Thumbnail
* Styles for displaying an article in a short thumbnail object that can be
* put in the usual places.
*
* Version:
* 1.0.0 - 2018/10/31
*/
@import '~@styles/global';
.o-article-thumbnail {
padding-bottom: 1.5em;
&__header {
display: block;
position: relative;
}
&__image {
display: block;
width: 100%;
}
&__title {
margin: 0;
width: 100%;
&-box {
transition: all 0.3s $s-animation--ease-out;
.o-article-thumbnail__header:hover & {
transform: translateY(-7.5%);
}
}
}
&__content {
padding: 0 0.5em;
}
}

View File

@ -27,6 +27,7 @@ import { withLanguage } from '@public/language/Language';
import Page, { PageBoundary } from '@components/page/Page';
import FeaturedArticleSection from '@sections/blog/article/FeaturedArticleSection';
import ArticleGridSection from '@sections/blog/article/ArticleGridSection';
const TestBlogData = {
handle: "test-blog",
@ -43,6 +44,7 @@ export default withLanguage(props => {
<Page style="blog-page" className="p-blog-page" title={ lang.pages.blog.title }>
{/* First (Featured) Blog */}
<FeaturedArticleSection article={ TestBlogData } />
<ArticleGridSection articles={[ TestBlogData, TestBlogData, TestBlogData, TestBlogData, TestBlogData]} />
</Page>
);
});