Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 11c191b05f | |||
| 1edb5739a3 | |||
| ad314b49e6 | |||
| db5481118d | |||
| 73ade5e752 | |||
| 26d58036a8 |
@@ -1,15 +1,17 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from 'react-redux';
|
||||
import classnames from "classnames";
|
||||
import _ from "lodash";
|
||||
import PropTypes from "prop-types";
|
||||
import { connect } from "react-redux";
|
||||
import Griddle from "griddle-react";
|
||||
import MoreVertIcon from "@material-ui/icons/MoreVert";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
import EditIcon from "@material-ui/icons/Edit";
|
||||
import MenuIcon from "@material-ui/icons/Menu";
|
||||
import Map from '@material-ui/icons/Map'
|
||||
import red from "@material-ui/core/colors/red";
|
||||
import Collapse from "@material-ui/core/Collapse";
|
||||
import Link from 'next/link'
|
||||
// import { FormattedDate, FormattedTime } from "react-intl";
|
||||
import { withStyles, grey400 } from "@material-ui/core/styles";
|
||||
import {
|
||||
@@ -21,6 +23,9 @@ import {
|
||||
MenuItem
|
||||
} from "@material-ui/core";
|
||||
import GriddleCustomTableComponent from "../custom/GriddleCustomTableComponent";
|
||||
import GoogleMapReact from 'google-map-react';
|
||||
import compose from 'recompose/compose';
|
||||
import withHandlers from 'recompose/withHandlers';
|
||||
|
||||
const styles = theme => ({
|
||||
card: {
|
||||
@@ -92,13 +97,14 @@ class CustomRowComponent extends React.Component {
|
||||
// ClassObjectId nvarchar (Nothing)
|
||||
|
||||
|
||||
//griddle sample https://codesandbox.io/s/r50q23027o
|
||||
render() {
|
||||
const { rowData } = this.props;
|
||||
|
||||
const { rowData, griddleKey } = this.props;
|
||||
// console.log(griddleKey)
|
||||
let interventionDate = new Date(rowData.Dt_Itv);
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader title={rowData.Lbl_Itv} subheader={(interventionDate).toLocaleDateString("fr-FR") + ' ' + interventionDate.toLocaleTimeString("fr-FR", {hour: '2-digit', minute:'2-digit'})}/>
|
||||
<CardHeader title={rowData.Id_Cli} subheader={(interventionDate).toLocaleDateString("fr-FR") + ' ' + interventionDate.toLocaleTimeString("fr-FR", { hour: '2-digit', minute: '2-digit' })} />
|
||||
<CardContent>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
@@ -112,23 +118,33 @@ class CustomRowComponent extends React.Component {
|
||||
>
|
||||
<ExpandMoreIcon />
|
||||
</IconButton>
|
||||
<EditIcon onClick={() => alert('future edit')} />
|
||||
{/* <Link href={{
|
||||
pathname: '/edit',
|
||||
query: {
|
||||
rowData:JSON.stringify(rowData)
|
||||
}
|
||||
}} >
|
||||
<a><EditIcon /></a>
|
||||
</Link> */}
|
||||
</CardActions>
|
||||
<Collapse in={this.state.expanded} timeout="auto" unmountOnExit>
|
||||
<CardContent>
|
||||
<h3>Details</h3>
|
||||
<p>
|
||||
{rowData.Id_Adr_Key}
|
||||
</p>
|
||||
<p>
|
||||
{rowData.Id_Cct_Key}
|
||||
</p>
|
||||
<p>
|
||||
{rowData.Lbm_Itv_Dmd}
|
||||
</p>
|
||||
<p>
|
||||
{rowData.Id_Opr_Itv}
|
||||
</p>
|
||||
<h3>{rowData.Lbc_Cct_1 + ' ' + rowData.Lbc_Cct_2}</h3>
|
||||
<h3>{rowData.Tel_Cct_1}</h3>
|
||||
<h4>{rowData.Lbl_Itv}</h4>
|
||||
<p>{rowData.Lbl_Adr_2}</p>
|
||||
<p>{rowData.Lbl_Adr_3}</p>
|
||||
<p>{rowData.Lbl_Adr_4}</p>
|
||||
<p>{rowData.Lbc_Adr_Vil}</p>
|
||||
{
|
||||
!!rowData.Lbm_Adr && (
|
||||
<Link href={`https://www.google.com/maps/place/${rowData.Lbm_Adr}`}>
|
||||
<a> <Map /></a>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
</CardContent>
|
||||
</Collapse>
|
||||
|
||||
@@ -145,15 +161,14 @@ CustomRowComponent.propTypes = {
|
||||
// eslint-disable-next-line
|
||||
class Intervention extends Component {
|
||||
state = {
|
||||
data: []
|
||||
data: [],
|
||||
currentPage: 0,
|
||||
pageSize: 0,
|
||||
recordCount: 0
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
console.log("componentWillMount Intervention props : ", this.props.data);
|
||||
this.setState({
|
||||
|
||||
data: this.props.data
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() { }
|
||||
@@ -161,11 +176,16 @@ class Intervention extends Component {
|
||||
componentWillReceiveProps(nextProps) {
|
||||
console.log(
|
||||
"componentWillReceiveProps Intervention nextProps",
|
||||
nextProps.data
|
||||
nextProps.data,
|
||||
nextProps.currentPage, nextProps.pageSize, nextProps.recordCount
|
||||
);
|
||||
this.setState({
|
||||
data: nextProps.data
|
||||
data: nextProps.data,
|
||||
currentPage: nextProps.currentPage,
|
||||
pageSize: nextProps.pageSize,
|
||||
recordCount: nextProps.recordCount
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// rowDataSelector = (state, props) => {
|
||||
@@ -198,31 +218,49 @@ class Intervention extends Component {
|
||||
);
|
||||
|
||||
_onNext = () => {
|
||||
// const { currentPage, pageSize, filterText } = this.state;
|
||||
// this.props.fetchUserGamesRequest(currentPage + 1, pageSize, filterText);
|
||||
const { currentPage, pageSize, filterText } = this.state;
|
||||
this.props._onGetPage(currentPage + 1, pageSize, filterText)
|
||||
};
|
||||
|
||||
_onPrevious = () => {
|
||||
// const { currentPage, pageSize, filterText } = this.state;
|
||||
// this.props.fetchUserGamesRequest(currentPage - 1, pageSize, filterText);
|
||||
const { currentPage, pageSize, filterText } = this.state;
|
||||
this.props._onGetPage(currentPage - 1, pageSize, filterText)
|
||||
};
|
||||
|
||||
_onGetPage = pageNumber => {
|
||||
const { pageSize, filterText } = this.state;
|
||||
const { pageSize, filterText } = this.state;
|
||||
|
||||
this.props._onGetPage(pageNumber, pageSize, filterText)
|
||||
|
||||
this.props._onGetPage(pageNumber, pageSize, filterText)
|
||||
.then( (data) => this.setState(data))
|
||||
// this.props.fetchUserGamesRequest(pageNumber, pageSize, filterText);
|
||||
};
|
||||
|
||||
_onFilter = filterText => {
|
||||
// this.setState({ currentPage: 1 });
|
||||
// const { currentPage, pageSize } = this.state;
|
||||
// this.setState({ filterText });
|
||||
const { pageSize } = this.state;
|
||||
this.setState({ filterText });
|
||||
// this.props.fetchUserGamesRequest(currentPage, pageSize, filterText);
|
||||
this.props._onGetPage(1, pageSize, filterText)
|
||||
};
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
// const rowDataSelector = (state, { griddleKey }) => {
|
||||
// return state
|
||||
// .get('data')
|
||||
// .find(rowMap => rowMap.get('griddleKey') === griddleKey)
|
||||
// .toJSON();
|
||||
// };
|
||||
|
||||
// const enhancedWithRowData = connect((state, props) => {
|
||||
// return {
|
||||
// // rowData will be available into MyCustomComponent
|
||||
// rowData: rowDataSelector(state, props)
|
||||
// };
|
||||
// });
|
||||
|
||||
const { data, currentPage, pageSize, recordCount } = this.state;
|
||||
return (
|
||||
<div>
|
||||
@@ -235,7 +273,7 @@ class Intervention extends Component {
|
||||
)}
|
||||
{
|
||||
<Griddle
|
||||
data={this.props.data}
|
||||
data={data}
|
||||
pageProperties={{
|
||||
currentPage,
|
||||
pageSize,
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from 'react-redux';
|
||||
import classnames from "classnames";
|
||||
import _ from "lodash";
|
||||
import PropTypes from "prop-types";
|
||||
import Griddle from "griddle-react";
|
||||
import MoreVertIcon from "@material-ui/icons/MoreVert";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
import EditIcon from "@material-ui/icons/Edit";
|
||||
import MenuIcon from "@material-ui/icons/Menu";
|
||||
import red from "@material-ui/core/colors/red";
|
||||
import Collapse from "@material-ui/core/Collapse";
|
||||
// import { FormattedDate, FormattedTime } from "react-intl";
|
||||
import { withStyles, grey400 } from "@material-ui/core/styles";
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardContent,
|
||||
CardActions,
|
||||
IconButton,
|
||||
MenuItem
|
||||
} from "@material-ui/core";
|
||||
import GriddleCustomTableComponent from "../custom/GriddleCustomTableComponent";
|
||||
import GoogleMapReact from 'google-map-react';
|
||||
import compose from 'recompose/compose';
|
||||
import withHandlers from 'recompose/withHandlers';
|
||||
|
||||
const styles = theme => ({
|
||||
card: {
|
||||
maxWidth: 400
|
||||
},
|
||||
media: {
|
||||
height: 0,
|
||||
paddingTop: "56.25%" // 16:9
|
||||
},
|
||||
actions: {
|
||||
display: "flex"
|
||||
},
|
||||
expand: {
|
||||
transform: "rotate(0deg)",
|
||||
transition: theme.transitions.create("transform", {
|
||||
duration: theme.transitions.duration.shortest
|
||||
}),
|
||||
marginLeft: "auto"
|
||||
},
|
||||
expandOpen: {
|
||||
transform: "rotate(180deg)"
|
||||
},
|
||||
avatar: {
|
||||
backgroundColor: red[500]
|
||||
}
|
||||
});
|
||||
|
||||
const iconButtonElement = (
|
||||
<IconButton touch tooltip="more" tooltipPosition="bottom-left">
|
||||
<MoreVertIcon color={grey400} />
|
||||
</IconButton>
|
||||
);
|
||||
|
||||
const rightIconMenu = (
|
||||
<MenuIcon iconButtonElement={iconButtonElement}>
|
||||
<MenuItem>Call</MenuItem>
|
||||
</MenuIcon>
|
||||
);
|
||||
|
||||
class CustomRowComponent extends React.Component {
|
||||
state = {
|
||||
expanded: false
|
||||
};
|
||||
|
||||
handleExpandClick = () => {
|
||||
this.setState({ expanded: !this.state.expanded });
|
||||
};
|
||||
|
||||
// SchemaName SchemaType Caption
|
||||
// Id_Indice int (Nothing)
|
||||
// Id_Itv nvarchar Code
|
||||
// Id_Res_Aff uniqueidentifier Affaire
|
||||
// Id_Res_Elt uniqueidentifier Elément
|
||||
// Dt_Crt datetime Date création
|
||||
// Dt_Itv datetime Date
|
||||
// Id_Opr_Sas nvarchar Demandeur
|
||||
// Id_Opr_Itv nvarchar Intervenant
|
||||
// Id_Itv_Typ nvarchar Type
|
||||
// Id_Cli nvarchar Code client
|
||||
// Id_Adr_Key nvarchar Adresse
|
||||
// Id_Cct_Key nvarchar Contact
|
||||
// Id_Res_Elt_Fab uniqueidentifier Elément
|
||||
// Lbl_Itv nvarchar Résumé
|
||||
// Lbm_Itv_Dmd nvarchar Demande
|
||||
// Lbm_Itv_Sol nvarchar Description intervention
|
||||
// Ldv_Gar int Garantie
|
||||
// Ldv_Sts int Statut
|
||||
// Dt_Clt datetime Date clôture
|
||||
// ClassObjectId nvarchar (Nothing)
|
||||
|
||||
|
||||
//griddle sample https://codesandbox.io/s/r50q23027o
|
||||
render() {
|
||||
const { rowData, griddleKey } = this.props;
|
||||
console.log(griddleKey)
|
||||
let interventionDate = new Date(rowData.Dt_Itv);
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader title={rowData.Lbl_Itv} subheader={(interventionDate).toLocaleDateString("fr-FR") + ' ' + interventionDate.toLocaleTimeString("fr-FR", { hour: '2-digit', minute: '2-digit' })} />
|
||||
<CardContent>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<IconButton
|
||||
className={classnames(styles.expand, {
|
||||
[styles.expandOpen]: this.state.expanded
|
||||
})}
|
||||
onClick={this.handleExpandClick}
|
||||
aria-expanded={this.state.expanded}
|
||||
aria-label="Show more"
|
||||
>
|
||||
<ExpandMoreIcon />
|
||||
</IconButton>
|
||||
<EditIcon onClick={() => alert('future edit : ' + griddleKey)} />
|
||||
</CardActions>
|
||||
<Collapse in={this.state.expanded} timeout="auto" unmountOnExit>
|
||||
<CardContent>
|
||||
<h3>Details</h3>
|
||||
<p>
|
||||
{rowData.Id_Adr_Key}
|
||||
</p>
|
||||
<p>
|
||||
{rowData.Id_Cct_Key}
|
||||
</p>
|
||||
<p>
|
||||
{rowData.Lbm_Itv_Dmd}
|
||||
</p>
|
||||
<p>
|
||||
{rowData.Id_Opr_Itv}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Collapse>
|
||||
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CustomRowComponent.propTypes = {
|
||||
rowData: PropTypes.func.isRequired,
|
||||
editQuest: PropTypes.func.isRequired,
|
||||
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
class MapInt extends Component {
|
||||
state = {
|
||||
data: [],currentPage:1,
|
||||
pageSize:2, recordCount:5
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({
|
||||
|
||||
data: this.props.data,
|
||||
});
|
||||
this.setState({
|
||||
|
||||
recordCount:5
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() { }
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
console.log(
|
||||
"componentWillReceiveProps Intervention nextProps",
|
||||
nextProps.data
|
||||
);
|
||||
this.setState({
|
||||
data: nextProps.data
|
||||
});
|
||||
}
|
||||
|
||||
// rowDataSelector = (state, props) => {
|
||||
// let o = state
|
||||
// .get("data")
|
||||
// .find(rowMap => rowMap.get("griddleKey") === props.griddleKey);
|
||||
// o = o.concat({ gameId: this.props.gameId });
|
||||
// return o.toJSON();
|
||||
// };
|
||||
|
||||
// enhancedWithRowData = connect((state, props) => ({
|
||||
// editQuest: this.props.edit,
|
||||
// // rowData will be available into MyCustomComponent
|
||||
// rowData: this.rowDataSelector(state, props),
|
||||
// value: this.props.gameId
|
||||
// }));
|
||||
|
||||
NewLayout = ({ Table, Pagination, Filter }) => (
|
||||
<div>
|
||||
<Filter />
|
||||
<Pagination />
|
||||
<Table />
|
||||
</div>
|
||||
);
|
||||
|
||||
CustomTableBody = ({ rowIds, Row, style, className }) => (
|
||||
<div style={style} className={className}>
|
||||
{rowIds && rowIds.map(r => <Row key={r} griddleKey={r} />)}
|
||||
</div>
|
||||
);
|
||||
|
||||
_onNext = () => {
|
||||
// const { currentPage, pageSize, filterText } = this.state;
|
||||
// this.props.fetchUserGamesRequest(currentPage + 1, pageSize, filterText);
|
||||
};
|
||||
|
||||
_onPrevious = () => {
|
||||
// const { currentPage, pageSize, filterText } = this.state;
|
||||
// this.props.fetchUserGamesRequest(currentPage - 1, pageSize, filterText);
|
||||
};
|
||||
|
||||
_onGetPage = pageNumber => {
|
||||
const { pageSize, filterText } = this.state;
|
||||
|
||||
this.props._onGetPage(pageNumber, pageSize, filterText)
|
||||
.then((data) => {console.log('_onGetPage'+
|
||||
data["server.Qtbl_Itv_Sav"]);this.setState({data:data["server.Qtbl_Itv_Sav"]})})
|
||||
|
||||
// this.props.fetchUserGamesRequest(pageNumber, pageSize, filterText);
|
||||
};
|
||||
|
||||
_onFilter = filterText => {
|
||||
// this.setState({ currentPage: 1 });
|
||||
// const { currentPage, pageSize } = this.state;
|
||||
// this.setState({ filterText });
|
||||
// this.props.fetchUserGamesRequest(currentPage, pageSize, filterText);
|
||||
const { pageSize } = this.state;
|
||||
|
||||
this.props._onGetPage(2, pageSize, filterText)
|
||||
.then((data) => this.setState({data}))
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
// const rowDataSelector = (state, { griddleKey }) => {
|
||||
// return state
|
||||
// .get('data')
|
||||
// .find(rowMap => rowMap.get('griddleKey') === griddleKey)
|
||||
// .toJSON();
|
||||
// };
|
||||
|
||||
// const enhancedWithRowData = connect((state, props) => {
|
||||
// return {
|
||||
// // rowData will be available into MyCustomComponent
|
||||
// rowData: rowDataSelector(state, props)
|
||||
// };
|
||||
// });
|
||||
|
||||
const { data, currentPage, pageSize, recordCount } = this.state;
|
||||
return (
|
||||
<div>
|
||||
{!this.props.data && (
|
||||
<div className="text-center">
|
||||
<div className="alert alert-info">
|
||||
Aucune intervention disponnible.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{
|
||||
<Griddle
|
||||
data={this.state.data}
|
||||
pageProperties={{
|
||||
currentPage,
|
||||
pageSize,
|
||||
recordCount
|
||||
}}
|
||||
components={{
|
||||
Layout: this.NewLayout,
|
||||
Row: CustomRowComponent,
|
||||
TableContainer: GriddleCustomTableComponent,
|
||||
TableBody: this.CustomTableBody
|
||||
}}
|
||||
events={{
|
||||
onNext: this._onNext,
|
||||
onPrevious: this._onPrevious,
|
||||
onGetPage: this._onGetPage,
|
||||
onFilter: this._onFilter
|
||||
}}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MapInt;
|
||||
+22
-11
@@ -21,12 +21,15 @@ import ListItem from '@material-ui/core/ListItem';
|
||||
import { ListItemText } from '@material-ui/core';
|
||||
|
||||
import { Spring, animated } from 'react-spring'
|
||||
import Button from '@material-ui/core/Button';
|
||||
import GetApp from '@material-ui/icons/GetApp';
|
||||
import PWAInstallSnack from './PWAInstallSnack'
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
width: '100%',
|
||||
'& a':{
|
||||
textDecoration:'none'
|
||||
'& a': {
|
||||
textDecoration: 'none'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -119,12 +122,12 @@ class Header extends React.Component {
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
<Divider />
|
||||
<Link href="/contact" prefetch >
|
||||
<Link href="/listeSAV" prefetch >
|
||||
<a><ListItem>
|
||||
<ListItemIcon>
|
||||
<SendIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary='contact'>
|
||||
<ListItemText primary='Interventions'>
|
||||
</ListItemText>
|
||||
</ListItem></a>
|
||||
</Link>
|
||||
@@ -140,7 +143,7 @@ class Header extends React.Component {
|
||||
</IconButton>
|
||||
|
||||
<Link href="/" prefetch>
|
||||
<a><div onClick={this.toggle}>
|
||||
<a><div onClick={this.toggle}>
|
||||
<Spring native from={{ x: 0 }} to={{ x: this.state.toggle ? 1 : 0 }} config={{ duration: 1000 }}>
|
||||
{({ x }) => (
|
||||
<animated.div
|
||||
@@ -159,12 +162,20 @@ class Header extends React.Component {
|
||||
</Spring>
|
||||
</div></a>
|
||||
</Link>
|
||||
|
||||
<Link href="/contact" prefetch >
|
||||
<a><Typography className={classes.title} variant="h5" color="inherit" noWrap>
|
||||
Contact
|
||||
</Typography></a>
|
||||
</Link>
|
||||
<PWAInstallSnack >
|
||||
{({ initInstall }) =>
|
||||
|
||||
<Button
|
||||
aria-label='install' variant="contained" color="primary" onClick={initInstall}>
|
||||
<GetApp ></GetApp>
|
||||
<Typography variant="h6" color="inherit">
|
||||
Installer
|
||||
</Typography>
|
||||
</Button>
|
||||
|
||||
}
|
||||
</PWAInstallSnack>
|
||||
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</div >
|
||||
|
||||
@@ -74,10 +74,12 @@ class PWAInstallSnack extends Component {
|
||||
this.setState({ openSnack: false, buttonDisplay: false })
|
||||
|
||||
if(this.iOS())
|
||||
this.setState({ openSnack: false, buttonDisplay: true })
|
||||
this.setState({ buttonDisplay: true })
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
this.setState({ openSnack: false, buttonDisplay: false })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import axios from "axios";
|
||||
import getConfig from 'next/config'
|
||||
|
||||
const { publicRuntimeConfig } = getConfig()
|
||||
export default {
|
||||
intervention: {
|
||||
fetch: (page, pagesize, filter) => {
|
||||
console.log('intervention.fetch')
|
||||
console.log(page, pagesize, filter)
|
||||
let url = publicRuntimeConfig.apiUrl.Qtbl_Itv_Sav
|
||||
url += '?range=' + (page - 1) * pagesize + '-' + ((page * pagesize) - 1)
|
||||
|
||||
if (!!filter)
|
||||
url += `&filter={"Lbl_Itv":{"$regex":"${filter}"}}`
|
||||
|
||||
|
||||
console.log(url)
|
||||
return axios.get(url)
|
||||
}
|
||||
},
|
||||
adresse:
|
||||
{
|
||||
fetch:(ids)=>{
|
||||
console.log('adresse.fetch')
|
||||
console.log(ids)
|
||||
|
||||
let url = publicRuntimeConfig.apiUrl.Atbl_Adr
|
||||
if(!!ids)
|
||||
{
|
||||
url += `?filter={"Id_Adr_Key":{"$in":[${ids.map(i=>'"'+i+'"')}]}}`
|
||||
}
|
||||
console.log(url)
|
||||
return axios.get(url)
|
||||
|
||||
}
|
||||
},
|
||||
client:{
|
||||
fetch:(ids)=>{
|
||||
console.log('client.fetch')
|
||||
console.log(ids)
|
||||
|
||||
let url = publicRuntimeConfig.apiUrl.Atbl_Cli_Ent
|
||||
if(!!ids)
|
||||
{
|
||||
url += `?filter={"Id_Cct_Key":{"$in":[${ids.map(i=>'"'+i+'"')}]}}`
|
||||
}
|
||||
console.log(url)
|
||||
return axios.get(url)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/**
|
||||
* next-auth.config.js Example
|
||||
*
|
||||
* Environment variables for this example:
|
||||
*
|
||||
* PORT=3000
|
||||
* SERVER_URL=http://localhost:3000
|
||||
* MONGO_URI=mongodb://localhost:27017/my-database
|
||||
*
|
||||
* If you wish, you can put these in a `.env` to seperate your environment
|
||||
* specific configuration from your code.
|
||||
**/
|
||||
|
||||
// Load environment variables from a .env file if one exists
|
||||
require('dotenv').load()
|
||||
|
||||
const nextAuthProviders = require('./next-auth.providers')
|
||||
const nextAuthFunctions = require('./next-auth.functions')
|
||||
|
||||
// If we want to pass a custom session store then we also need to pass an
|
||||
// instance of Express Session along with it.
|
||||
const expressSession = require('express-session')
|
||||
const MongoStore = require('connect-mongo')(expressSession)
|
||||
|
||||
// If no store set, NextAuth defaults to using Express Sessions in-memory
|
||||
// session store (the fallback is intended as fallback for testing only).
|
||||
let sessionStore
|
||||
if (process.env.MONGO_URI) {
|
||||
sessionStore = new MongoStore({
|
||||
url: process.env.MONGO_URI,
|
||||
autoRemove: 'interval',
|
||||
autoRemoveInterval: 10, // Removes expired sessions every 10 minutes
|
||||
collection: 'sessions',
|
||||
stringify: false
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = () => {
|
||||
// We connect to the User DB before we define our functions.
|
||||
// next-auth.functions.js returns an async method that does that and returns
|
||||
// an object with the functions needed for authentication.
|
||||
return nextAuthFunctions()
|
||||
.then(functions => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// This is the config block we return, ready to be passed to NextAuth
|
||||
resolve({
|
||||
// Define a port (if none passed, will not start Express)
|
||||
// Note: This project omits a port for NextAuth as it uses Express to
|
||||
// add additional routes for the examples, so it takes control of
|
||||
// starting Express, rather than leaving it to NextAuth.
|
||||
// port: process.env.PORT || 3000,
|
||||
// Secret used to encrypt session data on the server.
|
||||
sessionSecret: 'pwacrypretenonsecrettedsecsessi',
|
||||
// Maximum Session Age in ms (optional, default is 7 days).
|
||||
// The expiry time for a session is reset every time a user revisits
|
||||
// the site or revalidates their session token. This is the maximum
|
||||
// idle time value.
|
||||
sessionMaxAge: 60000 * 60 * 24 * 7,
|
||||
// Session Revalidation in X ms (optional, default is 60 seconds).
|
||||
// Specifies how often a Single Page App should revalidate a session.
|
||||
// Does not impact the session life on the server, but causes clients
|
||||
// to refetch session info (even if it is in a local cache) after N
|
||||
// seconds has elapsed since it was last checked so they always display
|
||||
// state correctly.
|
||||
// If set to 0 will revalidate a session before rendering every page.
|
||||
sessionRevalidateAge: 60000,
|
||||
// Canonical URL of the server (optiona, but recommended).
|
||||
// e.g. 'http://localhost:3000' or 'https://www.example.com'
|
||||
// Used in callbak URLs and email sign in links. It will be auto
|
||||
// generated if not specified, which may cause problems if your site
|
||||
// uses multiple aliases (e.g. 'example.com and 'www.examples.com').
|
||||
serverUrl: process.env.SERVER_URL || null,
|
||||
// Add an Express Session store.
|
||||
expressSession: expressSession,
|
||||
sessionStore: sessionStore,
|
||||
// Define oAuth Providers
|
||||
providers: nextAuthProviders(),
|
||||
// Define functions for manging users and sending email.
|
||||
functions: functions,
|
||||
|
||||
csrf:{whitelist:['/account/user']}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
/**
|
||||
* next-auth.functions.js Example
|
||||
*
|
||||
* This file defines functions NextAuth to look up, add and update users.
|
||||
*
|
||||
* It returns a Promise with the functions matching these signatures:
|
||||
*
|
||||
* {
|
||||
* find: ({
|
||||
* id,
|
||||
* email,
|
||||
* emailToken,
|
||||
* provider,
|
||||
* poviderToken
|
||||
* } = {}) => {},
|
||||
* update: (user) => {},
|
||||
* insert: (user) => {},
|
||||
* remove: (id) => {},
|
||||
* serialize: (user) => {},
|
||||
* deserialize: (id) => {}
|
||||
* }
|
||||
*
|
||||
* Each function returns Promise.resolve() - or Promise.reject() on error.
|
||||
*
|
||||
* This specific example supports both MongoDB and NeDB, but can be refactored
|
||||
* to work with any database.
|
||||
*
|
||||
* Environment variables for this example:
|
||||
*
|
||||
* MONGO_URI=mongodb://localhost:27017/my-database
|
||||
* EMAIL_FROM=username@gmail.com
|
||||
* EMAIL_SERVER=smtp.gmail.com
|
||||
* EMAIL_PORT=465
|
||||
* EMAIL_USERNAME=username@gmail.com
|
||||
* EMAIL_PASSWORD=p4ssw0rd
|
||||
*
|
||||
* If you wish, you can put these in a `.env` to seperate your environment
|
||||
* specific configuration from your code.
|
||||
**/
|
||||
|
||||
// Load environment variables from a .env file if one exists
|
||||
require('dotenv').load()
|
||||
|
||||
// This config file uses MongoDB for User accounts, as well as session storage.
|
||||
// This config includes options for NeDB, which it defaults to if no DB URI
|
||||
// is specified. NeDB is an in-memory only database intended here for testing.
|
||||
const MongoClient = require('mongodb').MongoClient
|
||||
const NeDB = require('nedb')
|
||||
const MongoObjectId = (process.env.MONGO_URI) ? require('mongodb').ObjectId : (id) => { return id }
|
||||
|
||||
// Use Node Mailer for email sign in
|
||||
const nodemailer = require('nodemailer')
|
||||
const nodemailerSmtpTransport = require('nodemailer-smtp-transport')
|
||||
const nodemailerDirectTransport = require('nodemailer-direct-transport')
|
||||
|
||||
// Send email direct from localhost if no mail server configured
|
||||
let nodemailerTransport = nodemailerDirectTransport()
|
||||
if (process.env.EMAIL_SERVER && process.env.EMAIL_USERNAME && process.env.EMAIL_PASSWORD) {
|
||||
nodemailerTransport = nodemailerSmtpTransport({
|
||||
host: process.env.EMAIL_SERVER,
|
||||
port: process.env.EMAIL_PORT || 25,
|
||||
secure: false,
|
||||
auth: {
|
||||
user: process.env.EMAIL_USERNAME,
|
||||
pass: process.env.EMAIL_PASSWORD
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (process.env.MONGO_URI) {
|
||||
// Connect to MongoDB Database and return user connection
|
||||
MongoClient.connect(process.env.MONGO_URI, (err, mongoClient) => {
|
||||
if (err) return reject(err)
|
||||
const dbName = process.env.MONGO_URI.split('/').pop().split('?').shift()
|
||||
const db = mongoClient.db(dbName)
|
||||
return resolve(db.collection('users'))
|
||||
})
|
||||
} else {
|
||||
// If no MongoDB URI string specified, use NeDB, an in-memory work-a-like.
|
||||
// NeDB is not persistant and is intended for testing only.
|
||||
let collection = new NeDB({ autoload: true })
|
||||
collection.loadDatabase(err => {
|
||||
if (err) return reject(err)
|
||||
resolve(collection)
|
||||
})
|
||||
}
|
||||
})
|
||||
.then(usersCollection => {
|
||||
return Promise.resolve({
|
||||
// If a user is not found find() should return null (with no error).
|
||||
find: ({id, email, emailToken, provider} = {}) => {
|
||||
let query = {}
|
||||
|
||||
// Find needs to support looking up a user by ID, Email, Email Token,
|
||||
// and Provider Name + Users ID for that Provider
|
||||
if (id) {
|
||||
query = { _id: MongoObjectId(id) }
|
||||
} else if (email) {
|
||||
query = { email: email }
|
||||
} else if (emailToken) {
|
||||
query = { emailToken: emailToken }
|
||||
} else if (provider) {
|
||||
query = { [`${provider.name}.id`]: provider.id }
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
usersCollection.findOne(query, (err, user) => {
|
||||
if (err) return reject(err)
|
||||
return resolve(user)
|
||||
})
|
||||
})
|
||||
},
|
||||
// The user parameter contains a basic user object to be added to the DB.
|
||||
// The oAuthProfile parameter is passed when signing in via oAuth.
|
||||
//
|
||||
// The optional oAuthProfile parameter contains all properties associated
|
||||
// with the users account on the oAuth service they are signing in with.
|
||||
//
|
||||
// You can use this to capture profile.avatar, profile.location, etc.
|
||||
insert: (user, oAuthProfile) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
usersCollection.insert(user, (err, response) => {
|
||||
if (err) return reject(err)
|
||||
|
||||
// Mongo Client automatically adds an id to an inserted object, but
|
||||
// if using a work-a-like we may need to add it from the response.
|
||||
if (!user._id && response._id) user._id = response._id
|
||||
|
||||
return resolve(user)
|
||||
})
|
||||
})
|
||||
},
|
||||
// The user parameter contains a basic user object to be added to the DB.
|
||||
// The oAuthProfile parameter is passed when signing in via oAuth.
|
||||
//
|
||||
// The optional oAuthProfile parameter contains all properties associated
|
||||
// with the users account on the oAuth service they are signing in with.
|
||||
//
|
||||
// You can use this to capture profile.avatar, profile.location, etc.
|
||||
update: (user, profile) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
usersCollection.update({_id: MongoObjectId(user._id)}, user, {}, (err) => {
|
||||
if (err) return reject(err)
|
||||
return resolve(user)
|
||||
})
|
||||
})
|
||||
},
|
||||
// The remove parameter is passed the ID of a user account to delete.
|
||||
//
|
||||
// This method is not used in the current version of next-auth but will
|
||||
// be in a future release, to provide an endpoint for account deletion.
|
||||
remove: (id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
usersCollection.remove({_id: MongoObjectId(id)}, (err) => {
|
||||
if (err) return reject(err)
|
||||
return resolve(true)
|
||||
})
|
||||
})
|
||||
},
|
||||
// Seralize turns the value of the ID key from a User object
|
||||
serialize: (user) => {
|
||||
// Supports serialization from Mongo Object *and* deserialize() object
|
||||
if (user.id) {
|
||||
// Handle responses from deserialize()
|
||||
return Promise.resolve(user.id)
|
||||
} else if (user._id) {
|
||||
// Handle responses from find(), insert(), update()
|
||||
return Promise.resolve(user._id)
|
||||
} else {
|
||||
return Promise.reject(new Error("Unable to serialise user"))
|
||||
}
|
||||
},
|
||||
// Deseralize turns a User ID into a normalized User object that is
|
||||
// exported to clients. It should not return private/sensitive fields,
|
||||
// only fields you want to expose via the user interface.
|
||||
deserialize: (id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
usersCollection.findOne({ _id: MongoObjectId(id) }, (err, user) => {
|
||||
if (err) return reject(err)
|
||||
|
||||
// If user not found (e.g. account deleted) return null object
|
||||
if (!user) return resolve(null)
|
||||
|
||||
return resolve({
|
||||
id: user._id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
emailVerified: user.emailVerified,
|
||||
admin: user.admin || false
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
// Define method for sending links for signing in over email.
|
||||
sendSignInEmail: ({
|
||||
email = null,
|
||||
url = null
|
||||
} = {}) => {
|
||||
nodemailer
|
||||
.createTransport(nodemailerTransport)
|
||||
.sendMail({
|
||||
to: email,
|
||||
from: process.env.EMAIL_FROM,
|
||||
subject: 'Sign in link',
|
||||
text: `Use the link below to sign in:\n\n${url}\n\n`,
|
||||
html: `<p>Use the link below to sign in:</p><p>${url}</p>`
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
console.error('Error sending email to ' + email, err)
|
||||
}
|
||||
})
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('Generated sign in link ' + url + ' for ' + email)
|
||||
}
|
||||
},
|
||||
|
||||
// Credentials Sign In
|
||||
//
|
||||
// If you use this you will need to define your own way to validate
|
||||
// credentials. Unlike with oAuth or Email Sign In, accounts are not
|
||||
// created automatically so you will need to provide a way to create them.
|
||||
//
|
||||
// This feature is intended for strategies like Two Factor Authentication.
|
||||
//
|
||||
// To disable this option, do not set signin (or set it to null).
|
||||
/*
|
||||
*/
|
||||
signIn: ({form, req}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Should validate credentials (e.g. hash password, compare 2FA token
|
||||
// etc) and return a valid user object from a database.
|
||||
return usersCollection.findOne({
|
||||
email: form.email
|
||||
}, (err, user) => {
|
||||
if (err) return reject(err)
|
||||
if (!user) return resolve(null)
|
||||
|
||||
// Check credentials - e.g. compare bcrypt password hashes
|
||||
if (form.password === "test1234") {
|
||||
// If valid, return user object - e.g. { id, name, email }
|
||||
return resolve(user)
|
||||
} else {
|
||||
// If invalid, return null
|
||||
return resolve(null)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// Session Object (optional)
|
||||
//
|
||||
// The session object that gets returned to the client. You don't need to
|
||||
// specify this function here unless you want to override or extend the
|
||||
// default (e.g. with any other properties you have added to req.session)
|
||||
//
|
||||
// Note: The object returned will be stored in localStorage and visible
|
||||
// client side so do not return data you would not want the user to see.
|
||||
/*
|
||||
session: (session, req) => {
|
||||
if (req.session && req.session.someCustomProperty)
|
||||
session.someCustomProperty = req.session.someCustomProperty
|
||||
|
||||
session.someOtherCustomProperty = "Example custom property"
|
||||
|
||||
return session
|
||||
}
|
||||
*/
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/**
|
||||
* next-auth.providers.js Example
|
||||
*
|
||||
* This file returns a simple array of oAuth Provider objects for NextAuth.
|
||||
*
|
||||
* This example returns an array based on what environment variables are set,
|
||||
* with explicit support for Facebook, Google and Twitter, but it can be used
|
||||
* to add strategies for other oAuth providers.
|
||||
*
|
||||
* Environment variables for this example:
|
||||
*
|
||||
* FACEBOOK_ID=
|
||||
* FACEBOOK_SECRET=
|
||||
* GOOGLE_ID=
|
||||
* GOOGLE_SECRET=
|
||||
* TWITTER_KEY=
|
||||
* TWITTER_SECRET=
|
||||
*
|
||||
* If you wish, you can put these in a `.env` to seperate your environment
|
||||
* specific configuration from your code.
|
||||
**/
|
||||
|
||||
// Load environment variables from a .env file if one exists
|
||||
require('dotenv').load()
|
||||
|
||||
module.exports = () => {
|
||||
let providers = []
|
||||
|
||||
if (process.env.FACEBOOK_ID && process.env.FACEBOOK_SECRET) {
|
||||
providers.push({
|
||||
providerName: 'Facebook',
|
||||
providerOptions: {
|
||||
scope: ['email', 'public_profile']
|
||||
},
|
||||
Strategy: require('passport-facebook').Strategy,
|
||||
strategyOptions: {
|
||||
clientID: process.env.FACEBOOK_ID,
|
||||
clientSecret: process.env.FACEBOOK_SECRET,
|
||||
profileFields: ['id', 'displayName', 'email', 'link']
|
||||
},
|
||||
getProfile(profile) {
|
||||
// Normalize profile into one with {id, name, email} keys
|
||||
return {
|
||||
id: profile.id,
|
||||
name: profile.displayName,
|
||||
email: profile._json.email
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (process.env.LINKEDIN_ID && process.env.LINKEDIN_SECRET) {
|
||||
providers.push({
|
||||
providerName: 'Linkedin',
|
||||
providerOptions: {
|
||||
scope: ['r_emailaddress', 'r_basicprofile']
|
||||
},
|
||||
Strategy: require('passport-linkedin-oauth2').Strategy,
|
||||
strategyOptions: {
|
||||
clientID: process.env.LINKEDIN_ID,
|
||||
clientSecret: process.env.LINKEDIN_SECRET,
|
||||
profileFields: ['r_emailaddress', 'r_basicprofile']
|
||||
},
|
||||
getProfile(profile) {
|
||||
console.log(profile);
|
||||
// Normalize profile into one with {id, name, email} keys
|
||||
return {
|
||||
id: profile.id,
|
||||
// name: profile.displayName,
|
||||
// email: profile._json.email
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if (process.env.GOOGLE_ID && process.env.GOOGLE_SECRET) {
|
||||
providers.push({
|
||||
providerName: 'Google',
|
||||
providerOptions: {
|
||||
scope: ['profile', 'email']
|
||||
},
|
||||
Strategy: require('passport-google-oauth').OAuth2Strategy,
|
||||
strategyOptions: {
|
||||
clientID: process.env.GOOGLE_ID,
|
||||
clientSecret: process.env.GOOGLE_SECRET
|
||||
},
|
||||
getProfile(profile) {
|
||||
// Normalize profile into one with {id, name, email} keys
|
||||
return {
|
||||
id: profile.id,
|
||||
name: profile.displayName,
|
||||
email: profile.emails[0].value
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Twitter doesn't expose emails by default.
|
||||
* If we don't get one NextAuth will create a placeholder in the form
|
||||
* `{provider}-{account-id}@localhost.localdomain`
|
||||
*
|
||||
* To have your Twitter oAuth return emails go to apps.twitter.com and add
|
||||
* links to your Terms and Conditions and Privacy Policy under the "Settings"
|
||||
* tab, then check the "Request email addresses" from users box under the
|
||||
* "Permissions" tab.
|
||||
**/
|
||||
if (process.env.TWITTER_KEY && process.env.TWITTER_SECRET) {
|
||||
providers.push({
|
||||
providerName: 'Twitter',
|
||||
providerOptions: {
|
||||
scope: []
|
||||
},
|
||||
Strategy: require('passport-twitter').Strategy,
|
||||
strategyOptions: {
|
||||
consumerKey: process.env.TWITTER_KEY,
|
||||
consumerSecret: process.env.TWITTER_SECRET,
|
||||
userProfileURL: 'https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true'
|
||||
},
|
||||
getProfile(profile) {
|
||||
// Normalize profile into one with {id, name, email} keys
|
||||
return {
|
||||
id: profile.id,
|
||||
name: profile.displayName,
|
||||
email: (profile.emails && profile.emails[0].value) ? profile.emails[0].value : ''
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return providers
|
||||
}
|
||||
+12
-7
@@ -19,10 +19,7 @@ module.exports = withPlugins(
|
||||
workboxOpts: {
|
||||
globPatterns: ['static/**/*'],
|
||||
globDirectory: '.',
|
||||
runtimeCaching: [
|
||||
{ urlPattern: /.*auth.*/, handler: 'networkOnly' },
|
||||
{ urlPattern: /.*account.*/, handler: 'networkOnly' },
|
||||
{ urlPattern: /^https?.*/, handler: 'networkFirst' },
|
||||
runtimeCaching: [
|
||||
{ urlPattern: /\.(?:png|jpg|jpeg|svg|webp)$/,
|
||||
handler: "cacheFirst",
|
||||
options: {
|
||||
@@ -30,10 +27,16 @@ module.exports = withPlugins(
|
||||
expiration: {
|
||||
maxEntries: 100
|
||||
}
|
||||
}}
|
||||
}
|
||||
},
|
||||
{ urlPattern: /.*auth.*/, handler: 'networkOnly' },
|
||||
{ urlPattern: /.*account.*/, handler: 'networkOnly' },
|
||||
{ urlPattern: /.*/, handler: 'networkFirst' },
|
||||
|
||||
],
|
||||
importScripts:
|
||||
['/static/js/firebase-messaging-sw.js',
|
||||
[
|
||||
//'/static/js/firebase-messaging-sw.js',
|
||||
'/static/js/backgroundSync-sw.js'
|
||||
]
|
||||
},
|
||||
@@ -57,7 +60,9 @@ module.exports = withPlugins(
|
||||
},
|
||||
apiUrl:{
|
||||
'token':'https://poc-api.ag2l.fr:50000/token/',
|
||||
'Qtbl_Itv_Sav': 'https://poc-api.ag2l.fr:50000/rest/server.Qtbl_Itv_Sav'
|
||||
'Qtbl_Itv_Sav': 'https://poc-api.ag2l.fr:50000/rest/server.Qtbl_Itv_Sav',
|
||||
'Atbl_Adr':'https://poc-api.ag2l.fr:50000/rest/server.Atbl_Adr',
|
||||
'Atbl_Cli_Ent':'https://poc-api.ag2l.fr:50000/rest/server.Atbl_Cct_Ent'
|
||||
},
|
||||
ReCAPTCHA:{
|
||||
"siteKey":""
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"firebase": "^5.7.0",
|
||||
"flubber": "^0.4.2",
|
||||
"fs": "^0.0.1-security",
|
||||
"google-map-react": "^1.1.2",
|
||||
"googleapis": "^35.0.0",
|
||||
"griddle": "^0.1.2",
|
||||
"griddle-react": "^1.13.1",
|
||||
@@ -60,6 +61,7 @@
|
||||
"react-redux": "^6.0.0",
|
||||
"react-spring": "^6.1.7",
|
||||
"reactstrap": "^7.0.2",
|
||||
"recompose": "^0.30.0",
|
||||
"start-server-and-test": "^1.7.5",
|
||||
"universal-cookie": "^3.0.7"
|
||||
},
|
||||
|
||||
+22
-17
@@ -4,23 +4,26 @@ import { MuiThemeProvider } from '@material-ui/core/styles';
|
||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||
import JssProvider from 'react-jss/lib/JssProvider';
|
||||
import getPageContext from '../src/getPageContext';
|
||||
|
||||
import axios from "axios";
|
||||
import Router from 'next/router'
|
||||
import getConfig from 'next/config'
|
||||
import Head from 'next/head'
|
||||
|
||||
import { initGA, logPageView } from '../utils/analytics'
|
||||
import setAuthorizationHeader from "../utils/setAuthorizationHeader";
|
||||
|
||||
|
||||
const { publicRuntimeConfig } = getConfig()
|
||||
|
||||
|
||||
function tokenIsValid(tokenExpireString) {
|
||||
if (!!tokenExpireString)
|
||||
return true
|
||||
let tokenExpireDate = new Date(tokenExpireString)
|
||||
if (!!!tokenExpireString)
|
||||
return false
|
||||
|
||||
return (tokenExpireDate.getTime() > Date().now.getTime())
|
||||
var d = new Date(0); // The 0 there is the key, which sets the date to the epoch
|
||||
d.setUTCSeconds(tokenExpireString);
|
||||
|
||||
return (d.getTime() < Date.now())
|
||||
}
|
||||
|
||||
class MyApp extends App {
|
||||
@@ -54,31 +57,33 @@ class MyApp extends App {
|
||||
logPageView()
|
||||
Router.router.events.on('routeChangeComplete', logPageView)
|
||||
}
|
||||
|
||||
|
||||
if (!!localStorage.AG2LToken
|
||||
|| (!!localStorage.AG2LTokenExpireDateTime && tokenIsValid(localStorage.AG2LTokenExpireDateTime))) {
|
||||
if (!!!localStorage.AG2LToken
|
||||
|| !tokenIsValid(localStorage.AG2LTokenExpireDateTime)) {
|
||||
//get a new token
|
||||
const res = await fetch(publicRuntimeConfig.apiUrl.token,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept": "application/json"
|
||||
"Accept": "application/json"
|
||||
},
|
||||
body: 'username=AG2L&grant_type=password&password=AG2L'
|
||||
})
|
||||
|
||||
if(res.ok == true)
|
||||
{
|
||||
if (res.ok == true) {
|
||||
const data = await res.json()
|
||||
|
||||
// setAuthorizationHeader(data.access_token)
|
||||
localStorage.AG2LToken = data.access_token
|
||||
localStorage.AG2LTokenExpireDateTime = new Date(Date.now() + data.expires_in).getTime()
|
||||
axios.defaults.headers.common.authorization = `Bearer ${localStorage.AG2LToken}`;
|
||||
localStorage.AG2LTokenExpireDateTime = new Date(Date.now() + data.expires_in).getTime()
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: + trycatch
|
||||
else {
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// setAuthorizationHeader(localStorage.AG2LToken)
|
||||
axios.defaults.headers.common.authorization = `Bearer ${localStorage.AG2LToken}`;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,295 +0,0 @@
|
||||
import Layout from '../components/MyLayout.js'
|
||||
import axios from 'axios'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Slide from '@material-ui/core/Slide';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import ReCAPTCHA from "react-google-recaptcha";
|
||||
import green from '@material-ui/core/colors/green';
|
||||
import orange from '@material-ui/core/colors/orange';
|
||||
import SnackbarContent from '@material-ui/core/SnackbarContent';
|
||||
import { Transition, config } from 'react-spring'
|
||||
import getConfig from 'next/config'
|
||||
import Head from 'next/head'
|
||||
|
||||
const {publicRuntimeConfig} = getConfig()
|
||||
|
||||
//variable for client side only import
|
||||
let back = ''
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
margin: theme.spacing.unit,
|
||||
maxWidth: '400px', [theme.breakpoints.down('md')]: {
|
||||
maxWidth: `${100 - (theme.spacing.unit)}vw`
|
||||
},
|
||||
|
||||
},
|
||||
wrapper: {
|
||||
maxWidth: '400px',
|
||||
[theme.breakpoints.down('md')]: {
|
||||
maxWidth: `${100 - (theme.spacing.unit)}vw`
|
||||
},
|
||||
},
|
||||
paper: {
|
||||
'& form':{
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: `${100 - (theme.spacing.unit)}vw`
|
||||
},
|
||||
padding: theme.spacing.unit * 2,
|
||||
|
||||
display:'flex',
|
||||
flexWrap: 'wrap',
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
website: {
|
||||
width: 400,
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: `${100 - (theme.spacing.unit)}vw`
|
||||
},
|
||||
},
|
||||
textField: {
|
||||
|
||||
width: '100%'
|
||||
},
|
||||
button: {
|
||||
|
||||
margin: theme.spacing.unit,
|
||||
alignSelf:'flex-end'
|
||||
},
|
||||
link: {
|
||||
|
||||
cursor: 'pointer'
|
||||
},
|
||||
success: {
|
||||
backgroundColor: green[600],
|
||||
},
|
||||
error: {
|
||||
backgroundColor: theme.palette.error.dark,
|
||||
},
|
||||
warning: {
|
||||
backgroundColor: orange[600],
|
||||
},
|
||||
|
||||
spock: {
|
||||
display: 'inline'
|
||||
},
|
||||
errorCaptcha: {
|
||||
border: '2px',
|
||||
borderColor: 'red',
|
||||
borderStyle: 'solid'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let spring = { ...config.default, precision: 0.1 }
|
||||
const recaptchaRef = React.createRef();
|
||||
class Contact extends React.Component {
|
||||
state = {
|
||||
nom:"",
|
||||
prenom:"",
|
||||
mail:"",
|
||||
tel:"",
|
||||
message: "",
|
||||
checked: false,
|
||||
openSnack: false,
|
||||
loading: false,
|
||||
error: false,
|
||||
warning: false,
|
||||
success: false,
|
||||
snackMessage: ""
|
||||
};
|
||||
|
||||
handleMessage = event => {
|
||||
this.setState({ success: false, message: event.target.value })
|
||||
}
|
||||
handleField = e => {
|
||||
this.setState({ success: false, [e.target.name]: e.target.value })
|
||||
}
|
||||
sendMessage = (recaptchaValue) => {
|
||||
|
||||
axios.post("/feedback", {
|
||||
nom:this.state.nom,
|
||||
prenom:this.state.prenom,
|
||||
tel:this.state.tel,
|
||||
mail:this.state.mail,
|
||||
message: this.state.message,
|
||||
recaptchaValue: recaptchaValue
|
||||
}).then(response => {
|
||||
this.setState({ success: true, error: false, warning: false, message: '', snackMessage: "Votre message à bien été envoyé.", loading: false, openSnack: true })
|
||||
}).catch(error => {
|
||||
if (error.status != 500) {
|
||||
if (process.browser) {
|
||||
// client-side-only code
|
||||
back.saveEventDataLocally([{ message: this.state.message, recaptchaValue }]);
|
||||
}
|
||||
this.setState({ success: false, error: false, warning: true,
|
||||
snackMessage: "📴 Votre message n'a pas pu aboutir, mais a été sauvegardé. Nous l'enverrons lorsque nous aurons une meilleure connectivité.",
|
||||
loading: false, openSnack: true })
|
||||
}
|
||||
else
|
||||
this.setState({ success: false, error: true, warning: false,
|
||||
snackMessage: "Une erreur système est survenue.",
|
||||
loading: false, openSnack: true })
|
||||
});
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({ openSnack: false });
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
const recaptchaValue = recaptchaRef.current.getValue();
|
||||
if (this.state.mail === '' || this.state.message === '' || recaptchaValue === '')
|
||||
this.setState({ success: false, error: true, warning: false,
|
||||
snackMessage: "Veuillez entrer les champs necessaires et valider le Captcha.",
|
||||
loading: false, openSnack: true })
|
||||
else
|
||||
this.setState({ success: false, error: false, warning: false, loading: true }, this.sendMessage(recaptchaValue))
|
||||
}
|
||||
config = (item, state) => (state === 'leave' ? [{ duration: 1000 }, spring] : [{ duration: 5000 }, spring])
|
||||
|
||||
async componentDidMount() {
|
||||
//loading lib for client side only
|
||||
let result = await import("../src/backSync.js")
|
||||
back = result.default
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
|
||||
return (
|
||||
<Layout menu={this.props.menu}>
|
||||
<Head>
|
||||
<title>Devis Développement PWA</title>
|
||||
<meta name="description" content="Vous souhaitez créer une PWA, développer des fonctionnalités à votre site web et améliorer l'expérience utilisateur sur votre site internet? Contactez-nous pour parler de votre projet." />
|
||||
<link rel="canonical" href="https://www.application.bzh/contact"/>
|
||||
</Head>
|
||||
<div className={classes.root}>
|
||||
<div className={classes.wrapper}>
|
||||
<Slide direction="right" in={true} mountOnEnter unmountOnExit timeout={800}>
|
||||
<Paper elevation={4} className={classes.paper}>
|
||||
{this.state.loading && (
|
||||
<div className="alert alert-info">
|
||||
<CircularProgress color="secondary" />Validating your inputs...
|
||||
</div>
|
||||
)}
|
||||
{!this.state.loading &&
|
||||
(<form onSubmit={this.handleSubmit}>
|
||||
<TextField
|
||||
id="prenom"
|
||||
name="prenom"
|
||||
label="Prénom"
|
||||
value={this.state.prenom}
|
||||
onChange={this.handleField}
|
||||
className={classes.textField}
|
||||
margin="normal"
|
||||
/>
|
||||
<TextField
|
||||
id="nom"
|
||||
name="nom"
|
||||
label="Nom"
|
||||
value={this.state.nom}
|
||||
onChange={this.handleField}
|
||||
className={classes.textField}
|
||||
margin="normal"
|
||||
/>
|
||||
<TextField
|
||||
id="mail"
|
||||
name="mail"
|
||||
label="Email*"
|
||||
value={this.state.mail}
|
||||
onChange={this.handleField}
|
||||
className={classes.textField}
|
||||
margin="normal"
|
||||
error={this.state.error}
|
||||
/>
|
||||
<TextField
|
||||
id="tel"
|
||||
name="tel"
|
||||
label="Tel"
|
||||
value={this.state.tel}
|
||||
onChange={this.handleField}
|
||||
className={classes.textField}
|
||||
margin="normal"
|
||||
/>
|
||||
<TextField
|
||||
id="standard-multiline-flexible"
|
||||
label="Message*"
|
||||
multiline
|
||||
rowsMax={10}
|
||||
rows={4}
|
||||
value={this.state.message}
|
||||
onChange={this.handleMessage}
|
||||
className={classes.textField}
|
||||
margin="normal"
|
||||
error={this.state.error}
|
||||
/>
|
||||
<div className={this.state.error ? classes.errorCaptcha : ''}>
|
||||
<ReCAPTCHA
|
||||
id="component-outlined"
|
||||
ref={recaptchaRef}
|
||||
sitekey={publicRuntimeConfig.ReCAPTCHA.siteKey}
|
||||
size="normal"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<Button type="submit" variant="outlined" color="secondary" className={classes.button}>
|
||||
Send
|
||||
</Button>
|
||||
<Transition
|
||||
config={this.config}
|
||||
items={this.state.success}
|
||||
from={{ opacity: 0 }}
|
||||
enter={{ opacity: 1 }}
|
||||
leave={{ opacity: 0 }}>
|
||||
{show =>
|
||||
show && (props => <div style={props} className={classes.spock}>🖖</div>)
|
||||
}
|
||||
</Transition>
|
||||
</form>)
|
||||
}
|
||||
</Paper>
|
||||
</Slide>
|
||||
</div>
|
||||
<br></br>
|
||||
<div>
|
||||
<Paper elevation={4} className={classes.website}>
|
||||
<a href={publicRuntimeConfig.eDeclicUrl} >
|
||||
<Typography variant="subtitle1" color="secondary" className={classes.link} >
|
||||
www.e-declic.com
|
||||
</Typography>
|
||||
</a>
|
||||
</Paper>
|
||||
</div>
|
||||
</div>
|
||||
<Snackbar
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
open={this.state.openSnack}
|
||||
onClose={this.handleClose}
|
||||
autoHideDuration={6000}
|
||||
TransitionComponent={(props)=><Slide {...props} direction="left" />}
|
||||
ContentProps={{
|
||||
'aria-describedby': 'message-id',
|
||||
}}
|
||||
>
|
||||
<SnackbarContent
|
||||
aria-describedby="message-id"
|
||||
className={classes[this.state.error ? 'error' : this.state.warning ? 'warning' : 'success']}
|
||||
message={<span id="message-id">{this.state.snackMessage}</span>}
|
||||
/>
|
||||
</Snackbar>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(Contact)
|
||||
@@ -0,0 +1,62 @@
|
||||
import React, { Component } from 'react'
|
||||
|
||||
import Layout from '../components/MyLayout.js'
|
||||
import { withStyles } from "@material-ui/core/styles";
|
||||
import Head from 'next/head'
|
||||
const styles = theme => ({})
|
||||
class edit extends Component {
|
||||
|
||||
state = {
|
||||
data: []
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
console.log('edit', this.props)
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
||||
this.setState({ data: nextProps.data })
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
// this.setState({...this.state, loading: true });
|
||||
// e.preventDefault();
|
||||
|
||||
// const errors = this.validate(this.state);
|
||||
// this.setState({ errors });
|
||||
// if (Object.keys(errors).length === 0) {
|
||||
// console.log( " if (Object.keys(errors).length === 0) {", this.state);
|
||||
|
||||
// this.props.submit(this.state);
|
||||
// }
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, menu } = this.props;
|
||||
const { data } = this.state;
|
||||
return (
|
||||
<Layout menu={menu}>
|
||||
<Head>
|
||||
<title>AG2L SAV</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="canonical" href="https://AG2L-pwa.bzh" />
|
||||
</Head>
|
||||
<div className={classes.root}>
|
||||
|
||||
<div className="container">
|
||||
<h3>{data.Lbl_Itv}</h3>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label htmlFor="gameTitle">Descriptif</label>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(edit)
|
||||
+37
-20
@@ -5,6 +5,7 @@ import Head from 'next/head'
|
||||
import _ from 'lodash'
|
||||
import getConfig from 'next/config'
|
||||
import FormatListNumbered from '@material-ui/icons/FormatListNumbered'
|
||||
import Map from '@material-ui/icons/Map'
|
||||
import Card from '@material-ui/core/Card';
|
||||
import CardActionArea from '@material-ui/core/CardActionArea';
|
||||
import CardContent from '@material-ui/core/CardContent';
|
||||
@@ -21,22 +22,25 @@ const styles = theme => ({
|
||||
height: 250,
|
||||
width: 400
|
||||
},
|
||||
|
||||
|
||||
icon: {
|
||||
fontSize: '64px',
|
||||
margin: 'auto',
|
||||
textAlign: 'center'
|
||||
|
||||
},
|
||||
innerCard:{
|
||||
display:'flex',
|
||||
flexDirection: 'column'
|
||||
innerCard: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
},
|
||||
|
||||
text: {
|
||||
justifyContent: 'center',
|
||||
textAlign:'center'
|
||||
}
|
||||
textAlign: 'center'
|
||||
},
|
||||
card:{
|
||||
margin:theme.spacing.unit,
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -47,7 +51,7 @@ class Index extends React.Component {
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -63,21 +67,34 @@ class Index extends React.Component {
|
||||
|
||||
<div className={classes.root}>
|
||||
|
||||
|
||||
|
||||
<Card className={classes.card}>
|
||||
<Link href={"listeSAV"} prefetch><a>
|
||||
<CardActionArea >
|
||||
<CardContent>
|
||||
<div className={classes.innerCard + ' '+classes.icon}>
|
||||
|
||||
<FormatListNumbered className={classes.icon} />
|
||||
<Typography variant='h3' className={classes.text}>Interventions</Typography>
|
||||
</div>
|
||||
</CardContent>
|
||||
</CardActionArea></a>
|
||||
</Link>
|
||||
</Card>
|
||||
|
||||
<CardActionArea >
|
||||
<CardContent>
|
||||
<div className={classes.innerCard + ' ' + classes.icon}>
|
||||
|
||||
<FormatListNumbered className={classes.icon} />
|
||||
<Typography variant='h3' className={classes.text}>Interventions</Typography>
|
||||
</div>
|
||||
</CardContent>
|
||||
</CardActionArea></a>
|
||||
</Link>
|
||||
</Card>
|
||||
{/* <Card className={classes.card}>
|
||||
<Link href={"listeMap"} prefetch><a>
|
||||
<CardActionArea >
|
||||
<CardContent>
|
||||
<div className={classes.innerCard + ' ' + classes.icon}>
|
||||
|
||||
<Map className={classes.icon} />
|
||||
<Typography variant='h3' className={classes.text}>Map</Typography>
|
||||
</div>
|
||||
</CardContent>
|
||||
</CardActionArea></a>
|
||||
</Link>
|
||||
</Card> */}
|
||||
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import React from 'react'
|
||||
import Layout from '../components/MyLayout.js'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Head from 'next/head'
|
||||
import _ from 'lodash'
|
||||
import getConfig from 'next/config'
|
||||
import MapInt from '../components/AG2L/MapInt'
|
||||
import api from '../data/api'
|
||||
|
||||
|
||||
const { publicRuntimeConfig } = getConfig()
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
margin: theme.spacing.unit,
|
||||
height: 250,
|
||||
width: 400
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
class ListeSAV extends React.Component {
|
||||
state = {
|
||||
data: []
|
||||
};
|
||||
|
||||
|
||||
async componentWillMount() {
|
||||
|
||||
}
|
||||
|
||||
//example requete adress:
|
||||
//https://poc-api.ag2l.fr:50000/rest/server.Atbl_Adr?filter={"Id_Adr_Key":"Cli.ARMORACIER22F.112731"}
|
||||
async componentDidMount() {
|
||||
console.log('ListeMap componentDidMount')
|
||||
if (!!localStorage.AG2LToken) {
|
||||
|
||||
let res = await api.intervention.fetch(1,2,'')
|
||||
|
||||
if (res.ok == true) {
|
||||
res.headers.forEach(function (val, key) { console.log(key + ' -> ' + val); });
|
||||
const data = await res.json()
|
||||
console.log(data)
|
||||
this.setState({ data: data["server.Qtbl_Itv_Sav"] })
|
||||
}
|
||||
else {
|
||||
//TODO: + trycatch
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onGetPage = (pageNumber, pageSize) => {
|
||||
console.log('onGetPage')
|
||||
console.log(pageNumber, pageSize)
|
||||
let from = pageNumber * pageSize;
|
||||
let to = from + pageSize
|
||||
let requestSuffix = "?range=" + from + '-' + to
|
||||
|
||||
|
||||
// axios.defaults.headers.common.authorization = `Bearer ${localStorage.AG2LToken}`;
|
||||
// return axios.get(publicRuntimeConfig.apiUrl.Qtbl_Itv_Sav + requestSuffix)
|
||||
// .then((res) => {console.log(res)
|
||||
// if (res.ok == true) {
|
||||
// res.headers.forEach(function (val, key) { console.log(key + ' -> ' + val); });
|
||||
// return res.json()
|
||||
|
||||
// }
|
||||
// else {
|
||||
// //TODO: + trycatch
|
||||
// return null
|
||||
// }
|
||||
// } )
|
||||
|
||||
return fetch(publicRuntimeConfig.apiUrl.Qtbl_Itv_Sav + requestSuffix,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
'Authorization': 'Bearer ' + localStorage.AG2LToken
|
||||
}
|
||||
}).then(
|
||||
(res) => {
|
||||
if (res.ok == true) {
|
||||
res.headers.forEach(function (val, key) { console.log(key + ' -> ' + val); });
|
||||
return res.json()
|
||||
|
||||
}
|
||||
else {
|
||||
//TODO: + trycatch
|
||||
return null
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, menu } = this.props;
|
||||
const { data } = this.state;
|
||||
return (
|
||||
<Layout menu={menu}>
|
||||
<Head>
|
||||
<title>AG2L SAV</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="canonical" href="https://AG2L-pwa.bzh" />
|
||||
</Head>
|
||||
|
||||
<div className={classes.root}>
|
||||
<MapInt data={data}
|
||||
_onGetPage={this.onGetPage}></MapInt>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(styles)(ListeSAV)
|
||||
+86
-47
@@ -5,7 +5,9 @@ import Head from 'next/head'
|
||||
import _ from 'lodash'
|
||||
import getConfig from 'next/config'
|
||||
import Intervention from '../components/AG2L/Intervention'
|
||||
|
||||
import axios from "axios";
|
||||
import api from '../data/api'
|
||||
import { resolve } from 'bluebird';
|
||||
|
||||
const { publicRuntimeConfig } = getConfig()
|
||||
|
||||
@@ -29,58 +31,92 @@ class ListeSAV extends React.Component {
|
||||
|
||||
}
|
||||
|
||||
//example requete adress:
|
||||
//https://poc-api.ag2l.fr:50000/rest/server.Atbl_Adr?filter={"Id_Adr_Key":"Cli.ARMORACIER22F.112731"}
|
||||
//https://poc-api.ag2l.fr:50000/rest/server.Ttbl_Aff_Elt?filter={Id_Res_Hg:"c7edb876-15e7-4dfe-be37-2498beb6457c"}
|
||||
async componentDidMount() {
|
||||
axios.defaults.headers.common.authorization = `Bearer ${localStorage.AG2LToken}`;
|
||||
|
||||
if (!!localStorage.AG2LToken) {
|
||||
|
||||
const res = await fetch(publicRuntimeConfig.apiUrl.Qtbl_Itv_Sav + '?range=0-1',
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
'Authorization': 'Bearer ' + localStorage.AG2LToken,
|
||||
}
|
||||
})
|
||||
|
||||
if (res.ok == true) {
|
||||
res.headers.forEach(function (val, key) { console.log(key + ' -> ' + val); });
|
||||
const data = await res.json()
|
||||
console.log(data)
|
||||
this.setState({ data: data["server.Qtbl_Itv_Sav"] })
|
||||
}
|
||||
else {
|
||||
//TODO: + trycatch
|
||||
}
|
||||
}
|
||||
this.onGetPage(1, 20)
|
||||
|
||||
}
|
||||
|
||||
onGetPage = (pageNumber, pageSize) => {
|
||||
let from = pageNumber * pageSize;
|
||||
let to = from + pageSize
|
||||
let requestSuffix = "?range=" + from + '-' + to
|
||||
return fetch(publicRuntimeConfig.apiUrl.Qtbl_Itv_Sav + requestSuffix,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
'Authorization': 'Bearer ' + localStorage.AG2LToken
|
||||
onGetPage = (pageNumber, pageSize, filter) => {
|
||||
console.log('onGetPage')
|
||||
console.log(pageNumber, pageSize, filter)
|
||||
return api.intervention.fetch(pageNumber, pageSize, filter).then(
|
||||
(res) => {
|
||||
if (res.status === 206 || res.status === 200) {
|
||||
let cr = res.headers['content-range']
|
||||
let crRegexp = /(\d*)-(\d*)\/(\d*)/
|
||||
let ranges = cr.match(crRegexp)
|
||||
|
||||
let from = ranges[1] * 1//hack: to transform to a number
|
||||
|
||||
let size = ranges[3] * 1
|
||||
this.setState({ currentPage: pageNumber, pageSize: pageSize, recordCount: size })
|
||||
return res.data["server.Qtbl_Itv_Sav"]
|
||||
}
|
||||
}).then(
|
||||
(res) => {
|
||||
if (res.ok == true) {
|
||||
res.headers.forEach(function (val, key) { console.log(key + ' -> ' + val); });
|
||||
res.json().then(
|
||||
(j) => {return j}
|
||||
)
|
||||
|
||||
}
|
||||
else {
|
||||
//TODO: + trycatch
|
||||
return null
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw false;
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
.then((data) => {
|
||||
if (!!data) {
|
||||
let tab = data
|
||||
|
||||
let addrIds = tab.map(a => a.Id_Adr_Key)
|
||||
console.log(addrIds)
|
||||
return api.adresse.fetch(addrIds).then((res) => {
|
||||
if (res.status === 200) {
|
||||
let raw = res.data["server.Atbl_Adr"];
|
||||
|
||||
const merged = [...tab.concat(raw).reduce((m, o) =>
|
||||
m.set(o.Id_Adr_Key, Object.assign(m.get(o.Id_Adr_Key) || {}, o))
|
||||
, new Map()).values()];
|
||||
|
||||
console.log(merged);
|
||||
this.setState({ data: merged });
|
||||
return merged;
|
||||
// raw.Lbc_Adr_1
|
||||
// raw.Lbl_Adr_2
|
||||
// raw.Lbl_Adr_3
|
||||
// raw.Lbl_Adr_4
|
||||
// raw.Lbc_Adr_Vil
|
||||
// raw.Id_Adr_Cp
|
||||
// raw.Id_Adr_Pys
|
||||
// raw.Lbm_Adr
|
||||
}
|
||||
|
||||
}).catch(() => this.setState({ data: null }))
|
||||
}
|
||||
})
|
||||
.then((r) => {
|
||||
if (!!r) {
|
||||
let tab = r
|
||||
|
||||
let contactIds = tab.map(a => a.Id_Cct_Key)
|
||||
console.log(contactIds)
|
||||
api.client.fetch(contactIds).then((res) => {
|
||||
if (res.status === 200) {
|
||||
let raw = res.data["server.Atbl_Cct_Ent"];
|
||||
|
||||
const merged = [...tab.concat(raw).reduce((m, o) =>
|
||||
m.set(o.Id_Cct_Key, Object.assign(m.get(o.Id_Cct_Key) || {}, o))
|
||||
, new Map()).values()];
|
||||
|
||||
console.log(merged);
|
||||
this.setState({ data: merged });
|
||||
return merged;
|
||||
}
|
||||
|
||||
}).catch(() => this.setState({ data: null }))
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(() => this.setState({ data: null }))
|
||||
|
||||
}
|
||||
|
||||
@@ -92,11 +128,14 @@ class ListeSAV extends React.Component {
|
||||
<Head>
|
||||
<title>AG2L SAV</title>
|
||||
<meta name="description" content="" />
|
||||
<link rel="canonical" href="https://AG2L-pwa.bzh" />
|
||||
<link rel="canonical" href="https://ag2l.e-declic.net" />
|
||||
</Head>
|
||||
|
||||
<div className={classes.root}>
|
||||
<Intervention data={data}
|
||||
currentPage={this.state.currentPage}
|
||||
pageSize={this.state.pageSize}
|
||||
recordCount={this.state.recordCount}
|
||||
_onGetPage={this.onGetPage}></Intervention>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
|
||||
require('dotenv').load()
|
||||
const utils = require('./src/utils');
|
||||
const mailer = require("./src/mailer.js")
|
||||
const { google } = require('googleapis');
|
||||
//const express = require('express')
|
||||
const express = require('express')
|
||||
const axios = require('axios')
|
||||
const next = require('next')
|
||||
const nextAuth = require('next-auth')
|
||||
const nextAuthConfig = require('./next-auth.config')
|
||||
const { join } = require('path');
|
||||
const { parse } = require('url');
|
||||
|
||||
@@ -16,261 +12,18 @@ const dev = process.env.NODE_ENV !== 'production'
|
||||
const app = next({ dev })
|
||||
const handle = app.getRequestHandler()
|
||||
|
||||
// const passport = require('passport')
|
||||
// const FacebookStrategy = require('passport-facebook').Strategy
|
||||
|
||||
const routes = {
|
||||
admin: require('./routes/admin'),
|
||||
account: require('./routes/account')
|
||||
}
|
||||
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
function getAccessToken() {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var key = require('./service-account.json');
|
||||
var jwtClient = new google.auth.JWT(
|
||||
key.client_email,
|
||||
null,
|
||||
key.private_key,
|
||||
'https://www.googleapis.com/auth/firebase.messaging',
|
||||
null
|
||||
);
|
||||
jwtClient.authorize(function (err, tokens) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(tokens.access_token);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// passport.use(new FacebookStrategy({
|
||||
// clientID: process.env.FACEBOOK_ID,
|
||||
// clientSecret: process.env.FACEBOOK_SECRET,
|
||||
// callbackURL: "http://localhost:3000/auth/facebook/callback",
|
||||
// enableProof: true
|
||||
// },
|
||||
// function (accessToken, refreshToken, profile, cb) {
|
||||
// User.findOrCreate({ facebookId: profile.id }, function (err, user) {
|
||||
// return cb(err, user);
|
||||
// });
|
||||
// console.log(profile)
|
||||
|
||||
// console.log("accessToken : " + accessToken);
|
||||
// console.log("refreshToken" + refreshToken);//****not needed because we only use accesstoken to connect to our api*/
|
||||
|
||||
// return cb(null, profile);
|
||||
// }
|
||||
// ));
|
||||
|
||||
app.prepare()
|
||||
.then(() => {
|
||||
// Load configuration and return config object
|
||||
return nextAuthConfig()
|
||||
})
|
||||
.then(nextAuthOptions => {
|
||||
// Pass Next.js App instance and NextAuth options to NextAuth
|
||||
// Note We do not pass a port in nextAuthOptions, because we want to add some
|
||||
// additional routes before Express starts (if you do pass a port, NextAuth
|
||||
// tells NextApp to handle default routing and starts Express automatically).
|
||||
return nextAuth(app, nextAuthOptions)
|
||||
})
|
||||
.then(nextAuthOptions => {
|
||||
|
||||
const express = nextAuthOptions.express
|
||||
const expressApp = nextAuthOptions.expressApp
|
||||
|
||||
// Add admin routes
|
||||
routes.admin(expressApp)
|
||||
|
||||
// Add account management route - reuses functions defined for NextAuth
|
||||
routes.account(expressApp, nextAuthOptions.functions)
|
||||
const expressApp = express()
|
||||
|
||||
expressApp.use('/', express.static(__dirname + '/.next/'))
|
||||
|
||||
var jsonParser = bodyParser.json()
|
||||
|
||||
expressApp.post('/feedback', jsonParser, (req, res) => {
|
||||
|
||||
let message = req.body.message;
|
||||
let nom = req.body.nom;
|
||||
let prenom = req.body.prenom;
|
||||
let tel = req.body.tel;
|
||||
let mail = req.body.mail;
|
||||
let recaptchaValue = req.body.recaptchaValue;
|
||||
|
||||
console.log(message);
|
||||
if (message === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message is empty." }
|
||||
}); return;
|
||||
}
|
||||
if (mail === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "email is empty." }
|
||||
}); return;
|
||||
}
|
||||
utils.verifyCaptcha(recaptchaValue)
|
||||
.then(
|
||||
respo => {
|
||||
if (respo.data.success == true) {
|
||||
try {
|
||||
mailer.sendEmail(message, nom, prenom, tel, mail);
|
||||
res.status(200).send({})
|
||||
} catch (err) {
|
||||
res.status(500).send({ message: "Send mail fail." })
|
||||
}
|
||||
}
|
||||
else
|
||||
res.status(500).send({ message: "Captcha invalid." })
|
||||
})
|
||||
.catch(() =>
|
||||
res.status(403).send({ message: "Captcha verification impossible." })
|
||||
)
|
||||
|
||||
});
|
||||
|
||||
expressApp.post('/push/message', jsonParser, (req, res) => {
|
||||
let message = req.body.payload;
|
||||
|
||||
if (message === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message is empty." }
|
||||
}); return;
|
||||
}
|
||||
else {
|
||||
getAccessToken().then((googleAccessToken) => {
|
||||
utils.setAuthorizationHeader(googleAccessToken);
|
||||
// console.log(message);
|
||||
axios.post('https://fcm.googleapis.com/v1/projects/edeclicpwa/messages:send',
|
||||
message
|
||||
).then(r => {
|
||||
console.log("message : "); console.log(r)
|
||||
res.status(200).send({ message: "message sent to firebase" })
|
||||
}
|
||||
)
|
||||
.catch(err => console.log("first catch" + err)
|
||||
//res.status(500).send({ message: "Push error" })
|
||||
)
|
||||
}).catch(err => console.log("second catch" + err)
|
||||
//err => res.status(500).send({ message: "Push error" + err })
|
||||
)
|
||||
|
||||
}
|
||||
})
|
||||
expressApp.get('/push/info/:token', (req, res) => {
|
||||
|
||||
var token = req.params.token
|
||||
if (token === '') {
|
||||
res.status(498).json({
|
||||
errors: { global: "No token specified." }
|
||||
}); return;
|
||||
}
|
||||
|
||||
var url = 'https://iid.googleapis.com/iid/info/' + token + '?details=true'
|
||||
|
||||
utils.setAuthorizationHeaderForIID(process.env.FIREBASE_API_KEY)
|
||||
axios.get(url).then(r => {
|
||||
if (!!r.data.rel && !!r.data.rel.topics) {
|
||||
res.status(200).send({ topics: r.data.rel.topics })
|
||||
}
|
||||
else
|
||||
res.status(200).send({ topics: null })
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
res.status(500).send({ message: "Push error" })
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
expressApp.post('/push/subscribe', jsonParser, (req, res) => {
|
||||
let message = req.body;
|
||||
|
||||
if (message === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message is empty." }
|
||||
}); return;
|
||||
}
|
||||
else {
|
||||
if (message.topic === '' || message.token === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message isnot well formed." }
|
||||
}); return;
|
||||
}
|
||||
|
||||
var url = 'https://iid.googleapis.com/iid/v1/' + message.token + '/rel/topics/' + message.topic
|
||||
|
||||
utils.setAuthorizationHeaderForIID(process.env.FIREBASE_API_KEY)
|
||||
|
||||
axios.post(url)
|
||||
.then(r => {
|
||||
res.status(200).send({ message: "message sent to firebase" })
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
expressApp.post('/push/unsubscribe', jsonParser, (req, res) => {
|
||||
let message = req.body;
|
||||
|
||||
if (message === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message is empty." }
|
||||
}); return;
|
||||
}
|
||||
else {
|
||||
if (message.topic === '' || message.token === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message is not well formed." }
|
||||
}); return;
|
||||
}
|
||||
message.topic = '/topics/' + message.topic
|
||||
var payload = { to: message.topic, registration_tokens: [message.token] }
|
||||
var url = 'https://iid.googleapis.com/iid/v1:batchRemove'
|
||||
|
||||
utils.setAuthorizationHeaderForIID(process.env.FIREBASE_API_KEY)
|
||||
axios.post(url, payload
|
||||
).then(r => {
|
||||
res.status(200).send({ message: "message sent to firebase" })
|
||||
}
|
||||
)
|
||||
.catch(err => console.log(err)
|
||||
)
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
//https://us-central1-edeclicpwa.cloudfunctions.net/pushMessageToAllSubscribers
|
||||
expressApp.post('/push/allsubscribers', jsonParser, (req, res) => {
|
||||
let message = req.body.payload;
|
||||
|
||||
if (message === '') {
|
||||
res.status(400).json({
|
||||
errors: { global: "Message is empty." }
|
||||
}); return;
|
||||
}
|
||||
else {
|
||||
|
||||
utils.setAuthorizationHeader(process.env.FIREBASE_API_KEY)
|
||||
// console.log(message);
|
||||
axios.post('https://us-central1-edeclicpwa.cloudfunctions.net/pushMessageToAllSubscribers',
|
||||
{ payload: message }
|
||||
).then(r => {
|
||||
res.status(200).send({ message: "message sent to firebase" })
|
||||
}
|
||||
)
|
||||
.catch(err => console.log(err))
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
expressApp.get('/static/js/*.js', (req, res) => {
|
||||
|
||||
const parsedUrl = parse(req.url, true);
|
||||
const { pathname } = parsedUrl;
|
||||
const filePath = join(__dirname, '.next', pathname);
|
||||
@@ -278,14 +31,12 @@ app.prepare()
|
||||
})
|
||||
|
||||
expressApp.get('/manifest.json', (req, res) => {
|
||||
|
||||
const parsedUrl = parse(req.url, true);
|
||||
const { pathname } = parsedUrl;
|
||||
const filePath = join(__dirname, '/static/', pathname);
|
||||
app.serveStatic(req, res, filePath);
|
||||
})
|
||||
|
||||
|
||||
expressApp.get('*', (req, res) => {
|
||||
return handle(req, res)
|
||||
})
|
||||
@@ -293,7 +44,6 @@ app.prepare()
|
||||
expressApp.listen(process.env.PORT, (err) => {
|
||||
if (err) throw err
|
||||
console.log('> Ready on http://localhost:' + process.env.PORT)
|
||||
console.log('> access Token googleapi >' + getAccessToken())
|
||||
})
|
||||
})
|
||||
.catch((ex) => {
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"type": "service_account",
|
||||
"project_id": "edeclicpwa",
|
||||
"private_key_id": "aef80b8a8d6f9f10aa0ef0cffd46992399fac45d",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZuQVADJXtA7Hb\n2R36sZxD3fw5QOmLwvAGnIXtexf/hppz6J1mUDsbNDLF3FxlgzdKQguGE0+q6QI+\nIWEMYPVQPot8Tbs8rcL06EKkhLR3KHRI6hWRyFNnWKnig7xVD5LUNVjgtHNIx9TC\ndf+/F6kSsz7w7cjHZEFZ5k7eAeD3M15EhtGCCyJ9DM3MO/pKzW4lah1jTGeV1ZYS\nimuBSbSX9Z6k6l3dUayMYaARYjZkBu1syhUGs/KoeqS+o+bR1OJX/JiaYe0lWWAg\nuL4315c2SkuXeHX2y9BvxbY2TGfhAPuNFPSsJgt0hXE6QeSIjFZXePmWIq28tNhH\n6OR/EJFzAgMBAAECggEAZ23/YgF4mct3C19V4BnPB+ilYReGuzfkqediskIXUPMD\nXcvkNk4n/hDqi9dW53yR4AuHCO8UmjcuMxDNV0GaWEAWKHuO1tEfPBQ4UIqgZrkH\noPnfPE2j3YUf03VMm0YWNQyQx9LBr5IK70R6NbAKSFFxtafoiVyFtSz1S38t/ZB/\nqigCvK48kG6vZCyAozuKVbkLKorY8THZRbK24Mwp4rnAxRHUxG9pXCGe1/j1FvSP\nPRGPptvRSLP2kRPZXELKga7/yCPIOqT2jEoWiXAdfU2gyED4jEhby+ryBHuTsxpo\nJiaGtbUWMKjOEUOWekgTMvtgQD4T5WP5zx2AAZ5K4QKBgQDz7075SYWTy98MZSC2\nMVF6Ei2mGDMxLDJqpTnc3Oi7+eOXI8uTo5SqgaBHfM/uTywcipqSUQTseDN7C1wu\nWOb6r0shK6FfDP1GQc9l0mmNuIZ8JLkc6nB8Es5wwd4vLRhuSsy6pSz/wDovC3Q2\n5se/B7ir+kYeFlhIMAjN91rukwKBgQDkfdDpAociVjFpcjly5Zf60uL/BzIZOdpn\n1Iq/kAxFr2kuZzGDpwUgXvSU4nELivrsf452x3+R78C2SWwil9IRrD3DAYJzT3qP\nb6l4EuKuHRPtVJBqIPWaMiT6Ov6aAQpGYh5qZjFeHSIDBzXHd/OBbSzisE3zTOqm\nED3/eQq9oQKBgAD/XYdPcahlEQhv8W5NTVP+dwlS2AK/d4VQH6hzjtAV+YRItTBp\nXtZDqXAhZohG8ps7Rd6LTkXZR/yc00etPWSRCvGbyBEncHG1GzADaEMYGhSv4cHo\ng4U+XnG/mTUALjVlQOkSe9if5J0EovkGgJKbaXnqkBbXaI0DBUYyWMDZAoGBAMND\nGfLmbCFV02gvaxTbTCPXcJFMzu1r2U99/Qxzx2kN3C8BlPjTFLhzLUTGtqCMpp7Q\n6yhqmIRYhTHCURzG7YiYzzcE5TwxoaVOYV7xlLICu3LIH5nyjLC3RY5qOAXX+bXo\nR+HZbzrkXpqD4NuTkI78g609yX+wLZ64pqLaB+nBAoGATMflJNxgyWtY6b2yFYgm\nCOhMecJKMS2Rgmdl3FQGxAMPMIy18URW/t99LmbUhqQGsdFPDTcxR6V4ajWqltrj\nLkbrEtSHp7xFAQD2anUeEwxtW8PpICwhgGXJUSjXU8+2A20CaWcTwH5USnNp8kp/\n9402JWBkoe+kodILFHZ363M=\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "firebase-adminsdk-hffwl@edeclicpwa.iam.gserviceaccount.com",
|
||||
"client_id": "100436348289421185617",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-hffwl%40edeclicpwa.iam.gserviceaccount.com"
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
importScripts("https://www.gstatic.com/firebasejs/5.5.8/firebase-app.js")
|
||||
importScripts("https://www.gstatic.com/firebasejs/5.5.8/firebase-messaging.js")
|
||||
|
||||
if (firebase.messaging.isSupported()) {
|
||||
// Initialize Firebase
|
||||
var config = {
|
||||
apiKey: "AIzaSyArZab_4hUDgksQ4Dqdwv970JyRSlbGaKY",
|
||||
authDomain: "edeclicpwa.firebaseapp.com",
|
||||
databaseURL: "https://edeclicpwa.firebaseio.com",
|
||||
projectId: "edeclicpwa",
|
||||
storageBucket: "edeclicpwa.appspot.com",
|
||||
messagingSenderId: "130215947970"
|
||||
};
|
||||
firebase.initializeApp(config);
|
||||
|
||||
var messaging = firebase.messaging();
|
||||
|
||||
/**
|
||||
* Here is is the code snippet to initialize Firebase Messaging in the Service
|
||||
* Worker when your app is not hosted on Firebase Hosting.
|
||||
// [START initialize_firebase_in_sw]
|
||||
// Give the service worker access to Firebase Messaging.
|
||||
// Note that you can only use Firebase Messaging here, other Firebase libraries
|
||||
// are not available in the service worker.
|
||||
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
|
||||
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
|
||||
// Initialize the Firebase app in the service worker by passing in the
|
||||
// messagingSenderId.
|
||||
firebase.initializeApp({
|
||||
'messagingSenderId': 'YOUR-SENDER-ID'
|
||||
});
|
||||
// Retrieve an instance of Firebase Messaging so that it can handle background
|
||||
// messages.
|
||||
const messaging = firebase.messaging();
|
||||
// [END initialize_firebase_in_sw]
|
||||
**/
|
||||
|
||||
|
||||
// If you would like to customize notifications that are received in the
|
||||
// background (Web app is closed or not in browser focus) then you should
|
||||
// implement this optional method.
|
||||
// [START background_handler]
|
||||
messaging.setBackgroundMessageHandler(function (payload) {
|
||||
console.log('[firebase-messaging-sw.js] Received background message ', payload);
|
||||
// Customize notification here
|
||||
var notificationTitle = 'Background Message Title';
|
||||
var notificationOptions = {
|
||||
body: 'Background Message body.',
|
||||
icon: '/firebase-logo.png'
|
||||
};
|
||||
|
||||
return self.registration.showNotification(notificationTitle,
|
||||
notificationOptions);
|
||||
});
|
||||
// [END background_handler]
|
||||
}
|
||||
+6
-57
@@ -1,72 +1,21 @@
|
||||
{
|
||||
"name": "E-Declic PWA",
|
||||
"short_name": "E-Declic",
|
||||
"name": "AG2L SAV",
|
||||
"short_name": "AG2L",
|
||||
"lang": "fr",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco16x16.png",
|
||||
"sizes": "16x16",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco32x32.png",
|
||||
"src": "/static/images/icons/AG2L32x32.png",
|
||||
"sizes": "32x32",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco57x57.png",
|
||||
"sizes": "57x57",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco114x114.png",
|
||||
"sizes": "114x114",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco180x180.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/images/icons/e-declicIco512x512.png",
|
||||
"sizes": "512x512",
|
||||
"src": "/static/images/icons/AG2L270x270.png",
|
||||
"sizes": "270x270",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#21b8cc",
|
||||
"gcm_sender_id":"103953800507"
|
||||
"theme_color": "#21b8cc"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import axios from "axios";
|
||||
|
||||
export default (token = null) => {console.log(token)
|
||||
if (token) {
|
||||
axios.defaults.headers.common.authorization = `Bearer ${token}`;
|
||||
} else {
|
||||
delete axios.defaults.headers.common.authorization;
|
||||
}
|
||||
};
|
||||
@@ -873,6 +873,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.11.tgz#32a853fad9974cbbc9fc766ec5699a18b22ccee6"
|
||||
integrity sha512-WyMXDxk/WZ+f2lOCeEvDWUce2f5Kk2sNfvArK8f+PlUnzFdy/MBzLXrmbMgyZXP7GP4ooUxYV8Sdmoh1hGk1Uw==
|
||||
|
||||
"@mapbox/point-geometry@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2"
|
||||
integrity sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=
|
||||
|
||||
"@material-ui/core@^3.2.0":
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-3.9.0.tgz#7e74cf1979ee65f9fd388145764b3e58f48da6c6"
|
||||
@@ -3943,6 +3948,11 @@ event-stream@=3.3.4:
|
||||
stream-combiner "~0.0.4"
|
||||
through "~2.3.1"
|
||||
|
||||
eventemitter3@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"
|
||||
integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=
|
||||
|
||||
events@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
|
||||
@@ -4874,6 +4884,15 @@ google-auth-library@^2.0.0:
|
||||
lru-cache "^5.0.0"
|
||||
semver "^5.5.0"
|
||||
|
||||
google-map-react@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/google-map-react/-/google-map-react-1.1.2.tgz#9ec9cbee88bf043dd24ce6c5953663e636461a71"
|
||||
integrity sha512-uHyhLW0db1nXMWYfazTnm6GiMzITUZ+OldFt+u0lLsC/ndSNVZWY0Hn2v8s2+vnpg88ZU0cAk7nRK5UXq0ahaA==
|
||||
dependencies:
|
||||
"@mapbox/point-geometry" "^0.1.0"
|
||||
eventemitter3 "^1.1.0"
|
||||
scriptjs "^2.5.7"
|
||||
|
||||
google-p12-pem@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-1.0.3.tgz#3d8acc140573339a5bca7b2f6a4b206bbea6d8d7"
|
||||
@@ -8970,7 +8989,7 @@ readdirp@^2.0.0:
|
||||
micromatch "^3.1.10"
|
||||
readable-stream "^2.0.2"
|
||||
|
||||
"recompose@0.28.0 - 0.30.0":
|
||||
"recompose@0.28.0 - 0.30.0", recompose@^0.30.0:
|
||||
version "0.30.0"
|
||||
resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.30.0.tgz#82773641b3927e8c7d24a0d87d65aeeba18aabd0"
|
||||
integrity sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w==
|
||||
@@ -9425,6 +9444,11 @@ schema-utils@^1.0.0:
|
||||
ajv-errors "^1.0.0"
|
||||
ajv-keywords "^3.1.0"
|
||||
|
||||
scriptjs@^2.5.7:
|
||||
version "2.5.9"
|
||||
resolved "https://registry.yarnpkg.com/scriptjs/-/scriptjs-2.5.9.tgz#343915cd2ec2ed9bfdde2b9875cd28f59394b35f"
|
||||
integrity sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg==
|
||||
|
||||
seek-bzip@^1.0.3, seek-bzip@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc"
|
||||
|
||||
Reference in New Issue
Block a user