You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.6 KiB
92 lines
3.6 KiB
import React, { Component } from 'react'
|
|
import { Container, Table } from 'semantic-ui-react'
|
|
import Moment from 'react-moment';
|
|
import toastr from 'toastr'
|
|
|
|
export default class VisitorComponent extends Component {
|
|
state = {
|
|
visitors: [],
|
|
info: null
|
|
}
|
|
|
|
componentWillMount() {
|
|
this.setState({ id: this.props.match.params.id })
|
|
fetch("/api/v1/protected/lookup", {
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
ID: this.props.match.params.id
|
|
}),
|
|
headers: {
|
|
'Authorization': window.localStorage.getItem('token'),
|
|
'Content-Type': 'application/json'
|
|
}
|
|
})
|
|
.then(res => res.ok ? res.json() : Promise.reject(res.json()))
|
|
.then(info => this.setState({ info }))
|
|
.catch(e => {
|
|
toastr.error(`Could not fetch lookup: ${e}`)
|
|
})
|
|
this.reloadVisitors()
|
|
this.loop = setInterval(this.reloadVisitors, 1000)
|
|
}
|
|
|
|
reloadVisitors = () => {
|
|
fetch('/api/v1/protected/visitors', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
ID: this.props.match.params.id
|
|
}),
|
|
headers: {
|
|
'Authorization': window.localStorage.getItem('token'),
|
|
'Content-Type': 'application/json'
|
|
}
|
|
})
|
|
.then(res => res.ok ? res.json() : Promise.reject(res.json()))
|
|
.then(visitors => this.setState({ visitors }))
|
|
.catch(e => e.done(res => toastr.error(`Could not fetch visitors: ${res}`)))
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
clearInterval(this.loop)
|
|
}
|
|
|
|
// getUTMSource is a function which generates the output for the utm[...] table column
|
|
getUTMSource(visit) {
|
|
return [visit.UTMSource, visit.UTMMedium, visit.UTMCampaign, visit.UTMContent, visit.UTMTerm]
|
|
.map(value => value ? value : null)
|
|
.filter(v => v)
|
|
.map((value, idx, data) => value + (idx !== data.length - 1 ? ", " : ""))
|
|
.join("")
|
|
}
|
|
|
|
render() {
|
|
const { visitors, id, info } = this.state
|
|
return (
|
|
<Container >
|
|
{info && <p>
|
|
Entry with id '{id}' was created at <Moment>{info.CreatedOn}</Moment> and redirects to '{info.URL}'. Currently it has {visitors.length} visits.
|
|
</p>}
|
|
<Table celled>
|
|
<Table.Header>
|
|
<Table.Row>
|
|
<Table.HeaderCell>Timestamp</Table.HeaderCell>
|
|
<Table.HeaderCell>IP</Table.HeaderCell>
|
|
<Table.HeaderCell>User Agent</Table.HeaderCell>
|
|
<Table.HeaderCell>Referer</Table.HeaderCell>
|
|
<Table.HeaderCell>UTM (source, medium, campaign, content, term)</Table.HeaderCell>
|
|
</Table.Row>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
{visitors && visitors.map((visit, idx) => <Table.Row key={idx}>
|
|
<Table.Cell><Moment>{visit.Timestamp}</Moment></Table.Cell>
|
|
<Table.Cell>{visit.IP}</Table.Cell>
|
|
<Table.Cell>{visit.UserAgent}</Table.Cell>
|
|
<Table.Cell>{visit.Referer}</Table.Cell>
|
|
<Table.Cell>{this.getUTMSource(visit)}</Table.Cell>
|
|
</Table.Row>)}
|
|
</Table.Body>
|
|
</Table>
|
|
</Container>
|
|
)
|
|
}
|
|
};
|
|
|