159 lines
3.6 KiB
JavaScript

import React, { useState } from "react"
import PropTypes from "prop-types"
import { connect } from "react-redux"
import { UAParser } from "ua-parser-js"
import moment from "moment"
import { Map, List } from "immutable"
import { getUserTokens, deleteUserToken } from "../../actions/users"
const mapStateToProps = (state) => ({
tokens: state.userStore.get("tokens"),
});
const mapDispatchToProps = { getUserTokens, deleteUserToken };
const UserTokens = (props) => {
const [fetched, setIsFetched] = useState(false);
if (!fetched) {
props.getUserTokens();
setIsFetched(true);
}
return (
<div className="row">
<div className="col-12">
{props.tokens.map((el, index) => (
<Token key={index} data={el} deleteToken={props.deleteUserToken} />
))}
</div>
</div>
);
}
UserTokens.propTypes = {
tokens: PropTypes.instanceOf(List),
isLoading: PropTypes.bool.isRequired,
getUserTokens: PropTypes.func.isRequired,
deleteUserToken: PropTypes.func.isRequired,
};
const Token = (props) => {
const ua = UAParser(props.data.get("user_agent"));
return (
<div className="card mt-3">
<div className="card-header">
<h4>
<Logo {...ua} />
<span className="ml-3">{props.data.get("description")}</span>
<Actions {...props} />
</h4>
</div>
<div className="card-body row">
<div className="col-12 col-md-6">
<p>Last IP: {props.data.get("ip")}</p>
<p>Last used: {moment(props.data.get("last_used")).fromNow()}</p>
<p>Created: {moment(props.data.get("created_at")).fromNow()}</p>
</div>
<div className="col-12 col-md-6">
<p>Device: <Device {...ua.device}/></p>
<p>OS: <OS {...ua.os}/></p>
<p>Browser: <Browser {...ua.browser}/></p>
</div>
</div>
</div>
);
}
Token.propTypes = {
data: PropTypes.instanceOf(Map).isRequired,
};
const Actions = (props) => {
const handleClick = () => {
props.deleteToken(props.data.get("token"));
}
return (
<span
className="fa fa-trash fa-lg pull-right clickable"
onClick={handleClick}>
</span>
);
}
Actions.propTypes = {
data: PropTypes.instanceOf(Map).isRequired,
deleteToken: PropTypes.func.isRequired,
};
const 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 (<span className={`fa fa-${className}`}></span>);
}
const OS = (props) => {
var osName = "-";
if (props.name !== undefined) {
osName = props.name;
if (props.version !== undefined) {
osName += " " + props.version;
}
}
return (
<span> {osName}</span>
);
}
const Device = (props) => {
var deviceName = "-";
if (props.model !== undefined) {
deviceName = props.model;
}
return (
<span> {deviceName}</span>
);
}
const 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);