import React from "react"; import { Link, withRouter } from 'react-router-dom' import Transition from "../../../transition.js"; import FadeIn from '../../fade-in' import Modal from './modal' import * as api from '../../api' import numberFormatter, {durationFormatter} from '../../number-formatter' import {parseQuery} from '../../query' const TITLES = { sources: 'Top sources', utm_mediums: 'Top UTM mediums', utm_sources: 'Top UTM sources', utm_campaigns: 'Top UTM campaigns' } class SourcesModal extends React.Component { constructor(props) { super(props) this.state = { loading: true, sources: [], query: parseQuery(props.location.search, props.site), page: 1, moreResultsAvailable: false } } loadSources() { const {site} = this.props const {query, page, sources} = this.state const include = this.showExtra() ? 'bounce_rate,visit_duration' : null api.get(`/api/stats/${encodeURIComponent(site.domain)}/${this.currentFilter()}`, query, {limit: 100, page: page, include: include, show_noref: true}) .then((res) => this.setState({loading: false, sources: sources.concat(res), moreResultsAvailable: res.length === 100})) } componentDidMount() { this.loadSources() } componentDidUpdate(prevProps) { if (this.props.location.pathname !== prevProps.location.pathname) { this.setState({sources: [], loading: true}, this.loadSources.bind(this)) } } currentFilter() { const urlparts = this.props.location.pathname.split('/') return urlparts[urlparts.length - 1] } showExtra() { return this.state.query.period !== 'realtime' && !this.state.query.filters.goal } loadMore() { this.setState({loading: true, page: this.state.page + 1}, this.loadSources.bind(this)) } formatBounceRate(page) { if (typeof(page.bounce_rate) === 'number') { return page.bounce_rate + '%' } else { return '-' } } formatDuration(source) { if (typeof(source.visit_duration) === 'number') { return durationFormatter(source.visit_duration) } else { return '-' } } renderSource(source) { const query = new URLSearchParams(window.location.search) const filter = this.currentFilter() if (filter === 'sources') query.set('source', source.name) if (filter === 'utm_mediums') query.set('utm_medium', source.name) if (filter === 'utm_sources') query.set('utm_source', source.name) if (filter === 'utm_campaigns') query.set('utm_campaign', source.name) return ( { source.name } {numberFormatter(source.count)} {this.showExtra() && {this.formatBounceRate(source)} } {this.showExtra() && {this.formatDuration(source)} } ) } label() { return this.state.query.period === 'realtime' ? 'Current visitors' : 'Visitors' } renderLoading() { if (this.state.loading) { return
} else if (this.state.moreResultsAvailable) { return (
) } } title() { return TITLES[this.currentFilter()] } render() { return (

{this.title()}

{this.showExtra() && } {this.showExtra() && } { this.state.sources.map(this.renderSource.bind(this)) }
Source {this.label()}Bounce rateVisit duration
{ this.renderLoading() }
) } } export default withRouter(SourcesModal)