initial boilerplate import

master
Malar Kannan 2017-08-09 10:50:04 +05:30
commit fffed7a048
21 changed files with 8015 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

1905
README.md Normal file

File diff suppressed because it is too large Load Diff

22
SPEC.md Normal file
View File

@ -0,0 +1,22 @@
Q1 Blogging platform with in-place comments
Tests: Machine coding, technology decision making, experience with web apps in production, problem solving
Criteria. We evaluate that you can:
Break down code into a tiered structure
Present working code
Write code that is testable
Create something that can be deployed with ease.
Design use-able APIs around abstract product requirements
Problem statement:
You are to create a blogging product that supports comments on paragraphs. Not comments on the blog, but on a specific paragraph. Requirements follow:
I should be able to add blog posts. Blog posts have a unique random identifier, a title and plain text where paragraphs are separated by two new-line characters.
I should be able to view all blog posts (list-mode) starting with first 5 and then the next 5 and so on. This view will not have any comments.
I should be able to click on one of these blogs to view it in full-mode. In full-mode, all past comments on the text are visible next to the text. Also, the viewer is able to comment on a paragraph of text. In essence, the comment is on a paragraph.
The API, when it responds with comments should provide some means to figure out which comment is on which paragraph. The notation for that is up to you to choose.
Non-requirements: Please do not think of or address any of these items:
There are no users. No authentication. Everyone could be an admin and a viewer.
The comments are not attached to any user, because there are none. There are just blogs and comments.
You are not required to create the UI to achieve any of the goals. Simple APIs are all we are looking for. These could be HTTP APIs. The HTTP APIs should be able to respond to all the user stories enumerated above.
You are not required to write tests for this. You may, if that is how you work.

24
package-lock.json generated Normal file
View File

@ -0,0 +1,24 @@
{
"name": "typeset-blog",
"version": "0.1.0",
"lockfileVersion": 1,
"dependencies": {
"@types/history": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.6.0.tgz",
"integrity": "sha512-2A0stT6b61DANLErAfSkeQ77N+A3FbR7ardUJUP3xm9f4W8qtG9ispBYDUX42Fl1EbR0rqSV3IWjbB6ew7hXRw=="
},
"@types/react-router": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-4.0.14.tgz",
"integrity": "sha512-wbcqBGFv2KcBo0fIief2MJeE5e1Ph9Z35FzWPmadNMzd5dwpFGLVxyDQiLc30u3ehNrgG7JlQcFYLe5YJnToyA==",
"dependencies": {
"@types/react": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.0.1.tgz",
"integrity": "sha512-0ofqK0AZwPGnbWrpowUsdSVxI7iqt6vpIpf9OC6hvAo/ZzJ7eNibys6kuE3aJwcLLIsDinU1ent/n3oYj+99yQ=="
}
}
}
}
}

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "typeset-blog",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/jest": "^20.0.6",
"@types/node": "^8.0.20",
"@types/react": "^16.0.1",
"@types/react-dom": "^15.5.2",
"@types/react-router": "^4.0.14",
"@types/react-router-dom": "^4.0.7",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router": "^4.1.2",
"react-router-dom": "^4.1.2",
"react-scripts-ts": "2.5.0",
"react-semantic-ui": "^0.2.0",
"semantic-ui-react": "^0.71.3"
},
"devDependencies": {},
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

10
public/index.html Executable file
View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="root"></div>
</body>
</html>

15
public/manifest.json Normal file
View File

@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

12
src/app.tsx Executable file
View File

@ -0,0 +1,12 @@
import * as React from 'react';
import { Header } from './components';
export const App: React.StatelessComponent<{}> = (props) => {
return (
<div className="container-fluid">
<Header />
{props.children}
</div>
);
}

79
src/components/about.tsx Executable file
View File

@ -0,0 +1,79 @@
import * as React from 'react';
export const About: React.StatelessComponent<{}> = () => {
return (
<div className="row about-page">
<h1 className="jumbotron">03 Navigation</h1>
<div className="col-xs-12">
<h1>
<small>
This sample takes as starting point sample "02 Components".
</small>
</h1>
<div className="col-xs-12">
<h3>
<small>
We are adding page navigation to this project:
</small>
</h3>
<ul>
<li><h3><small>We have added two pages (about, members).</small></h3></li>
<li><h3><small>The user can navigate by clicking on links in a common navbar.</small></h3></li>
</ul>
<h3>
<small>
We are using <a target="_blank" href="https://github.com/reactjs/react-router">react-router</a> for the navigation support
</small>
</h3>
</div>
</div>
<div className="col-xs-12 top-buffer">
<h3>Highlights</h3>
<hr />
<h3>
<small>
The most interesting parts worth to take a look
</small>
</h3>
</div>
<div className="col-xs-12 top-buffer">
<ul>
<li className="top-buffer">
<h4><b>Router:</b></h4>
<ul className="top-buffer">
<li>
<h4>
index.ts: <small>routes configuration.</small>
</h4>
</li>
</ul>
</li>
<li className="top-buffer">
<h4><b>Components:</b></h4>
<ul className="top-buffer">
<li>
<h4>
app.tsx: <small>header + page container.</small>
</h4>
</li>
<li>
<h4>
header.tsx: <small>navigation links.</small>
</h4>
</li>
<li>
<h4>
aboutPage.tsx / membersPage.tsx: <small>pages</small>
</h4>
</li>
</ul>
</li>
</ul>
</div>
</div>
);
}

17
src/components/header.tsx Executable file
View File

@ -0,0 +1,17 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
export const Header: React.StatelessComponent<{}> = () => {
return (
<div className="row">
<nav className="navbar navbar-default">
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul className="nav navbar-nav">
<li><Link to="/about">About</Link></li>
<li><Link to="/members">Members</Link></li>
</ul>
</div>
</nav>
</div>
);
}

3
src/components/index.ts Executable file
View File

@ -0,0 +1,3 @@
export * from './header';
export * from './about';
export * from './members';

View File

@ -0,0 +1 @@
export * from './page';

View File

@ -0,0 +1,9 @@
import * as React from 'react';
export const MembersPage: React.StatelessComponent<{}> = () => {
return (
<div className="row">
<h2> Members Page</h2>
</div>
);
}

21
src/css/site.css Executable file
View File

@ -0,0 +1,21 @@
.top-buffer{
margin-top: 20px;
}
.about-page{
position: relative;
top: -20px;
}
.about-page .jumbotron{
margin: 0;
background:rgba(9,69,95,0.8);
color: white;
border-radius: 0 !important;
}
/*React apply activeClassName to <a> element, but Bootstrap active class is over <li> element*/
.navbar .nav .active, .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus{
background: #e7e7e7 !important;
color: #333 !important;
}

7
src/index.tsx Executable file
View File

@ -0,0 +1,7 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AppRouter } from './router';
ReactDOM.render(
<AppRouter />
, document.getElementById('root'));

16
src/router.tsx Executable file
View File

@ -0,0 +1,16 @@
import * as React from 'react';
import { Route, HashRouter } from 'react-router-dom';
import { App } from './app';
import { About, MembersPage } from './components';
export const AppRouter: React.StatelessComponent<{}> = () => {
return (
<HashRouter>
<div >
<Route exact={true} path="/" component={App} />
<Route path="/about" component={About} />
<Route path="/members" component={MembersPage} />
</div>
</HashRouter>
);
}

29
tsconfig.json Normal file
View File

@ -0,0 +1,29 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
]
}

6
tsconfig.test.json Normal file
View File

@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}

99
tslint.json Normal file
View File

@ -0,0 +1,99 @@
{
"extends": ["tslint-react"],
"rules": {
"align": [
true,
"parameters",
"arguments",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": false,
"forin": true,
"indent": [ true, "spaces" ],
"interface-name": [true, "never-prefix"],
"jsdoc-format": true,
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"label-position": true,
"max-line-length": [ true, 120 ],
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": true,
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"log",
"error",
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": false,
"no-unused-expression": true,
"no-use-before-declare": true,
"one-line": [
true,
"check-catch",
"check-else",
"check-open-brace",
"check-whitespace"
],
"quotemark": [true, "single", "jsx-double"],
"radix": true,
"semicolon": [true, "always"],
"switch-default": true,
"trailing-comma": false,
"triple-equals": [ true, "allow-null-check" ],
"typedef": [
true,
"parameter",
"property-declaration"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-module",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
}
}

5692
yarn.lock Normal file

File diff suppressed because it is too large Load Diff