add static pages
This commit is contained in:
parent
bd78b8e4d7
commit
5ba5100a52
19 changed files with 320 additions and 7 deletions
11
imports/api/Utility/server/methods.js
Normal file
11
imports/api/Utility/server/methods.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import getPrivateFile from '../../../modules/server/get-private-file';
|
||||
import parseMarkdown from '../../../modules/parse-markdown';
|
||||
|
||||
Meteor.methods({
|
||||
'utility.getPage': function utilityReadFileAsText(fileName) {
|
||||
check(fileName, String);
|
||||
return parseMarkdown(getPrivateFile(`pages/${fileName}.md`));
|
||||
},
|
||||
});
|
||||
8
imports/modules/parse-markdown.js
Normal file
8
imports/modules/parse-markdown.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { Parser, HtmlRenderer } from 'commonmark';
|
||||
|
||||
export default (markdown, options) => {
|
||||
const reader = new Parser();
|
||||
const writer = options ? new HtmlRenderer(options) : new HtmlRenderer();
|
||||
const parsed = reader.parse(markdown);
|
||||
return writer.render(parsed);
|
||||
};
|
||||
3
imports/modules/server/get-private-file.js
Normal file
3
imports/modules/server/get-private-file.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import fs from 'fs';
|
||||
|
||||
export default path => fs.readFileSync(`assets/app/${path}`, 'utf8');
|
||||
|
|
@ -5,3 +5,5 @@ import '../../api/OAuth/server/methods';
|
|||
|
||||
import '../../api/Users/server/methods';
|
||||
import '../../api/Users/server/publications';
|
||||
|
||||
import '../../api/Utility/server/methods';
|
||||
|
|
|
|||
16
imports/ui/components/Content/Content.js
Normal file
16
imports/ui/components/Content/Content.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/* eslint-disable react/no-danger */
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './Content.scss';
|
||||
|
||||
const Content = ({ content }) => (
|
||||
<div className="Content" dangerouslySetInnerHTML={{ __html: content }} />
|
||||
);
|
||||
|
||||
Content.propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Content;
|
||||
36
imports/ui/components/Content/Content.scss
Normal file
36
imports/ui/components/Content/Content.scss
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
@import '../../stylesheets/mixins';
|
||||
|
||||
.Content {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 30px 0 20px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
> *:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
> *:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
.Content {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,9 @@ body {
|
|||
color: $gray-light;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
a:hover,
|
||||
a:active,
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
color: $gray;
|
||||
}
|
||||
|
|
|
|||
24
imports/ui/components/PageHeader/PageHeader.js
Normal file
24
imports/ui/components/PageHeader/PageHeader.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './PageHeader.scss';
|
||||
|
||||
const PageHeader = ({ title, subtitle }) => (
|
||||
<div className="PageHeader">
|
||||
<div className="PageHeader-container">
|
||||
<h1>{title}</h1>
|
||||
{subtitle ? <p>{subtitle}</p> : ''}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
PageHeader.defaultProps = {
|
||||
subtitle: '',
|
||||
};
|
||||
|
||||
PageHeader.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
subtitle: PropTypes.string,
|
||||
};
|
||||
|
||||
export default PageHeader;
|
||||
47
imports/ui/components/PageHeader/PageHeader.scss
Normal file
47
imports/ui/components/PageHeader/PageHeader.scss
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
@import '../../stylesheets/mixins';
|
||||
@import '../../stylesheets/colors';
|
||||
|
||||
.PageHeader {
|
||||
border-bottom: 1px solid $gray-lighter;
|
||||
padding: 0px 0 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0;
|
||||
color: $gray-light;
|
||||
}
|
||||
}
|
||||
|
||||
.PageHeader-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
.PageHeader {
|
||||
padding: 10px 0 30px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(desktop) {
|
||||
.PageHeader {
|
||||
padding: 20px 0 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,8 @@ import ResetPassword from '../../pages/ResetPassword/ResetPassword';
|
|||
import Profile from '../../pages/Profile/Profile';
|
||||
import NotFound from '../../pages/NotFound/NotFound';
|
||||
import Footer from '../../components/Footer/Footer';
|
||||
import Terms from '../../pages/Terms/Terms';
|
||||
import Privacy from '../../pages/Privacy/Privacy';
|
||||
|
||||
import './App.scss';
|
||||
|
||||
|
|
@ -41,6 +43,8 @@ const App = props => (
|
|||
<Public path="/logout" component={Logout} {...props} />
|
||||
<Route name="recover-password" path="/recover-password" component={RecoverPassword} />
|
||||
<Route name="reset-password" path="/reset-password/:token" component={ResetPassword} />
|
||||
<Route name="terms" path="/terms" component={Terms} />
|
||||
<Route name="privacy" path="/privacy" component={Privacy} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ const Index = () => (
|
|||
<Button href="https://pup.cleverbeagle.com">Read the Docs</Button>
|
||||
<Button href="https://github.com/cleverbeagle/pup"><i className="fa fa-star" /> Star on GitHub</Button>
|
||||
</div>
|
||||
<footer>
|
||||
<p>Need help and want to stay accountable building your product? <a href="https://cleverbeagle.com?utm_source=pupappindex&utm_campaign=oss">Check out Clever Beagle</a>.</p>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,14 +33,23 @@
|
|||
.btn {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:last-child {
|
||||
background: darken($cb-blue, 20%);
|
||||
color: lighten($cb-blue, 30%);
|
||||
footer {
|
||||
margin: 20px -20px -20px;
|
||||
border-top: 1px solid darken($cb-blue, 10%);
|
||||
padding: 20px;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: lighten($cb-blue, 35%);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p a {
|
||||
color: lighten($cb-blue, 35%);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,11 +57,19 @@
|
|||
@include breakpoint(tablet) {
|
||||
.Index {
|
||||
padding: 30px;
|
||||
|
||||
footer {
|
||||
margin: 30px -30px -30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(desktop) {
|
||||
.Index {
|
||||
padding: 40px;
|
||||
|
||||
footer {
|
||||
margin: 40px -40px -40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
44
imports/ui/pages/Page/Page.js
Normal file
44
imports/ui/pages/Page/Page.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { createContainer } from 'meteor/react-meteor-data';
|
||||
import { ReactiveVar } from 'meteor/reactive-var';
|
||||
import PageHeader from '../../components/PageHeader/PageHeader';
|
||||
import Content from '../../components/Content/Content';
|
||||
|
||||
import './Page.scss';
|
||||
|
||||
const Page = ({ title, subtitle, content }) => (
|
||||
<div className="Page">
|
||||
<PageHeader title={title} subtitle={subtitle} />
|
||||
<Content content={content} />
|
||||
</div>
|
||||
);
|
||||
|
||||
Page.defaultProps = {
|
||||
subtitle: '',
|
||||
};
|
||||
|
||||
Page.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
subtitle: PropTypes.string,
|
||||
content: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
const pageContent = new ReactiveVar('');
|
||||
|
||||
export default createContainer(({ content, page }) => {
|
||||
window.scrollTo(0, 0); // Force window to top of page.
|
||||
|
||||
Meteor.call('utility.getPage', page, (error, response) => {
|
||||
if (error) {
|
||||
console.warn(error);
|
||||
} else {
|
||||
pageContent.set(response);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
content: content || pageContent.get(),
|
||||
};
|
||||
}, Page);
|
||||
11
imports/ui/pages/Page/Page.scss
Normal file
11
imports/ui/pages/Page/Page.scss
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
@import '../../stylesheets/mixins';
|
||||
|
||||
.Page {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
.Page {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
14
imports/ui/pages/Privacy/Privacy.js
Normal file
14
imports/ui/pages/Privacy/Privacy.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
import Page from '../Page/Page';
|
||||
|
||||
const Privacy = () => (
|
||||
<div className="Privacy">
|
||||
<Page
|
||||
title="Privacy Policy"
|
||||
subtitle="Last updated May 29th, 2017"
|
||||
page="privacy"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Privacy;
|
||||
14
imports/ui/pages/Terms/Terms.js
Normal file
14
imports/ui/pages/Terms/Terms.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
import Page from '../Page/Page';
|
||||
|
||||
const Terms = () => (
|
||||
<div className="Terms">
|
||||
<Page
|
||||
title="Terms of Service"
|
||||
subtitle="Last updated May 29th, 2017"
|
||||
page="terms"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Terms;
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
"@cleverbeagle/strings": "^0.1.0",
|
||||
"babel-runtime": "^6.20.0",
|
||||
"bcrypt": "^1.0.2",
|
||||
"commonmark": "^0.27.0",
|
||||
"jquery": "^2.2.4",
|
||||
"jquery-validation": "^1.16.0",
|
||||
"meteor-node-stubs": "~0.2.4",
|
||||
|
|
|
|||
18
private/pages/privacy.md
Normal file
18
private/pages/privacy.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Your privacy is important to us.
|
||||
|
||||
It is Clever Beagle's policy to respect your privacy regarding any information we may collect while operating our website. Accordingly, we have developed this privacy policy in order for you to understand how we collect, use, communicate, disclose and otherwise make use of personal information. We have outlined our privacy policy below.
|
||||
|
||||
We will collect personal information by lawful and fair means and, where appropriate, with the knowledge or consent of the individual concerned.
|
||||
Before or at the time of collecting personal information, we will identify the purposes for which information is being collected.
|
||||
|
||||
We will collect and use personal information solely for fulfilling those purposes specified by us and for other ancillary purposes, unless we obtain the consent of the individual concerned or as required by law.
|
||||
|
||||
Personal data should be relevant to the purposes for which it is to be used, and, to the extent necessary for those purposes, should be accurate, complete, and up-to-date.
|
||||
|
||||
We will protect personal information by using reasonable security safeguards against loss or theft, as well as unauthorized access, disclosure, copying, use or modification.
|
||||
|
||||
We will make readily available to customers information about our policies and practices relating to the management of personal information.
|
||||
|
||||
We will only retain personal information for as long as necessary for the fulfillment of those purposes.
|
||||
|
||||
We are committed to conducting our business in accordance with these principles in order to ensure that the confidentiality of personal information is protected and maintained. Clever Beagle may change this privacy policy from time to time at Clever Beagle's sole discretion.
|
||||
38
private/pages/terms.md
Normal file
38
private/pages/terms.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#### Terms
|
||||
|
||||
By accessing the website at https://pup.cleverbeagle.com, you are agreeing to be bound by these terms of service, all applicable laws and regulations, and agree that you are responsible for compliance with any applicable local laws. If you do not agree with any of these terms, you are prohibited from using or accessing this site. The materials contained in this website are protected by applicable copyright and trademark law.
|
||||
|
||||
#### Use License
|
||||
|
||||
Permission is granted to temporarily download one copy of the materials (information or software) on Clever Beagle's website for personal, non-commercial transitory viewing only. This is the grant of a license, not a transfer of title, and under this license you may not:
|
||||
modify or copy the materials;
|
||||
use the materials for any commercial purpose, or for any public display (commercial or non-commercial);
|
||||
attempt to decompile or reverse engineer any software contained on Clever Beagle's website;
|
||||
remove any copyright or other proprietary notations from the materials; or
|
||||
transfer the materials to another person or "mirror" the materials on any other server.
|
||||
This license shall automatically terminate if you violate any of these restrictions and may be terminated by Clever Beagle at any time. Upon terminating your viewing of these materials or upon the termination of this license, you must destroy any downloaded materials in your possession whether in electronic or printed format.
|
||||
|
||||
#### Disclaimer
|
||||
|
||||
The materials on Clever Beagle's website are provided on an 'as is' basis. Clever Beagle makes no warranties, expressed or implied, and hereby disclaims and negates all other warranties including, without limitation, implied warranties or conditions of merchantability, fitness for a particular purpose, or non-infringement of intellectual property or other violation of rights.
|
||||
Further, Clever Beagle does not warrant or make any representations concerning the accuracy, likely results, or reliability of the use of the materials on its website or otherwise relating to such materials or on any sites linked to this site.
|
||||
|
||||
#### Limitations
|
||||
|
||||
In no event shall Clever Beagle or its suppliers be liable for any damages (including, without limitation, damages for loss of data or profit, or due to business interruption) arising out of the use or inability to use the materials on Clever Beagle's website, even if Clever Beagle or a Clever Beagle authorized representative has been notified orally or in writing of the possibility of such damage. Because some jurisdictions do not allow limitations on implied warranties, or limitations of liability for consequential or incidental damages, these limitations may not apply to you.
|
||||
|
||||
#### Accuracy of materials
|
||||
|
||||
The materials appearing on Clever Beagle's website could include technical, typographical, or photographic errors. Clever Beagle does not warrant that any of the materials on its website are accurate, complete or current. Clever Beagle may make changes to the materials contained on its website at any time without notice. However Clever Beagle does not make any commitment to update the materials.
|
||||
|
||||
#### Links
|
||||
|
||||
Clever Beagle has not reviewed all of the sites linked to its website and is not responsible for the contents of any such linked site. The inclusion of any link does not imply endorsement by Clever Beagle of the site. Use of any such linked website is at the user's own risk.
|
||||
|
||||
#### Modifications
|
||||
|
||||
Clever Beagle may revise these terms of service for its website at any time without notice. By using this website you are agreeing to be bound by the then current version of these terms of service.
|
||||
|
||||
#### Governing Law
|
||||
|
||||
These terms and conditions are governed by and construed in accordance with the laws of Illinois and you irrevocably submit to the exclusive jurisdiction of the courts in that State or location.
|
||||
Loading…
Add table
Add a link
Reference in a new issue