4 Commits

43 changed files with 13586 additions and 376 deletions

View File

@@ -1,5 +1,30 @@
# subtaskio # subtaskio
Subtask Io Subtask Io
frontend - React JS frontend #Frontend
## How to use - React JS frontend
- Clone git
- Switch to frontend directory
`$ cd frontend`
- Install dependencies:
`$ npm install`
- Host dev environment and start
`$ npm start`
## Stack:
- React 16.3.1
- React-Router-dom 4.2.2
- babel-core 6.26.0
- Webpack 3.8.1
- Unit Testing :
- Jest 22.4.3.8
- Enzyme 3.3.0
#Backend
backend - Aws Lambda backend backend - Aws Lambda backend

View File

@@ -1,6 +0,0 @@
build:
go get github.com/aws/aws-lambda-go/lambda
go get github.com/aws/aws-lambda-go/events
set GOOS=linux
go build -o bin/Task_API Tasks.go
C:\Users\Emir\go\bin\build-lambda-zip.exe -o bin/Task_API.zip bin/Task_API

View File

@@ -1,149 +0,0 @@
package main
import (
"fmt"
"encoding/json"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
type User struct {
Username string
FirstName string
LastName string
ListOfTasks []Task
}
type Project struct {
Name string
Description string
Leader User
ListOfTasks []Task
}
type Task struct {
Title string
Description string
UsersOnTask []User
Date string
TaskProject Project
}
func main() {
lambda.Start(Handler)
}
func Handler() (events.APIGatewayProxyResponse, error) {
// Getting JSON as []byte
b, err := convertTasksToJSON()
status := 200
if err != nil {
status = 500
}
return events.APIGatewayProxyResponse {
Body: string(b[:]),
StatusCode: status,
}, err
}
func convertTasksToJSON() ([]byte, error) {
user1 := User {
Username: "emirbarucija",
FirstName: "Emir",
LastName: "Baručija",
}
user2 := User {
Username: "noviUser",
FirstName: "Novi",
LastName: "User",
}
project1 := Project {
Name: "GO language project",
Description: "Making Web API in GO language",
Leader: user1,
}
project2 := Project {
Name: "Movie collection",
Description: "Collection of movies, listed by categories. Make Web API in Java, and connect it with frontend application",
Leader: user2,
}
task1 := Task {
Title: "First task",
Description: "This is my first task in GO language",
UsersOnTask: []User{user1},
Date: "10.04.2018.",
TaskProject: project1,
}
task2 := Task {
Title: "Second task",
Description: "This is my second task in GO language",
UsersOnTask: []User{user1},
Date: "14.04.2018.",
TaskProject: project1,
}
task3 := Task {
Title: "Models in Java",
Description: "The goal of task is to make some models for Java application",
UsersOnTask: []User{user2},
Date: "05.02.2018.",
TaskProject: project2,
}
task4 := Task {
Title: "Controllers in Java",
Description: "The goal is to make controllers for CRUD operations on models",
UsersOnTask: []User{user1, user2},
Date: "15.02.2018.",
TaskProject: project2,
}
task5 := Task {
Title: "Correct menu items positions",
Description: "Items in menu need to be corrected via CSS, all items should be of the same size and aligned in the same way",
UsersOnTask: []User{user1},
Date: "12.03.2018.",
TaskProject: project2,
}
task6 := Task {
Title: "Diplay entries from database in list",
Description: "Categories from the database need to be displayed in the list of the Categories menu",
UsersOnTask: []User{user1, user2},
Date: "24.03.2018.",
TaskProject: project2,
}
project1.ListOfTasks = []Task{task1, task2}
project2.ListOfTasks = []Task{task3, task4, task5, task6}
user1.ListOfTasks = []Task{task1, task2, task4, task5, task6}
user2.ListOfTasks = []Task{task3, task4, task6}
tasks := []Task{task1, task2, task3, task4, task5, task6}
b, err := json.Marshal(tasks)
return b, err
}
func (u User) String() string {
return fmt.Sprintf("Username: %v\nFirst name: %v\nLast name: %v\nTAsks: %v", u.Username, u.FirstName, u.LastName, u.ListOfTasks)
}
func (t Task) String() string {
return fmt.Sprintf("Title: %v\nDescription: %v\nUsers: %v\nDate: %v\nProject: %v", t.Title, t.Description, t.UsersOnTask, t.Date, t.TaskProject)
}
func (p Project) String() string {
return fmt.Sprintf("Name: %v\nDescription: %v\nLeader: %v", p.Name, p.Description, p.Leader)
}

View File

@@ -1,2 +0,0 @@
# Serverless directories
.serverless

View File

@@ -1,6 +0,0 @@
build:
go get github.com/aws/aws-lambda-go/lambda
go get github.com/aws/aws-lambda-go/events
set GOOS=linux
go build -o bin/Task_API Tasks.go
C:\Users\Emir\go\bin\build-lambda-zip.exe -o bin/Task_API.zip bin/Task_API

View File

@@ -1,149 +0,0 @@
package main
import (
"fmt"
"encoding/json"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
type User struct {
Username string
FirstName string
LastName string
ListOfTasks []Task
}
type Project struct {
Name string
Description string
Leader User
ListOfTasks []Task
}
type Task struct {
Title string
Description string
UsersOnTask []User
Date string
TaskProject Project
}
func main() {
lambda.Start(Handler)
}
func Handler() (events.APIGatewayProxyResponse, error) {
// Getting JSON as []byte
b, err := convertTasksToJSON()
status := 200
if err != nil {
status = 500
}
return events.APIGatewayProxyResponse {
Body: string(b[:]),
StatusCode: status,
}, err
}
func convertTasksToJSON() ([]byte, error) {
user1 := User {
Username: "emirbarucija",
FirstName: "Emir",
LastName: "Baručija",
}
user2 := User {
Username: "noviUser",
FirstName: "Novi",
LastName: "User",
}
project1 := Project {
Name: "GO language project",
Description: "Making Web API in GO language",
Leader: user1,
}
project2 := Project {
Name: "Movie collection",
Description: "Collection of movies, listed by categories. Make Web API in Java, and connect it with frontend application",
Leader: user2,
}
task1 := Task {
Title: "First task",
Description: "This is my first task in GO language",
UsersOnTask: []User{user1},
Date: "10.04.2018.",
TaskProject: project1,
}
task2 := Task {
Title: "Second task",
Description: "This is my second task in GO language",
UsersOnTask: []User{user1},
Date: "14.04.2018.",
TaskProject: project1,
}
task3 := Task {
Title: "Models in Java",
Description: "The goal of task is to make some models for Java application",
UsersOnTask: []User{user2},
Date: "05.02.2018.",
TaskProject: project2,
}
task4 := Task {
Title: "Controllers in Java",
Description: "The goal is to make controllers for CRUD operations on models",
UsersOnTask: []User{user1, user2},
Date: "15.02.2018.",
TaskProject: project2,
}
task5 := Task {
Title: "Correct menu items positions",
Description: "Items in menu need to be corrected via CSS, all items should be of the same size and aligned in the same way",
UsersOnTask: []User{user1},
Date: "12.03.2018.",
TaskProject: project2,
}
task6 := Task {
Title: "Diplay entries from database in list",
Description: "Categories from the database need to be displayed in the list of the Categories menu",
UsersOnTask: []User{user1, user2},
Date: "24.03.2018.",
TaskProject: project2,
}
project1.ListOfTasks = []Task{task1, task2}
project2.ListOfTasks = []Task{task3, task4, task5, task6}
user1.ListOfTasks = []Task{task1, task2, task4, task5, task6}
user2.ListOfTasks = []Task{task3, task4, task6}
tasks := []Task{task1, task2, task3, task4, task5, task6}
b, err := json.Marshal(tasks)
return b, err
}
func (u User) String() string {
return fmt.Sprintf("Username: %v\nFirst name: %v\nLast name: %v\nTAsks: %v", u.Username, u.FirstName, u.LastName, u.ListOfTasks)
}
func (t Task) String() string {
return fmt.Sprintf("Title: %v\nDescription: %v\nUsers: %v\nDate: %v\nProject: %v", t.Title, t.Description, t.UsersOnTask, t.Date, t.TaskProject)
}
func (p Project) String() string {
return fmt.Sprintf("Name: %v\nDescription: %v\nLeader: %v", p.Name, p.Description, p.Leader)
}

View File

@@ -1,19 +0,0 @@
service: Task_API_service
provider:
name: aws
runtime: go1.x
package:
exclude:
- ./**
include:
- ./bin/**
functions:
Task_API:
handler: bin/Task_API
events:
- http:
path: tasks
method: GET

View File

@@ -79,6 +79,7 @@ module.exports = function(proxy, allowedHost) {
// See https://github.com/facebookincubator/create-react-app/issues/387. // See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true, disableDotRule: true,
}, },
historyApiFallback: true,
public: allowedHost, public: allowedHost,
proxy, proxy,
before(app) { before(app) {

12963
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,10 @@
"react": "^16.3.1", "react": "^16.3.1",
"react-dev-utils": "^5.0.1", "react-dev-utils": "^5.0.1",
"react-dom": "^16.3.1", "react-dom": "^16.3.1",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"react-test-renderer": "^16.3.1", "react-test-renderer": "^16.3.1",
"redux": "^3.7.2",
"resolve": "1.6.0", "resolve": "1.6.0",
"sass-loader": "^6.0.7", "sass-loader": "^6.0.7",
"style-loader": "0.19.0", "style-loader": "0.19.0",
@@ -59,6 +62,7 @@
"watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive" "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive"
}, },
"jest": { "jest": {
"setupTestFrameworkScriptFile": "<rootDir>/src/setupTests.js",
"collectCoverageFrom": [ "collectCoverageFrom": [
"src/**/*.{js,jsx,mjs}" "src/**/*.{js,jsx,mjs}"
], ],

View File

@@ -19,7 +19,7 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>React App</title> <title>Sutask io</title>
</head> </head>
<body> <body>
<noscript> <noscript>

View File

@@ -1,6 +1,6 @@
{ {
"short_name": "React App", "short_name": "Subtask IO",
"name": "Create React App Sample", "name": "Subtask",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "favicon.ico",

View File

@@ -0,0 +1,6 @@
export const INIT_PAGE = 'INIT_PAGE'
export const initPage = titles => ({
type: INIT_PAGE,
titles
})

View File

@@ -1,9 +1,10 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import {MemoryRouter as Router} from 'react-router-dom'
import App from './index'; import App from './index';
it('renders without crashing', () => { it('renders without crashing', () => {
const div = document.createElement('div'); const div = document.createElement('div');
ReactDOM.render(<App />, div); ReactDOM.render(<Router><App/></Router>, div);
ReactDOM.unmountComponentAtNode(div); ReactDOM.unmountComponentAtNode(div);
}); });

View File

@@ -0,0 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Daoardshb renders correctly 1`] = `
ShallowWrapper {
"length": 1,
Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <HashRouter>
<Unknown
title="Dashboard"
/>
</HashRouter>,
Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function],
"getNode": [Function],
"render": [Function],
"simulateEvent": [Function],
"unmount": [Function],
},
Symbol(enzyme.__node__): Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <Unknown
title="Dashboard"
/>,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {
"title": "Dashboard",
},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <Unknown
title="Dashboard"
/>,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {
"title": "Dashboard",
},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
"options": Object {
"enableComponentDidUpdateOnSetState": true,
},
},
},
}
`;

View File

@@ -0,0 +1,13 @@
import React from 'react';
import {HashRouter as Router} from 'react-router-dom'
import {Dashboard} from './index';
import {shallow} from 'enzyme'
import renderer from 'react-test-renderer';
test('Daoardshb renders correctly', () => {
const props = {
title: 'Dashboard'
}
const component = shallow((<Router><Dashboard {...props} /></Router>))
expect(component).toMatchSnapshot();
});

View File

@@ -0,0 +1,16 @@
import React from 'react';
import { connect } from 'react-redux'
import styles from './styles.scss';
import Header from '../Header/index'
export const Dashboard = (props) => {
return <div className={styles.colored}><Header />Title {props.title}</div>;
};
const mapStateToProps = (state) => {
return {
title: state.pageInitialised.titles.title,
}
}
export default connect(mapStateToProps)(Dashboard);

View File

@@ -1,10 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Dummy renders correctly 1`] = `
<div
className={undefined}
>
Hello,
Hamo
</div>
`;

View File

@@ -1,8 +0,0 @@
import React from 'react';
import styles from './styles.scss';
const Dummy = (props) => {
return <div className={styles.colored}>Hello, {props.name}</div>;
};
export default Dummy;

View File

@@ -1,3 +0,0 @@
.colored {
color: blueviolet;
}

View File

@@ -0,0 +1,36 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Header renders correctly 1`] = `
<div
className={undefined}
>
<h1>
SUBTASK
</h1>
<div
className={undefined}
>
<a
className={undefined}
href="#/mytask"
onClick={[Function]}
>
My Task
</a>
<a
className={undefined}
href="#/inbox"
onClick={[Function]}
>
Inbox
</a>
<a
className={undefined}
href="#/dashboard"
onClick={[Function]}
>
Dashboard
</a>
</div>
</div>
`;

View File

@@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import Dummy from './index'; import {HashRouter as Router} from 'react-router-dom'
import Header from './index';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
test('Dummy renders correctly', () => { test('Header renders correctly', () => {
const component = renderer.create( const component = renderer.create(
<Dummy name="Hamo"/>, <Router><Header/></Router>,
); );
let tree = component.toJSON(); let tree = component.toJSON();
expect(tree).toMatchSnapshot(); expect(tree).toMatchSnapshot();
}); });

View File

@@ -0,0 +1,16 @@
import React from 'react';
import { Link } from 'react-router-dom'
import styles from './styles.scss';
export const Header = () => {
return <div className={styles.Header}>
<h1>SUBTASK</h1>
<div className={styles.HeaderContainer}>
<Link className={styles.HeaderContainer} to="/mytask">My Task</Link>
<Link className={styles.HeaderContainer} to="/inbox">Inbox</Link>
<Link className={styles.HeaderContainer} to="/dashboard">Dashboard</Link>
</div>
</div>;
};
export default Header;

View File

@@ -0,0 +1,14 @@
.Header {
padding-top : 6px;
padding-bottom : 6px;
display: flex;
justify-content: space-between;
align-items:center;
display: flex;
margin-left: 8px;
margin-right: 8px;
}
.HeaderContainer {
padding: 10px;
}

View File

@@ -0,0 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Inbox renders correctly 1`] = `
ShallowWrapper {
"length": 1,
Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <HashRouter>
<Unknown
title="Inbox"
/>
</HashRouter>,
Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function],
"getNode": [Function],
"render": [Function],
"simulateEvent": [Function],
"unmount": [Function],
},
Symbol(enzyme.__node__): Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <Unknown
title="Inbox"
/>,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {
"title": "Inbox",
},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <Unknown
title="Inbox"
/>,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {
"title": "Inbox",
},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
"options": Object {
"enableComponentDidUpdateOnSetState": true,
},
},
},
}
`;

View File

@@ -0,0 +1,13 @@
import React from 'react';
import {HashRouter as Router} from 'react-router-dom'
import {shallow} from 'enzyme'
import {Inbox} from './index';
import renderer from 'react-test-renderer';
test('Inbox renders correctly', () => {
const props = {
title: 'Inbox'
}
const component = shallow((<Router><Inbox {...props} /></Router>))
expect(component).toMatchSnapshot();
});

View File

@@ -0,0 +1,16 @@
import React from 'react';
import { connect } from 'react-redux'
import styles from './styles.scss';
import Header from '../Header/index'
export const Inbox = (props) => {
return <div className={styles.colored}><Header />Title {props.title}</div>;
};
const mapStateToProps = (state) => {
return {
title: state.pageInitialised.titles.title,
}
}
export default connect(mapStateToProps)(Inbox);

View File

@@ -0,0 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MyTask renders correctly 1`] = `
ShallowWrapper {
"length": 1,
Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <HashRouter>
<Unknown
title="MyTask"
/>
</HashRouter>,
Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function],
"getNode": [Function],
"render": [Function],
"simulateEvent": [Function],
"unmount": [Function],
},
Symbol(enzyme.__node__): Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <Unknown
title="MyTask"
/>,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {
"title": "MyTask",
},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {
"children": <Unknown
title="MyTask"
/>,
"history": Object {
"action": "POP",
"block": [Function],
"createHref": [Function],
"go": [Function],
"goBack": [Function],
"goForward": [Function],
"length": 1,
"listen": [Function],
"location": Object {
"hash": "",
"pathname": "/",
"search": "",
"state": undefined,
},
"push": [Function],
"replace": [Function],
},
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "function",
"props": Object {
"title": "MyTask",
},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": [Function],
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
"options": Object {
"enableComponentDidUpdateOnSetState": true,
},
},
},
}
`;

View File

@@ -0,0 +1,16 @@
import React from 'react';
import { connect } from 'react-redux'
import styles from './styles.scss';
import Header from '../Header/index'
export const MyTask = (props) => {
return <div className={styles.colored}><Header />Title {props.title}</div>;
};
const mapStateToProps = (state) => {
return {
title: state.pageInitialised.titles.title,
}
}
export default connect(mapStateToProps)(MyTask);

View File

@@ -0,0 +1,14 @@
import React from 'react';
import {HashRouter as Router} from 'react-router-dom'
import {shallow} from 'enzyme'
import {MyTask} from './index';
import renderer from 'react-test-renderer';
test('MyTask renders correctly', () => {
const props = {
title: 'MyTask'
}
const component = shallow((<Router><MyTask {...props} /></Router>))
expect(component).toMatchSnapshot();
});

View File

@@ -0,0 +1,53 @@
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import App from '../index'
import Inbox from '../Inbox/index';
import MyTask from '../Mytask/index';
import Dashboard from '../Dashboard/index';
import { initPage } from '../../../actions/index'
class Root extends Component {
render() {
return (
<Provider store={this.props.store}>
<Router>
<div>
<Route path='/' exact component={App} />
<Route path="/mytask" exact component={mountComponentWithPathAction(MyTask, this.props)} />
<Route path="/inbox" exact component={mountComponentWithPathAction(Inbox, this.props)} />
<Route path="/dashboard" exact component={mountComponentWithPathAction(Dashboard, this.props)} />
</div>
</Router>
</Provider>
);
}
}
/**
* Pass this function to `react-router-dom` Route component property
* In orderd to triger redux action that is related to te Route path
* If such action exists
*
* @param {} WrappedComponent a React component to render
* @param {*} props a an object containing redux `store` to dispach initPage action with route path name
* @returns A new HIGHT ORDER React component from WrappedComponent after redux action is dispatched
*/
let mountComponentWithPathAction = function (WrappedComponent, props) {
return class extends Component {
componentWillMount() {
props.store.dispatch(initPage({ pathName: this.props.location.pathname }))
}
render() {
return <WrappedComponent {...this.props} />
}
}
}
export default Root

View File

@@ -1,20 +1,10 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import logo from '../../logo.svg'; import Header from './Header';
import styles from './styles.scss';
import Dummy from './Dummy';
class App extends Component { class App extends Component {
render() { render() {
return ( return (
<div className={styles.App}> <Header />
<header className={styles["App-header"]}>
<img src={logo} className={styles["App-logo"]} alt="logo" />
<h1 className={styles["App-title"]}><Dummy name="Hamo"/> </h1>
</header>
<p className={styles["App-intro"]}>
To get started ba, edit <code>src/App.js</code> and save to reload.
</p>
</div>
); );
} }
} }

View File

@@ -1,8 +1,15 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { createStore } from 'redux'
import './index.css'; import './index.css';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker'; import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root')); import subtaskIo from './reducers/index'
import Root from './components/App/Root/index';
const store = createStore(subtaskIo)
ReactDOM.render(
<Root store={store} />,
document.getElementById('root'));
registerServiceWorker(); registerServiceWorker();

View File

@@ -0,0 +1,7 @@
import { combineReducers } from 'redux'
import pageInitialised from './router'
const subtaskIo = combineReducers({
pageInitialised,
})
export default subtaskIo

View File

@@ -0,0 +1,14 @@
const pageInitialised = (state = {
titles: { title: 'Default title' },
}, action) => {
switch (action.type) {
case 'INIT_PAGE':
return {
...state,
titles: { title: action.titles.pathName }
}
default:
return state
}
}
export default pageInitialised

View File

@@ -0,0 +1,4 @@
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });