188 lines
4.0 KiB
JavaScript
188 lines
4.0 KiB
JavaScript
import React from "react"
|
|
import { connect } from "react-redux"
|
|
import { UAParser } from "ua-parser-js"
|
|
import moment from "moment"
|
|
|
|
import { bindActionCreators } from "redux"
|
|
import { deleteUserToken } from "../../actions/users"
|
|
|
|
const mapDispatchToProps = (dispatch) =>
|
|
bindActionCreators({ deleteUserToken }, dispatch)
|
|
|
|
function mapStateToProps(state) {
|
|
return {
|
|
tokens: state.userStore.get("tokens"),
|
|
};
|
|
}
|
|
|
|
function UserTokens(props) {
|
|
return (
|
|
<div className="container">
|
|
<div className="content-fluid">
|
|
<TokenList {...props} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function TokenList(props) {
|
|
return (
|
|
<div>
|
|
<h2 className="hidden-xs">Tokens</h2>
|
|
<h3 className="visible-xs">Tokens</h3>
|
|
|
|
<div>
|
|
{props.tokens.map(function(el, index) {
|
|
return (
|
|
<Token
|
|
key={index}
|
|
data={el}
|
|
deleteToken={props.deleteUserToken}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Token(props) {
|
|
const ua = UAParser(props.data.get("user_agent"));
|
|
return (
|
|
<div className="panel panel-default">
|
|
<div className="container">
|
|
<Logo {...ua} />
|
|
<div className="col-xs-10">
|
|
<dl className="dl-horizontal">
|
|
<dt>Description</dt>
|
|
<dd>{props.data.get("description")}</dd>
|
|
|
|
<dt>Last IP</dt>
|
|
<dd>{props.data.get("ip")}</dd>
|
|
|
|
<dt>Last used</dt>
|
|
<dd>{moment(props.data.get("last_used")).fromNow()}</dd>
|
|
|
|
<dt>Created</dt>
|
|
<dd>{moment(props.data.get("created_at")).fromNow()}</dd>
|
|
|
|
<dt>Device</dt>
|
|
<dd><Device {...ua.device}/></dd>
|
|
|
|
<dt>OS</dt>
|
|
<dd><OS {...ua.os}/></dd>
|
|
|
|
<dt>Browser</dt>
|
|
<dd><Browser {...ua.browser}/></dd>
|
|
</dl>
|
|
</div>
|
|
<Actions {...props} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
class Actions extends React.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.handleClick = this.handleClick.bind(this);
|
|
}
|
|
handleClick() {
|
|
const token = this.props.data.get("token");
|
|
this.props.deleteToken(token);
|
|
}
|
|
render() {
|
|
return (
|
|
<div className="col-xs-1">
|
|
<span
|
|
className="fa fa-trash fa-lg pull-right clickable user-token-action"
|
|
onClick={this.handleClick}>
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
function Logo(props) {
|
|
var className;
|
|
if (props.ua === "canape-cli") {
|
|
className = "terminal";
|
|
} else if (props.device.type == "mobile" ){
|
|
className = "mobile";
|
|
} else {
|
|
switch (props.browser.name) {
|
|
case "Chrome":
|
|
case "chrome":
|
|
className = "chrome";
|
|
break;
|
|
case "Safari":
|
|
case "safari":
|
|
className = "safari";
|
|
break;
|
|
case "Firefox":
|
|
case "firefox":
|
|
className = "firefox";
|
|
break;
|
|
default:
|
|
className = "question";
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="user-token-icon">
|
|
<div className="hidden-xs hidden-sm col-md-1">
|
|
<span className={"fa fa-" + className + " fa-5x"}></span>
|
|
</div>
|
|
<div className="hidden-md hidden-lg col-xs-1">
|
|
<span className={"fa fa-" + className + " fa-lg"}></span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function OS(props) {
|
|
var osName = "-";
|
|
|
|
if (props.name !== undefined) {
|
|
osName = props.name;
|
|
|
|
if (props.version !== undefined) {
|
|
osName += " " + props.version;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<span> {osName}</span>
|
|
);
|
|
}
|
|
|
|
function Device(props) {
|
|
var deviceName = "-";
|
|
|
|
if (props.model !== undefined) {
|
|
deviceName = props.model;
|
|
}
|
|
|
|
return (
|
|
<span> {deviceName}</span>
|
|
);
|
|
}
|
|
|
|
function Browser(props) {
|
|
var browserName = "-";
|
|
if (props.name !== undefined) {
|
|
browserName = props.name;
|
|
|
|
if (props.version !== undefined) {
|
|
browserName += " - " + props.version;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<span> {browserName}</span>
|
|
);
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(UserTokens);
|