Files
AG2L-pwa/pages/pushCreator.js
T
2019-02-11 14:58:45 +01:00

363 lines
13 KiB
JavaScript

import React, { Fragment } from 'react';
import { NextAuth } from 'next-auth/client'
import Layout from '../components/MyLayout.js'
import withStyles from '@material-ui/core/styles/withStyles';
import Paper from '@material-ui/core/Paper';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import PushParamForm from '../components/push/PushParamForm';
import PushReview from '../components/push/PushReview';
import PushTargetForm from '../components/push/PushTargetForm';
import CircularProgress from '@material-ui/core/CircularProgress';
import axios from 'axios'
import getConfig from 'next/config'
import green from '@material-ui/core/colors/green';
import orange from '@material-ui/core/colors/orange';
import Snackbar from '@material-ui/core/Snackbar';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import dynamic from 'next/dynamic'
import Link from 'next/link'
import Cookies from 'universal-cookie'
import Router from 'next/router'
const styles = theme => ({
appBar: {
position: 'relative',
},
layout: {
width: 'auto',
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
[theme.breakpoints.up(600 + theme.spacing.unit * 2 * 2)]: {
width: 600,
marginLeft: 'auto',
marginRight: 'auto',
},
},
paper: {
marginTop: theme.spacing.unit * 3,
marginBottom: theme.spacing.unit * 3,
padding: theme.spacing.unit * 2,
[theme.breakpoints.up(600 + theme.spacing.unit * 3 * 2)]: {
marginTop: theme.spacing.unit * 6,
marginBottom: theme.spacing.unit * 6,
padding: theme.spacing.unit * 3,
},
},
stepper: {
padding: `${theme.spacing.unit * 3}px 0 ${theme.spacing.unit * 5}px`,
},
buttons: {
display: 'flex',
justifyContent: 'flex-end',
},
button: {
marginTop: theme.spacing.unit * 3,
marginLeft: theme.spacing.unit,
},
});
const { publicRuntimeConfig } = getConfig()
let back = ''
const steps = ['Parameters', 'Target', 'Review'];
class PushCreator extends React.Component {
state = {
session: this.props.session,
isSignedIn: (this.props.session.user) ? true : false,
activeStep: 0,
title: '',
body: '',
action: publicRuntimeConfig.push.defaultAction,
iconLink: publicRuntimeConfig.push.defaultIconLink,
imageLink: publicRuntimeConfig.push.defaultImageLink,
target: 'a',
topic: '',
loading: false,
openSnack: false,
error: false,
warning: false,
success: false,
snackMessage: ""
};
static async getInitialProps({ req }) {
let props = {};
props.session = await NextAuth.init({ req })
return props
}
constructor(props) {
super(props);
}
async componentDidMount() {
}
getStepContent = (step) => {
switch (step) {
case 0:
return <PushParamForm
onSelectedTitle={this.setTitle}
onSelectedBody={this.setBody}
onSelectedAction={this.setAction}
onSelectedImageLink={this.setImageLink}
onSelectedIconLink={this.setIconLink}
title={this.state.title}
body={this.state.body}
action={this.state.action}
imageLink={this.state.imageLink}
iconLink={this.state.iconLink}
/>;
case 1:
return <PushTargetForm
onSelectedTarget={this.setTarget}
onSelectedTopic={this.setTopic}
target={this.state.target}
topic={this.state.topic} />;
case 2:
return <PushReview
title={this.state.title}
body={this.state.body}
action={this.state.action}
imageLink={this.state.imageLink}
iconLink={this.state.iconLink}
target={this.state.target} />;
default:
throw new Error('Unknown step');
}
}
setTitle = (title) => {
this.setState(state => ({
title
}));
}
setBody = (body) => {
this.setState(state => ({
body
}));
}
setAction = (action) => {
this.setState(state => ({
action
}));
}
setImageLink = (imageLink) => {
this.setState(state => ({
imageLink
}));
}
setIconLink = (iconLink) => {
this.setState(state => ({
iconLink
}));
}
setTarget = (target) => {
this.setState(state => ({
target
}));
}
setTopic = (topic) => {
this.setState(state => ({
topic
}));
}
async componentDidMount() {
//loading lib for client side only
let result = await import("../src/backSync.js")
back = result.default
const cookies = new Cookies()
cookies.set('redirect_url', window.location.pathname, { path: '/' })
}
sendPush(url, payload) {
axios.post(url, {
payload
}).then(response => {
this.setState({ success: true, error: false, warning: false, message: '', snackMessage: "Votre message à bien été envoyé.", loading: false, openSnack: false })
}).catch(error => {
if (error.status != 500) {
if (process.browser) {
// client-side-only code
back.saveEventDataLocally([{ message: this.state.message }]);
}
}
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 })
});
}
async sendSingleMessage(payload) {
let EdeclicLib = (await import('../components/firebase-client.js')).default
if (!EdeclicLib.messaging)
return
payload.message.token = await EdeclicLib.askForToken();
this.sendPush("/push/message", payload)
}
sendToAll(payload) {
this.sendPush("/push/allsubscribers", payload)
}
sendToTopic(payload) {
payload.message.topic = this.state.topic
this.sendPush("/push/message", payload)
}
handleNext = async () => {
"use strict";
if (this.state.activeStep == 2) {
//TODO: verify infos
let payload = {
message: {
webpush: {
headers: {
Urgency: "high"
},
notification: {
title: this.state.title,
body: this.state.body,
icon: this.state.iconLink,
image: this.state.imageLink,
click_action: this.state.action
}
}
}
}
//single
if (this.state.target === 'a') {
this.sendSingleMessage(payload)
}//to All
else if (this.state.target === 'b') {
this.sendToAll(payload.message)
}//to topics
else if (this.state.target === 'c') {
this.sendToTopic(payload)
}
}
this.setState(state => ({
activeStep: state.activeStep + 1,
}));
};
handleBack = () => {
this.setState(state => ({
activeStep: state.activeStep - 1,
}));
};
handleReset = () => {
this.setState({
activeStep: 0,
});
};
handleClose = () => {
this.setState({ openSnack: false })
}
render() {
const { classes } = this.props;
const { activeStep } = this.state;
return (
<Layout menu={this.props.menu}>
{(this.state.isSignedIn) &&
(<Fragment>
<main className={classes.layout}>
<Paper className={classes.paper}>
{this.state.loading && (
<div className="alert alert-info">
<CircularProgress color="secondary" />Verification en cours...
</div>
)}
<Typography component="h1" variant="h4" align="center">
Push Notification Launcher
</Typography>
<Stepper activeStep={activeStep} className={classes.stepper}>
{steps.map(label => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
<Fragment>
{activeStep === steps.length ? (
<Fragment>
<Typography variant="h5" gutterBottom>
Votre push a été envoyé sur firebase.
</Typography>
<Typography variant="subtitle1">
Il devrait être soumis dans quelques instants.
</Typography>
<div className={classes.buttons}>
<Button
variant="contained"
color="primary"
onClick={this.handleReset} className={classes.button}>
Nouveau 🏭
</Button>
</div>
</Fragment>
) : (
<Fragment>
{this.getStepContent(activeStep)}
<div className={classes.buttons}>
{activeStep !== 0 && (
<Button onClick={this.handleBack} className={classes.button}>
Retour
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={this.handleNext}
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Launch 🚀' : 'Next'}
</Button>
</div>
</Fragment>
)}
</Fragment>
</Paper>
</main>
</Fragment>
)}
{(!this.state.isSignedIn) &&
(<Button
variant="contained"
color="primary"
className={classes.button}
onClick={() => Router.push('/auth/credentials')}>Sign in to use that feature</Button>)
}
<Snackbar
autoHideDuration={6000}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
open={this.state.openSnack}
onClose={this.handleClose}
>
<SnackbarContent
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)(PushCreator);