react collapse + charts
This commit is contained in:
parent
6a1f4d6752
commit
dd29a96161
1462
admin/dist/main.js
vendored
1462
admin/dist/main.js
vendored
File diff suppressed because one or more lines are too long
130
admin/package-lock.json
generated
130
admin/package-lock.json
generated
@ -1349,11 +1349,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
|
||||||
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
|
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
|
||||||
},
|
},
|
||||||
"@reach/observe-rect": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-kE+jvoj/OyJV24C03VvLt5zclb9ArJi04wWXMMFwQvdZjdHoBlN4g0ZQFjyy/ejPF1Z/dpUD5dhRdBiUmIGZTA=="
|
|
||||||
},
|
|
||||||
"@sheerun/mutationobserver-shim": {
|
"@sheerun/mutationobserver-shim": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",
|
||||||
@ -3435,6 +3430,32 @@
|
|||||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "2.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz",
|
||||||
|
"integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==",
|
||||||
|
"requires": {
|
||||||
|
"chartjs-color": "^2.1.0",
|
||||||
|
"moment": "^2.10.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chartjs-color": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
|
||||||
|
"requires": {
|
||||||
|
"chartjs-color-string": "^0.6.0",
|
||||||
|
"color-convert": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chartjs-color-string": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
|
||||||
@ -4245,80 +4266,6 @@
|
|||||||
"type": "^1.0.1"
|
"type": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"d3-array": {
|
|
||||||
"version": "2.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.4.0.tgz",
|
|
||||||
"integrity": "sha512-KQ41bAF2BMakf/HdKT865ALd4cgND6VcIztVQZUTt0+BH3RWy6ZYnHghVXf6NFjt2ritLr8H1T8LreAAlfiNcw=="
|
|
||||||
},
|
|
||||||
"d3-color": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
|
||||||
},
|
|
||||||
"d3-delaunay": {
|
|
||||||
"version": "5.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz",
|
|
||||||
"integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==",
|
|
||||||
"requires": {
|
|
||||||
"delaunator": "4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"d3-format": {
|
|
||||||
"version": "1.4.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz",
|
|
||||||
"integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw=="
|
|
||||||
},
|
|
||||||
"d3-interpolate": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
|
|
||||||
"requires": {
|
|
||||||
"d3-color": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"d3-path": {
|
|
||||||
"version": "1.0.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
|
|
||||||
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
|
|
||||||
},
|
|
||||||
"d3-scale": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-huz5byJO/6MPpz6Q8d4lg7GgSpTjIZW/l+1MQkzKfu2u8P6hjaXaStOpmyrD6ymKoW87d2QVFCKvSjLwjzx/rA==",
|
|
||||||
"requires": {
|
|
||||||
"d3-array": "1.2.0 - 2",
|
|
||||||
"d3-format": "1",
|
|
||||||
"d3-interpolate": "^1.2.0",
|
|
||||||
"d3-time": "1",
|
|
||||||
"d3-time-format": "2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"d3-shape": {
|
|
||||||
"version": "1.3.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
|
|
||||||
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
|
|
||||||
"requires": {
|
|
||||||
"d3-path": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"d3-time": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
|
|
||||||
},
|
|
||||||
"d3-time-format": {
|
|
||||||
"version": "2.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
|
|
||||||
"integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
|
|
||||||
"requires": {
|
|
||||||
"d3-time": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"d3-voronoi": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
|
|
||||||
},
|
|
||||||
"damerau-levenshtein": {
|
"damerau-levenshtein": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
|
||||||
@ -4494,11 +4441,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"delaunator": {
|
|
||||||
"version": "4.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz",
|
|
||||||
"integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag=="
|
|
||||||
},
|
|
||||||
"delayed-stream": {
|
"delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
@ -10526,18 +10468,20 @@
|
|||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-charts": {
|
"react-chartjs-2": {
|
||||||
"version": "2.0.0-beta.7",
|
"version": "2.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-charts/-/react-charts-2.0.0-beta.7.tgz",
|
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.9.0.tgz",
|
||||||
"integrity": "sha512-iUspg9rnx7kD0H/wsK67HNUioOgKgJ8WRXr/Tk3EGP2qcFb9Vo7pjDk4oz1jH12TC+mqL+HFxNYraMkhWd6CUw==",
|
"integrity": "sha512-IYwqUUnQRAJ9SNA978vxulHJTcUFTJk2LDVfbAyk0TnJFZZG7+6U/2flsE4MCw6WCbBjTTypy8T82Ch7XrPtRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@reach/observe-rect": "^1.1.0",
|
"lodash": "^4.17.4",
|
||||||
"d3-delaunay": "^5.2.1",
|
"prop-types": "^15.5.8"
|
||||||
"d3-scale": "^3.2.1",
|
|
||||||
"d3-shape": "^1.3.7",
|
|
||||||
"d3-voronoi": "^1.1.2"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-collapse": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-collapse/-/react-collapse-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-cN2tkxBWizhPQ2JHfe0aUSJtmMthKA17NZkTElpiQ2snQAAi1hssXZ2fv88rAPNNvG5ss4t0PbOZT0TIl9Lk3Q=="
|
||||||
|
},
|
||||||
"react-dev-utils": {
|
"react-dev-utils": {
|
||||||
"version": "10.2.1",
|
"version": "10.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz",
|
||||||
|
@ -6,8 +6,11 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.5.0",
|
"@testing-library/react": "^9.5.0",
|
||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
|
"chart.js": "^2.9.3",
|
||||||
"moment": "^2.26.0",
|
"moment": "^2.26.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
|
"react-chartjs-2": "^2.9.0",
|
||||||
|
"react-collapse": "^5.0.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "3.4.1",
|
"react-scripts": "3.4.1",
|
||||||
|
@ -1,2 +1,6 @@
|
|||||||
.page-link { color: #222629; }
|
.page-link { color: #222629; }
|
||||||
.page-link:hover { color: black; }
|
.page-link:hover { color: black; }
|
||||||
|
|
||||||
|
.ReactCollapse--collapse {
|
||||||
|
transition: height 500ms;
|
||||||
|
}
|
@ -3,6 +3,7 @@ import {Link} from "react-router-dom";
|
|||||||
import Alert from "../elements/alert";
|
import Alert from "../elements/alert";
|
||||||
import Icon from "../elements/icon";
|
import Icon from "../elements/icon";
|
||||||
import ReactTooltip from 'react-tooltip'
|
import ReactTooltip from 'react-tooltip'
|
||||||
|
import {Collapse} from "react-collapse/lib/Collapse";
|
||||||
|
|
||||||
export default class CreateUser extends React.Component {
|
export default class CreateUser extends React.Component {
|
||||||
|
|
||||||
@ -39,24 +40,6 @@ export default class CreateUser extends React.Component {
|
|||||||
errors.push(<Alert key={"error-" + i} onClose={() => this.removeError(i)} {...this.state.errors[i]}/>)
|
errors.push(<Alert key={"error-" + i} onClose={() => this.removeError(i)} {...this.state.errors[i]}/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
let passwordForm = null;
|
|
||||||
if (!this.state.sendInvite) {
|
|
||||||
passwordForm = <div className={"mt-2"}>
|
|
||||||
<div className={"form-group"}>
|
|
||||||
<label htmlFor={"password"}>Password</label>
|
|
||||||
<input type={"password"} className={"form-control"} placeholder={"Password"}
|
|
||||||
id={"password"} name={"password"} value={this.state.password}
|
|
||||||
onChange={this.onChangeInput.bind(this)}/>
|
|
||||||
</div>
|
|
||||||
<div className={"form-group"}>
|
|
||||||
<label htmlFor={"confirmPassword"}>Confirm Password</label>
|
|
||||||
<input type={"password"} className={"form-control"} placeholder={"Confirm Password"}
|
|
||||||
id={"confirmPassword"} name={"confirmPassword"} value={this.state.confirmPassword}
|
|
||||||
onChange={this.onChangeInput.bind(this)}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div className="content-header">
|
<div className="content-header">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@ -102,7 +85,24 @@ export default class CreateUser extends React.Component {
|
|||||||
data-type={"info"} data-place={"right"} data-effect={"solid"}/>
|
data-type={"info"} data-place={"right"} data-effect={"solid"}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{passwordForm}
|
|
||||||
|
<Collapse isOpened={!this.state.sendInvite}>
|
||||||
|
<div className={"mt-2"}>
|
||||||
|
<div className={"form-group"}>
|
||||||
|
<label htmlFor={"password"}>Password</label>
|
||||||
|
<input type={"password"} className={"form-control"} placeholder={"Password"}
|
||||||
|
id={"password"} name={"password"} value={this.state.password}
|
||||||
|
onChange={this.onChangeInput.bind(this)}/>
|
||||||
|
</div>
|
||||||
|
<div className={"form-group"}>
|
||||||
|
<label htmlFor={"confirmPassword"}>Confirm Password</label>
|
||||||
|
<input type={"password"} className={"form-control"} placeholder={"Confirm Password"}
|
||||||
|
id={"confirmPassword"} name={"confirmPassword"} value={this.state.confirmPassword}
|
||||||
|
onChange={this.onChangeInput.bind(this)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
<Link to={"/admin/users"} className={"btn btn-info mt-2 mr-2"}>
|
<Link to={"/admin/users"} className={"btn btn-info mt-2 mr-2"}>
|
||||||
<Icon icon={"arrow-left"}/>
|
<Icon icon={"arrow-left"}/>
|
||||||
Back
|
Back
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import Icon from "../elements/icon";
|
import Icon from "../elements/icon";
|
||||||
|
import { Bar } from 'react-chartjs-2';
|
||||||
|
import {Collapse} from 'react-collapse';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
export default class Overview extends React.Component {
|
export default class Overview extends React.Component {
|
||||||
|
|
||||||
@ -10,6 +13,10 @@ export default class Overview extends React.Component {
|
|||||||
showDialog: props.showDialog,
|
showDialog: props.showDialog,
|
||||||
notifications: props.notification,
|
notifications: props.notification,
|
||||||
api: props.api,
|
api: props.api,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
chartVisible : true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +31,22 @@ export default class Overview extends React.Component {
|
|||||||
let pageCount = 0;
|
let pageCount = 0;
|
||||||
let visitorCount = 0;
|
let visitorCount = 0;
|
||||||
|
|
||||||
|
const colors = [
|
||||||
|
'#ff4444', '#ffbb33', '#00C851', '#33b5e5',
|
||||||
|
'#ff4444', '#ffbb33', '#00C851', '#33b5e5',
|
||||||
|
'#ff4444', '#ffbb33', '#00C851', '#33b5e5'
|
||||||
|
];
|
||||||
|
|
||||||
|
let chartOptions = {};
|
||||||
|
let chartData = {
|
||||||
|
labels: moment.monthsShort(),
|
||||||
|
datasets: [{
|
||||||
|
label: 'Unique Visitors ' + moment().year(),
|
||||||
|
borderWidth: 1,
|
||||||
|
data: [ 10, 20, 30, 0, 15, 5, 40, 100, 6, 3, 10, 20 ],
|
||||||
|
backgroundColor: colors,
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div className={"content-header"}>
|
<div className={"content-header"}>
|
||||||
@ -100,27 +123,29 @@ export default class Overview extends React.Component {
|
|||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<h3 className="card-title">Unique Visitors this year</h3>
|
<h3 className="card-title">Unique Visitors this year</h3>
|
||||||
<div className="card-tools">
|
<div className="card-tools">
|
||||||
<button type="button" className="btn btn-tool" data-card-widget="collapse">
|
<button type="button" className={"btn btn-tool"} onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
this.setState({ ...this.state, chartVisible: !this.state.chartVisible });
|
||||||
|
}}>
|
||||||
<Icon icon={"minus"} />
|
<Icon icon={"minus"} />
|
||||||
</button>
|
</button>
|
||||||
<button type="button" className="btn btn-tool" data-card-widget="remove">
|
|
||||||
<Icon icon={"times"} />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body">
|
<Collapse isOpened={this.state.chartVisible}>
|
||||||
<div className="chart">
|
<div className="card-body">
|
||||||
<div className="chartjs-size-monitor">
|
<div className="chart">
|
||||||
<div className="chartjs-size-monitor-expand">
|
<div className="chartjs-size-monitor">
|
||||||
<div/>
|
<div className="chartjs-size-monitor-expand">
|
||||||
</div>
|
<div/>
|
||||||
<div className="chartjs-size-monitor-shrink">
|
</div>
|
||||||
<div/>
|
<div className="chartjs-size-monitor-shrink">
|
||||||
|
<div/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Bar data={chartData} options={chartOptions} />
|
||||||
</div>
|
</div>
|
||||||
<BarChart data={data} series={series} axes={axes} tooltip />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Collapse>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,6 +27,10 @@ class SendMail extends Request {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$mailConfig = $this->user->getConfiguration()->getMail();
|
$mailConfig = $this->user->getConfiguration()->getMail();
|
||||||
|
if (!$mailConfig) {
|
||||||
|
return $this->createError("Mail is not configured yet.");
|
||||||
|
}
|
||||||
|
|
||||||
$mail = new PHPMailer;
|
$mail = new PHPMailer;
|
||||||
$mail->IsSMTP();
|
$mail->IsSMTP();
|
||||||
$mail->setFrom($this->getParam('from'), $this->getParam('fromName'));
|
$mail->setFrom($this->getParam('from'), $this->getParam('fromName'));
|
||||||
|
@ -4,6 +4,8 @@ namespace Api\User;
|
|||||||
|
|
||||||
use Api\Parameter\StringType;
|
use Api\Parameter\StringType;
|
||||||
use \Api\Request;
|
use \Api\Request;
|
||||||
|
use Api\SendMail;
|
||||||
|
use DateTime;
|
||||||
use Driver\SQL\Condition\Compare;
|
use Driver\SQL\Condition\Compare;
|
||||||
|
|
||||||
class Invite extends Request {
|
class Invite extends Request {
|
||||||
@ -33,17 +35,26 @@ class Invite extends Request {
|
|||||||
$token = generateRandomString(36);
|
$token = generateRandomString(36);
|
||||||
$valid_until = (new DateTime())->modify("+48 hour");
|
$valid_until = (new DateTime())->modify("+48 hour");
|
||||||
$sql = $this->user->getSQL();
|
$sql = $this->user->getSQL();
|
||||||
$res = $sql->insert("UserInvite", array("name", "email","token","valid_until"))
|
$res = $sql->insert("UserInvitation", array("username", "email", "token", "valid_until"))
|
||||||
->addRow($username, $email, $token,$valid_until)
|
->addRow($username, $email, $token, $valid_until)
|
||||||
->execute();
|
->execute();
|
||||||
$this->success = ($res !== FALSE);
|
$this->success = ($res !== FALSE);
|
||||||
$this->lastError = $sql->getLastError();
|
$this->lastError = $sql->getLastError();
|
||||||
|
|
||||||
//send validation mail
|
//send validation mail
|
||||||
if($this->success) {
|
if($this->success) {
|
||||||
$request = new SendEmail($this->user);
|
$request = new SendMail($this->user);
|
||||||
|
$link = "http://localhost/acceptInvitation?token=$token";
|
||||||
$this->success = $request->execute(array(
|
$this->success = $request->execute(array(
|
||||||
"from" => "...", "to" => $email));
|
"from" => "webmaster@romanh.de",
|
||||||
|
"to" => $email,
|
||||||
|
"subject" => "Account Invitation for web-base@localhost",
|
||||||
|
"body" =>
|
||||||
|
"Hello,<br>
|
||||||
|
you were invited to create an account on web-base@localhost. Click on the following link to confirm the registration, it is 48h valid from now.
|
||||||
|
If the invitation was not intended, you can simply ignore this email.<br><br><a href=\"$link\">$link</a>"
|
||||||
|
)
|
||||||
|
);
|
||||||
$this->lastError = $request->getLastError();
|
$this->lastError = $request->getLastError();
|
||||||
}
|
}
|
||||||
return $this->success;
|
return $this->success;
|
||||||
|
@ -94,9 +94,7 @@ class Configuration {
|
|||||||
public function __construct() {
|
public function __construct() {
|
||||||
parent::__construct('$host', $port, '$login', '$password');$properties
|
parent::__construct('$host', $port, '$login', '$password');$properties
|
||||||
}
|
}
|
||||||
}
|
}", false
|
||||||
|
|
||||||
?>", false
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
1462
js/admin.min.js
vendored
1462
js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user