Skip to content

Commit a1c08ad

Browse files
author
Paul Bui-Quang
committed
Massive update
1 parent ce1fe3f commit a1c08ad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+10858
-103132
lines changed

.babelrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"presets": ["react-hmre"]
66
}
77
},
8-
"plugins": ["babel-plugin-add-module-exports"]
8+
"plugins": ["babel-plugin-add-module-exports", "transform-runtime"]
99
}

build/webpack.config.dev.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,16 @@ module.exports = {
3838
test: /\.(js|jsx)$/,
3939
exclude: /node_modules/,
4040
loader: 'babel',
41+
},{
42+
test: /\.(png|jpg|gif)$/,
43+
loader: 'url-loader?limit=8192',
4144
},{ test: /\.json$/, loader: 'json' },
4245
{
4346
test: /.css$/,
4447
loader: 'style-loader!css-loader',
45-
},]
48+
},{
49+
test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
50+
loader: 'file-loader',
51+
}]
4652
}
4753
};

dist/main.js

+100-96,203
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+16-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"scripts": {
77
"clean": "rm -fr ./dist/*",
88
"test": "echo \"Error: no test specified\" && exit 1",
9-
"build": "webpack ./src/main.js ./dist/bundle.js",
9+
"build": "cp src/config.json src/config.dev.json; cp src/config.prod.json src/config.json; webpack --progress --profile; cp src/config.dev.json src/config.json",
1010
"start": "node server.js"
1111
},
1212
"repository": {
@@ -20,45 +20,53 @@
2020
},
2121
"homepage": "https://github.com/pl-buiquang/cap#readme",
2222
"devDependencies": {
23-
"babel-core": "^6.6.5",
23+
"babel-core": "^6.25.0",
2424
"babel-eslint": "^7.1.1",
25-
"babel-loader": "^6.2.4",
25+
"babel-loader": "^6.4.1",
2626
"babel-plugin-add-module-exports": "^0.2.1",
27-
"babel-preset-es2015": "^6.3.13",
27+
"babel-polyfill": "^6.23.0",
28+
"babel-preset-es2015": "^6.24.1",
2829
"babel-preset-react": "^6.3.13",
2930
"babel-preset-react-hmre": "^1.1.1",
30-
"babel-preset-stage-0": "^6.16.0",
31+
"babel-preset-stage-0": "^6.24.1",
3132
"cross-env": "^1.0.7",
3233
"eslint": "^3.10.2",
3334
"eslint-config-airbnb": "^13.0.0",
3435
"eslint-plugin-import": "^2.2.0",
3536
"eslint-plugin-jsx-a11y": "^2.2.3",
3637
"eslint-plugin-react": "^6.7.1",
3738
"eventsource-polyfill": "^0.9.6",
39+
"file-loader": "^0.11.2",
3840
"html-webpack-plugin": "^2.24.1",
3941
"json-loader": "^0.5.4",
4042
"rimraf": "^2.4.3",
43+
"url-loader": "^0.5.9",
4144
"webpack": "^1.12.9",
4245
"webpack-dev-server": "^1.16.2",
4346
"webpack-hot-middleware": "^2.9.1"
4447
},
4548
"dependencies": {
4649
"algoliasearch": "^3.19.1",
4750
"babel-loader": "^6.2.8",
51+
"babel-plugin-transform-runtime": "^6.23.0",
4852
"cross-env": "^3.1.3",
4953
"css-loader": "^0.26.0",
5054
"json-loader": "^0.5.4",
51-
"leaflet": "^1.0.1",
55+
"leaflet": "^1.0.3",
56+
"leaflet.markercluster": "^1.0.6",
5257
"perfect-scrollbar": "^0.6.14",
5358
"react": "^15.4.0",
59+
"react-addons-css-transition-group": "^15.6.0",
5460
"react-dom": "^15.4.0",
55-
"react-leaflet": "^1.0.0-rc.3",
61+
"react-leaflet": "^1.3.1",
62+
"react-leaflet-markercluster": "^1.1.6",
5663
"react-perfect-scrollbar": "^0.1.1",
5764
"react-redux": "^4.4.6",
5865
"react-select": "^1.0.0-rc.2",
5966
"redux": "^3.6.0",
6067
"redux-thunk": "^2.1.0",
6168
"reselect": "^2.5.4",
62-
"style-loader": "^0.13.1"
69+
"style-loader": "^0.13.1",
70+
"whatwg-fetch": "^2.0.3"
6371
}
6472
}

src/components/Alternative/FullView/index.js

+162-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,102 @@
11
import React from 'react';
2+
import config from '../../../utils/config.js';
3+
import {analytics} from '../../../services/requests';
24

35
const STYLE_HEADER = {
46
display: 'flex',
7+
backgroundColor: '#fff',
8+
}
9+
10+
const STYLE_CONTAINER = {
11+
padding: '10px',
12+
}
13+
14+
const STYLE_BACK = {
15+
display: 'flex',
16+
alignItems: 'center',
17+
justifyContent: 'center',
18+
backgroundColor: '#fff',
19+
padding: '10px',
20+
cursor: 'pointer',
21+
}
22+
23+
const STYLE_IMAGE = {
24+
marginTop: '10px',
25+
height: '240px',
26+
backgroundRepeat: 'no-repeat',
27+
backgroundPosition: '50% 50%',
28+
backgroundSize: 'cover',
29+
};
30+
31+
32+
const STYLE_IMAGE_DEFAULT = {
33+
34+
}
35+
36+
const STYLE_CONTENT = {
37+
backgroundColor: '#fff',
38+
}
39+
40+
const processRS = (rs) => {
41+
const configData = config();
42+
rs = rs.replace("<br>", " <br>");
43+
rs = rs.replace("<br/>", " <br/>");
44+
const regex = /(\S+.*:\s*)?(http|https):\/\/(\S+)/g;
45+
const matches = [];
46+
let match = [];
47+
while ((match = regex.exec(rs)) !== null) {
48+
matches.push(match);
49+
}
50+
let links = [];
51+
if (matches) {
52+
links = matches.filter(m => m).map((m,i) => {
53+
let img = <img src={configData.baseURI+'img/misc/web-48.png'} />;
54+
if((m[3] && m[3].search(/(F|f)acebook/) !== -1) || (m[1] && m[1].search(/(F|f)acebook/) !== -1)){
55+
img = <img src={configData.baseURI+'img/misc/facebook-48.png'} />;
56+
}
57+
if((m[3] && m[3].search(/(T|t)witter/) !== -1) || (m[1] && m[1].search(/(T|t)witter/) !== -1)){
58+
img = <img src={configData.baseURI+'img/misc/twitter-48.png'} />;
59+
}
60+
if((m[3] && m[3].search(/(i|I)nstagram/) !== -1) || (m[1] && m[1].search(/(i|I)nstagram/) !== -1)){
61+
img = <img src={configData.baseURI+'img/misc/Instagram-Color.png'} />;
62+
}
63+
if((m[3] && m[3].search(/(Y|y)outube/) !== -1) || (m[1] && m[1].search(/(Y|y)outube/) !== -1)){
64+
img = <img src={configData.baseURI+'img/misc/YouTubeButton.png'} />;
65+
}
66+
return <a key={i} style={{marginRight: '20px'}} href={`${m[2]}://${m[3]}`} target="_blank">{img}</a>;
67+
})
68+
}
69+
return <div>{links}</div>;
70+
}
71+
72+
const processWebsite = (website) => {
73+
const regex = /\s*(lien\s*:|(.*)\s+:)?\s*(\S+)/;
74+
const match = regex.exec(website);
75+
if (match) {
76+
const re2 = /([\S]*)(\s+(;|\/)(.*))?/;
77+
const url = re2.exec(match[3]);
78+
if (!url[1].startsWith("http://") && !url[1].startsWith("http://")) {
79+
url[1] = "http://"+url[1];
80+
}
81+
if (url[4]) {
82+
url[4] == url[4].trim();
83+
if (!url[4].startsWith("http://") && !url[4].startsWith("http://")) {
84+
url[4] = "http://"+url[4];
85+
}
86+
return (
87+
<div>
88+
<a href={url[1]} target="_blank">{url[1]}</a><br />
89+
<a href={url[4]} target="_blank">{url[4]}</a><br />
90+
</div>
91+
);
92+
}
93+
return (
94+
<div>
95+
<a href={url[1]} target="_blank">{url[1]}</a><br />
96+
</div>
97+
);
98+
}
99+
return website;
5100
}
6101

7102
class FullView extends React.Component {
@@ -11,16 +106,78 @@ class FullView extends React.Component {
11106
close: React.PropTypes.func
12107
}
13108

109+
state = {
110+
showMail: false,
111+
}
112+
113+
componentWillReceiveProps (newProps, oldProps){
114+
this.setState({
115+
showMail: false
116+
});
117+
}
118+
119+
showMail = () => {
120+
const {showMail} = this.state;
121+
const {actor} = this.props;
122+
if (!showMail) {
123+
analytics({alt: actor.id, mail: true});
124+
this.setState({
125+
showMail: true
126+
});
127+
}
128+
}
129+
130+
14131
render() {
15132
const {actor, map} = this.props;
133+
const {showMail} = this.state;
134+
const configData = config();
135+
const typology = configData["typology"];
136+
const typoInfo = typology.find(t => t.id === actor.id_typologie);
137+
const typoColor = typoInfo ? typoInfo["color"] : '#fff';
16138
return (
17139
<div>
18-
<div style={STYLE_HEADER}>
19-
<div style={{width: '50%'}}>{actor.name}</div>
20-
<div style={{width: '50%'}}>{map}</div>
140+
<div style={{...STYLE_BACK, backgroundColor: typoInfo["color"]}} onClick={this.props.close}>
141+
Retour à la carte
142+
</div>
143+
<div style={{...STYLE_CONTAINER, backgroundColor: '#fff'}}>
144+
<div style={{...STYLE_HEADER}}>
145+
<div style={{width: '60%'}}>
146+
<div style={{fontFamily: 'Bebas Neue', fontSize: '36px', display: 'flex', justifyContent: 'center'}}><div>{actor.name}</div></div>
147+
<div style={{fontSize: '24px', fontStyle: 'italic', display: 'flex', justifyContent: 'center'}}><div>{actor.orga_initiative}</div></div>
148+
<div className="alt-list-view-image" style={{...STYLE_IMAGE, backgroundImage: `url(${configData.baseURI+actor.presa_image}`}} />
149+
<div style={{fontSize: '14px'}}>{`Crédit photo : ${actor.credit_picto}`}</div>
150+
<div style={{fontSize: '20px'}}>{actor.lieu_initiative}</div>
151+
<div style={{fontSize: '20px'}}>{actor.contact_initiative}</div>
152+
</div>
153+
<div style={{width: '40%', paddingLeft: '10px'}}>
154+
{map}
155+
<div style={{fontSize: '20px', marginTop: '10px',}}>
156+
<i className="fa fa-map-marker" aria-hidden="true" style={{marginRight: '10px'}}></i>
157+
<a target="_blank" href={`https://maps.google.com/?q=${actor.lat_initiative},${actor.long_initiative}&t=m`}>{actor.adress}</a>
158+
</div>
159+
<div style={{fontSize: '20px', marginTop: '10px'}}>{processWebsite(actor.website_initiative)}</div>
160+
<div style={{fontSize: '20px', marginTop: '10px'}}>{processRS(actor.rs_initiative)}</div>
161+
<div style={{fontSize: '20px', marginTop: '10px'}} onClick={this.showMail}>
162+
{showMail ?
163+
(<div>
164+
<div style={{fontSize: '20px', marginTop: '10px'}}><a href={`mailto:${actor.email_initiative}`}>{actor.email_initiative}</a></div>
165+
<div style={{fontSize: '20px', marginTop: '10px'}}>{actor.tel_initiative}</div>
166+
</div>) :
167+
(<div>
168+
<i className="fa fa-address-card" aria-hidden="true" style={{marginRight: '10px'}}></i>
169+
<span style={{cursor: 'pointer'}}>Afficher les informations de contact</span>
170+
</div>)
171+
}
172+
</div>
173+
{actor.horaires_initiative && <div style={{fontSize: '20px', marginTop: '10px'}}><b>Horaires :</b>{` ${actor.horaires_initiative}`}</div>}
174+
</div>
175+
</div>
176+
<div style={STYLE_CONTENT}>
177+
<div style={{fontSize: '20px'}} dangerouslySetInnerHTML={{__html: actor.objet_initiative}} />
178+
<div style={{fontSize: '20px'}} dangerouslySetInnerHTML={{__html: actor.info_initiative}} />
179+
</div>
21180
</div>
22-
<div>{actor.adress}</div>
23-
<div className="tmp-hightlight" onClick={this.props.close}>TODO ajouter un Control a la map pour la re expand</div>
24181
</div>
25182
);
26183
}
+68-30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,52 @@
11
import React from 'react';
2+
import config from '../../../utils/config.js';
3+
4+
5+
const STYLE_ALT_LIST_EXP_CONTAINER = {
6+
display: 'flex',
7+
padding: '10px',
8+
margin: '0px 15px 5px 0px',
9+
cursor: 'pointer',
10+
backgroundColor: '#fff',
11+
};
12+
13+
const STYLE_ALT_LIST_EXP_LEFT = {
14+
flex: '0 0 25%'
15+
};
16+
17+
const STYLE_TYPO = {
18+
flex: '0 0 26px',
19+
height: '26px',
20+
backgroundRepeat: 'no-repeat',
21+
backgroundPosition: '50% 50%',
22+
backgroundSize: 'cover',
23+
}
24+
25+
const STYLE_HEADER = {
26+
display: 'flex',
27+
justifyContent: 'space-between',
28+
}
29+
30+
const STYLE_CONTENT = {
31+
paddingLeft: '15px',
32+
}
33+
34+
const STYLE_NAME = {
35+
fontFamily: 'Bebas Neue',
36+
fontSize: '26px',
37+
marginLeft: '15px',
38+
}
39+
40+
const STYLE_ALT_LIST_EXP_RIGHT = {
41+
flex: '0 0 75%',
42+
};
43+
44+
const STYLE_IMAGE = {
45+
height: '120px',
46+
backgroundRepeat: 'no-repeat',
47+
backgroundPosition: '50% 50%',
48+
backgroundSize: 'cover',
49+
};
250

351
class ResultView extends React.Component {
452
static propTypes = {
@@ -8,43 +56,33 @@ class ResultView extends React.Component {
856
expanded: React.PropTypes.bool,
957
}
1058

11-
state = {
12-
expanded: this.props.expanded,
13-
}
14-
15-
toggleExpand = () => {
16-
const expanded = this.state.expanded;
17-
this.setState({
18-
expanded: !expanded,
19-
});
20-
if (!expanded) {
21-
this.props.focus(this.props.actor.id);
22-
}
59+
focus = () => {
60+
this.props.open(this.props.actor.id);
2361
}
2462

25-
renderExpanded = () => {
63+
render() {
2664
const {name, adress} = this.props.actor;
65+
const configData = config();
66+
const typology = configData["typology"];
67+
const typoInfo = typology.find(t => t.id == this.props.actor.id_typologie);
68+
const typoImg = typoInfo && typoInfo["img"]["small"];
2769
return (
28-
<div>
29-
<h3 className="tmp-hightlight" onClick={this.toggleExpand}>{name}</h3>
30-
<div>{adress}</div>
31-
<div className="tmp-hightlight" onClick={() => this.props.open(this.props.actor.id)}>more</div>
32-
</div>
33-
);
34-
}
35-
36-
renderListItem = () => {
37-
const {name} = this.props.actor;
38-
return (
39-
<div className="tmp-hightlight" onClick={this.toggleExpand}>
40-
{name}
70+
<div style={STYLE_ALT_LIST_EXP_CONTAINER} className="alt-list-view" onClick={this.focus}>
71+
<div style={STYLE_ALT_LIST_EXP_LEFT}>
72+
<div className="alt-list-view-image" style={{...STYLE_IMAGE, backgroundImage: `url(${configData.baseURI+this.props.actor.presa_image}`}} />
73+
</div>
74+
<div style={STYLE_ALT_LIST_EXP_RIGHT}>
75+
<div style={STYLE_HEADER}>
76+
<div style={STYLE_NAME}>{name}</div>
77+
<div style={{...STYLE_TYPO, backgroundImage: `url(${typoImg})`}}/>
78+
</div>
79+
<div style={STYLE_CONTENT}>
80+
<div>{adress}</div>
81+
</div>
82+
</div>
4183
</div>
4284
);
4385
}
44-
45-
render() {
46-
return this.state.expanded ? this.renderExpanded() : this.renderListItem();
47-
}
4886
}
4987

5088
export default ResultView;

0 commit comments

Comments
 (0)