Skip to content

Commit 3846de8

Browse files
author
Grishina Nastiya
committed
Add webpack
1 parent c433256 commit 3846de8

19 files changed

+397
-0
lines changed

.babelrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": ["es2015", "stage-0", "react"],
3+
"plugins": [
4+
["transform-decorators-legacy", "lodash", "add-module-exports"],
5+
]
6+
}

src/action.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { createAction } from 'redux-actions';
2+
3+
4+
const setCurrentTip = createAction('SET_CURRENT_TIP', id => (id));
5+
const closeTips = createAction('CLOSE_TIPS');
6+
const openTips = createAction('OPEN_TIPS');
7+
8+
export default {setCurrentTip, closeTips, openTips }

src/component/Tips.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import CSSModules from 'react-css-modules';
2+
import clickOutsideWrapper from 'react-click-outside';
3+
import styles from './Tips.scss';
4+
import images from '../images';
5+
6+
export default
7+
@clickOutsideWrapper
8+
@CSSModules(styles, {allowMultiple: true})
9+
10+
class Tips extends React.Component {
11+
static propTypes = {
12+
currentTipId: React.PropTypes.number.isRequired,
13+
tips: React.PropTypes.number.isRequired,
14+
open: React.PropTypes.bool.isRequired,
15+
onCloseTips: React.PropTypes.func.isRequired,
16+
setCurrentTip: React.PropTypes.func.isRequired,
17+
};
18+
19+
handleClickOutside(event) {
20+
if (this.props.open) {
21+
this.props.onCloseTips();
22+
event.stopPropagation();
23+
}
24+
}
25+
26+
renderDot(i) {
27+
const active = i === this.props.currentTipId ? "active" : ""
28+
return <span styleName={`dot ${active}`} onClick={() => this.props.setCurrentTip(i)}></span>
29+
}
30+
31+
renderNextButton = () => {
32+
return <button styleName="next-btn" onClick={()=>this.props.setCurrentTip(this.props.currentTipId + 1)}>next</button>
33+
}
34+
35+
renderLastButton = () => {
36+
return <button styleName="last-btn" onClick={this.props.onCloseTips}>{"ok,let's go!"}</button>
37+
}
38+
39+
render() {
40+
const tip = this.props.tips[this.props.currentTipId];
41+
const isLast = this.props.currentTipId === (this.props.tips.length - 1);
42+
return (
43+
<div styleName="body">
44+
<div styleName="close-btn" onClick={this.props.onCloseTips}>SKIP</div>
45+
<div styleName="header">{tip.header}</div>
46+
<div styleName="title">{tip.title}</div>
47+
<img styleName="image"src={images[this.props.currentTipId + 1]}/>
48+
<div styleName="dots-wrap">
49+
{
50+
this.props.tips.map((t,i) => this.renderDot(i))
51+
}
52+
</div>
53+
{isLast ? this.renderLastButton() : this.renderNextButton()}
54+
</div>
55+
);
56+
}
57+
}

src/component/Tips.scss

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
.body {
2+
width: 600px;
3+
height: 600px;
4+
padding: 0;
5+
position: absolute;
6+
top: 50%;
7+
left: 50%;
8+
transform: translate(-50%, -50%) ;
9+
background-color: white;
10+
z-index: 100;
11+
}
12+
.close-btn {
13+
top: 12px;
14+
right: 14px;
15+
cursor: pointer;
16+
opacity: 0.8;
17+
position: absolute;
18+
color: #A0A0A0;
19+
&:hover {
20+
opacity: 1;
21+
}
22+
}
23+
.header {
24+
text-align: center;
25+
margin: 30px 0px 16px;
26+
font-size: 26px;
27+
}
28+
.title {
29+
vertical-align: middle;
30+
text-align: center;
31+
padding: 0;
32+
font-size: 18px;
33+
color: #A0A0A0;
34+
}
35+
36+
.image {
37+
border-radius: 50%;
38+
width: 265px;
39+
height: 265px;
40+
display: block;
41+
margin: 20px auto;
42+
border: 2px solid #E9E9E9;
43+
}
44+
.popup {
45+
animation: fadeIn .3s ease;
46+
position: fixed;
47+
width: 100vw;
48+
height: 100vh;
49+
top: 0;
50+
left: 0;
51+
background-color: rgba(0, 0, 0, 0.6);
52+
z-index: 4;
53+
}
54+
55+
.dots-wrap {
56+
position: relative;
57+
display: inline-block;
58+
left: 50%;
59+
transform: translateX(-50%) ;
60+
}
61+
.dot {
62+
display: inline-block;
63+
border-radius: 50%;
64+
width: 15px;
65+
height: 15px;
66+
background-color: #E9E9E9;
67+
cursor: pointer;
68+
&.active {
69+
background-color: #27AAE1;
70+
}
71+
}
72+
.dot+.dot {
73+
margin-left: 10px;
74+
}
75+
76+
%button {
77+
margin: 0 auto;
78+
padding: 14px 10px;
79+
text-transform: uppercase;
80+
display: block;
81+
border-radius: 5px;
82+
margin-top: 28px;
83+
min-width: 168px;
84+
font-size: 18px;
85+
cursor: pointer;
86+
}
87+
88+
.next-btn {
89+
@extend %button;
90+
border: 2px solid #e9e9e9;
91+
color: #27aae1;
92+
background-color: #fff;
93+
&:hover {
94+
border: 1px solid #27AAE1;
95+
}
96+
}
97+
.last-btn {
98+
@extend %button;
99+
border: 2px solid #27AAE1;
100+
background-color: #27AAE1;
101+
color: #fff;
102+
}

src/component/action.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { createAction } from 'redux-actions';
2+
import { API_SERVICES } from '../config/config';
3+
4+
5+
export const setCurrentTip = createAction('SET_CURRENT_TIP', id => (id));
6+
export const closeTips = createAction('CLOSE_TIPS');
7+
export const openTips = createAction('OPEN_TIPS');

src/component/index.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import CSSModules from 'react-css-modules';
2+
import Transition from 'react-motion-ui-pack';
3+
4+
import Tips from './Tips';
5+
import styles from './Tips.scss';
6+
7+
export default
8+
@CSSModules(styles)
9+
10+
class TipsWrap extends React.Component {
11+
12+
render() {
13+
return (
14+
<Transition enter={{opacity: 1}} leave={{opacity: 0}}>
15+
{ this.props.open &&
16+
<div key="Tips" styleName="popup">
17+
<Tips {...this.props} />
18+
</div>
19+
}
20+
</Transition>
21+
);
22+
}
23+
}

src/container.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { connect } from 'react-redux';
2+
import Tips from './component';
3+
import { isTipsOpen, getTips, getCurrentTipId, tipsCount } from './reducer';
4+
import { closeTips, setCurrentTip } from './action.js';
5+
6+
const mapStateToProps = (state) => {
7+
return {
8+
open: isTipsOpen(state),
9+
currentTipId: getCurrentTipId(state),
10+
tips: getTips(state),
11+
};
12+
};
13+
14+
const mapDispatchToProps = (dispatch) => {
15+
return {
16+
onCloseTips: () => { dispatch(closeTips()); },
17+
setCurrentTip: (id) => {dispatch(setCurrentTip(id))}
18+
};
19+
};
20+
21+
export default connect(mapStateToProps, mapDispatchToProps)(Tips);

src/images/1.png

16 KB
Loading

src/images/2.png

16 KB
Loading

src/images/3.png

16 KB
Loading

src/images/4.png

16 KB
Loading

src/images/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
1: require('./1.png'),
3+
2: require('./2.png'),
4+
3: require('./3.png'),
5+
4: require('./4.png'),
6+
}

src/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import tipsreducer from './reducer';
2+
import TipsContainer from './container';
3+
4+
export {TipsContainer, tipsreducer};

src/reducer/config.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export default [
2+
{
3+
header: "Build Your Shadow Team.",
4+
title: "1. Use players from your lists.",
5+
},
6+
{
7+
header: "Build you app",
8+
title: "Amazing tip about app 2",
9+
},
10+
{
11+
header: "Build you app",
12+
title: "Amazing tip about app 3",
13+
},
14+
{
15+
header: "Build you app",
16+
title: "Amazing tip about app 4",
17+
}
18+
]

src/reducer/currentTip.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Duce from './duce';
2+
3+
class CurretTip extends Duce {
4+
5+
defaultState = 0;
6+
7+
setCurrentTip = (id) => ( this.replace(id) )
8+
}
9+
10+
export default CurretTip.reducer();

src/reducer/duce.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import _ from 'lodash';
2+
3+
export default class Duce {
4+
5+
static RESERVED_FUNCTIONS = ['set', 'reduce', 'delete', 'replace', '_functionMap'];
6+
7+
defaultState = { }
8+
9+
state = { }
10+
11+
replace = (value) => {
12+
return value;
13+
}
14+
15+
set = (key, value) => {
16+
return { ...this.state, [key]: value }
17+
}
18+
19+
delete = (key) => {
20+
return _.omit(this.state, key);
21+
}
22+
23+
union = (key, value) => {
24+
return { ...this.state, [key]: _.union(this.state[key], _.flatten([value])) }
25+
}
26+
27+
without = (key, value) => {
28+
return { ...this.state, [key]: _.without(this.state[key], value) }
29+
}
30+
31+
_functionMap = () => {
32+
const functions = _.omit(_.keyBy(_.functions(this)), Duce.RESERVED_FUNCTIONS);
33+
const functionNames = _.mapKeys(functions, (value, key) => ( _.toUpper(_.snakeCase(key)) ));
34+
return _.mapValues(functionNames, value => ( this[value] ));
35+
}
36+
37+
reduce = () => {
38+
const functionMap = _.memoize(this._functionMap)();
39+
40+
return (state = this.defaultState, action) => {
41+
if (!functionMap[action.type]) return state;
42+
this.state = state;
43+
return functionMap[action.type](action.payload);
44+
}
45+
}
46+
47+
static reducer = function() {
48+
return new this().reduce();
49+
}
50+
51+
}

src/reducer/index.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import tips from './config';
2+
import { combineReducers } from 'redux';
3+
import open from './open';
4+
import currentTip from './currentTip';
5+
6+
const Tips = combineReducers({
7+
open,
8+
currentTip
9+
});
10+
11+
export default Tips;
12+
13+
export const isTipsOpen = state => state.tips.open;
14+
export const getCurrentTipId = state => state.tips.currentTip;
15+
export const getTips = () => tips;

src/reducer/open.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Duce from './duce';
2+
3+
class Open extends Duce {
4+
5+
defaultState = true;
6+
7+
openTips = () => ( this.replace(true) )
8+
closeTips = () => ( this.replace(false) )
9+
}
10+
11+
export default Open.reducer();

0 commit comments

Comments
 (0)