import React from 'react'; import { Link } from 'react-router-dom' import FlipMove from 'react-flip-move'; import * as storage from '../../util/storage' import FadeIn from '../../fade-in' import Bar from '../bar' import MoreLink from '../more-link' import numberFormatter from '../../util/number-formatter' import * as api from '../../api' import * as url from '../../util/url' import LazyLoader from '../../components/lazy-loader' class AllSources extends React.Component { constructor(props) { super(props) this.onVisible = this.onVisible.bind(this) this.fetchReferrers = this.fetchReferrers.bind(this) this.state = { loading: true } } onVisible() { this.fetchReferrers() if (this.props.query.period === 'realtime') { document.addEventListener('tick', this.fetchReferrers) } } componentDidUpdate(prevProps) { if (this.props.query !== prevProps.query) { this.setState({ loading: true, referrers: null }) this.fetchReferrers() } } componentWillUnmount() { document.removeEventListener('tick', this.fetchReferrers) } showConversionRate() { return !!this.props.query.filters.goal } fetchReferrers() { api.get(`/api/stats/${encodeURIComponent(this.props.site.domain)}/sources`, this.props.query) .then((res) => this.setState({ loading: false, referrers: res })) } renderReferrer(referrer) { const maxWidthDeduction = this.showConversionRate() ? "10rem" : "5rem" return (
{referrer.name} {numberFormatter(referrer.visitors)} {this.showConversionRate() && {referrer.conversion_rate}%}
) } label() { if (this.props.query.period === 'realtime') { return 'Current visitors' } if (this.showConversionRate()) { return 'Conversions' } return 'Visitors' } renderList() { if (this.state.referrers && this.state.referrers.length > 0) { return (
Source
{this.label()} {this.showConversionRate() && CR}
{this.state.referrers.map(this.renderReferrer.bind(this))}
) } else { return
No data yet
} } render() { return (

Top Sources

{this.props.renderTabs()}
{this.state.loading &&
} {this.renderList()}
) } } const UTM_TAGS = { utm_medium: { label: 'UTM Medium', shortLabel: 'UTM Medium', endpoint: 'utm_mediums' }, utm_source: { label: 'UTM Source', shortLabel: 'UTM Source', endpoint: 'utm_sources' }, utm_campaign: { label: 'UTM Campaign', shortLabel: 'UTM Campai', endpoint: 'utm_campaigns' }, utm_content: { label: 'UTM Content', shortLabel: 'UTM Conten', endpoint: 'utm_contents' }, utm_term: { label: 'UTM Term', shortLabel: 'UTM Term', endpoint: 'utm_terms' }, } class UTMSources extends React.Component { constructor(props) { super(props) this.onVisible = this.onVisible.bind(this) this.fetchReferrers = this.fetchReferrers.bind(this) this.state = { loading: true } } onVisible() { this.fetchReferrers() if (this.props.query.period === 'realtime') { document.addEventListener('tick', this.fetchReferrers) } } componentDidUpdate(prevProps) { if (this.props.query !== prevProps.query || this.props.tab !== prevProps.tab) { this.setState({ loading: true, referrers: null }) this.fetchReferrers() } } componentWillUnmount() { document.removeEventListener('tick', this.fetchReferrers) } showNoRef() { return this.props.query.period === 'realtime' } showConversionRate() { return !!this.props.query.filters.goal } fetchReferrers() { const endpoint = UTM_TAGS[this.props.tab].endpoint api.get(`/api/stats/${encodeURIComponent(this.props.site.domain)}/${endpoint}`, this.props.query) .then((res) => this.setState({ loading: false, referrers: res })) } renderReferrer(referrer) { const maxWidthDeduction = this.showConversionRate() ? "10rem" : "5rem" return (
{referrer.name} {numberFormatter(referrer.visitors)} {this.showConversionRate() && {referrer.conversion_rate}%}
) } label() { if (this.props.query.period === 'realtime') { return 'Current visitors' } if (this.showConversionRate()) { return 'Conversions' } return 'Visitors' } renderList() { if (this.state.referrers && this.state.referrers.length > 0) { return (
{UTM_TAGS[this.props.tab].label}
{this.label()} {this.showConversionRate() && CR}
{this.state.referrers.map(this.renderReferrer.bind(this))}
) } else { return
No data yet
} } render() { return (

Top Sources

{this.props.renderTabs()}
{this.state.loading &&
} {this.renderList()}
) } } import { Fragment } from 'react' import { Menu, Transition } from '@headlessui/react' import { ChevronDownIcon } from '@heroicons/react/20/solid' import classNames from 'classnames' export default class SourceList extends React.Component { constructor(props) { super(props) this.tabKey = 'sourceTab__' + props.site.domain const storedTab = storage.getItem(this.tabKey) this.state = { tab: storedTab || 'all' } } setTab(tab) { return () => { storage.setItem(this.tabKey, tab) this.setState({ tab }) } } renderTabs() { const activeClass = 'inline-block h-5 text-indigo-700 dark:text-indigo-500 font-bold active-prop-heading truncate text-left' const defaultClass = 'hover:text-indigo-600 cursor-pointer truncate text-left' const dropdownOptions = Object.keys(UTM_TAGS) let buttonText = UTM_TAGS[this.state.tab] ? UTM_TAGS[this.state.tab].label : 'Campaigns' return (
All
{buttonText}
{dropdownOptions.map((option) => { return ( {({ active }) => ( {UTM_TAGS[option].label} )} ) })}
) } render() { if (this.state.tab === 'all') { return } else if (Object.keys(UTM_TAGS).includes(this.state.tab)) { return } } }