175 lines
3.9 KiB
JavaScript
175 lines
3.9 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,
|
|
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 = ({ ua, device, browser }) => {
|
|
var className;
|
|
if (ua === "canape-cli") {
|
|
className = "terminal";
|
|
} else if (device.type == "mobile") {
|
|
className = "mobile";
|
|
} else {
|
|
switch (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>;
|
|
};
|
|
Logo.propTypes = {
|
|
ua: PropTypes.string,
|
|
device: PropTypes.object,
|
|
browser: PropTypes.object
|
|
};
|
|
|
|
const OS = ({ name, version }) => {
|
|
var osName = "-";
|
|
|
|
if (name !== undefined) {
|
|
osName = name;
|
|
|
|
if (version !== undefined) {
|
|
osName += " " + version;
|
|
}
|
|
}
|
|
|
|
return <span> {osName}</span>;
|
|
};
|
|
OS.propTypes = {
|
|
name: PropTypes.string,
|
|
version: PropTypes.string
|
|
};
|
|
|
|
const Device = ({ model }) => {
|
|
var deviceName = "-";
|
|
|
|
if (model !== undefined) {
|
|
deviceName = model;
|
|
}
|
|
|
|
return <span> {deviceName}</span>;
|
|
};
|
|
Device.propTypes = {
|
|
model: PropTypes.string
|
|
};
|
|
|
|
const Browser = ({ name, version }) => {
|
|
var browserName = "-";
|
|
if (name !== undefined) {
|
|
browserName = name;
|
|
|
|
if (version !== undefined) {
|
|
browserName += " - " + version;
|
|
}
|
|
}
|
|
|
|
return <span> {browserName}</span>;
|
|
};
|
|
Browser.propTypes = {
|
|
name: PropTypes.string,
|
|
version: PropTypes.string
|
|
};
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(UserTokens);
|