2021-10-14 11:55:43 +03:00
|
|
|
import React from 'react';
|
|
|
|
|
2021-12-03 14:59:32 +03:00
|
|
|
import * as storage from '../../util/storage'
|
2021-10-14 11:55:43 +03:00
|
|
|
import CountriesMap from './map'
|
|
|
|
|
2021-11-23 12:39:09 +03:00
|
|
|
import * as api from '../../api'
|
2021-12-03 14:59:32 +03:00
|
|
|
import {apiPath, sitePath} from '../../util/url'
|
2021-11-23 12:39:09 +03:00
|
|
|
import ListReport from '../reports/list'
|
|
|
|
|
2021-12-13 15:45:19 +03:00
|
|
|
function Countries({query, site, onClick}) {
|
2021-11-25 13:00:17 +03:00
|
|
|
function fetchData() {
|
|
|
|
return api.get(apiPath(site, '/countries'), query, {limit: 9}).then((res) => {
|
|
|
|
return res.map(row => Object.assign({}, row, {percentage: undefined}))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-12-01 16:31:50 +03:00
|
|
|
function renderIcon(country) {
|
2021-12-31 13:16:25 +03:00
|
|
|
return <span className="mr-1">{country.flag}</span>
|
2021-12-01 16:31:50 +03:00
|
|
|
}
|
|
|
|
|
2021-11-25 13:00:17 +03:00
|
|
|
return (
|
|
|
|
<ListReport
|
|
|
|
fetchData={fetchData}
|
|
|
|
filter={{country: 'code', country_name: 'name'}}
|
2021-12-13 15:45:19 +03:00
|
|
|
onClick={onClick}
|
2021-11-25 13:00:17 +03:00
|
|
|
keyLabel="Country"
|
|
|
|
detailsLink={sitePath(site, '/countries')}
|
|
|
|
query={query}
|
2021-12-01 16:31:50 +03:00
|
|
|
renderIcon={renderIcon}
|
2021-11-25 13:00:17 +03:00
|
|
|
color="bg-orange-50"
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-12-13 15:45:19 +03:00
|
|
|
function Regions({query, site, onClick}) {
|
2021-11-23 12:39:09 +03:00
|
|
|
function fetchData() {
|
2021-12-30 11:59:45 +03:00
|
|
|
return api.get(apiPath(site, '/regions'), query, {limit: 9})
|
2021-11-23 12:39:09 +03:00
|
|
|
}
|
|
|
|
|
2021-12-01 16:31:50 +03:00
|
|
|
function renderIcon(region) {
|
|
|
|
return <span className="mr-1">{region.country_flag}</span>
|
|
|
|
}
|
|
|
|
|
2021-11-23 12:39:09 +03:00
|
|
|
return (
|
|
|
|
<ListReport
|
|
|
|
fetchData={fetchData}
|
|
|
|
filter={{region: 'code', region_name: 'name'}}
|
2021-12-13 15:45:19 +03:00
|
|
|
onClick={onClick}
|
2021-11-23 12:39:09 +03:00
|
|
|
keyLabel="Region"
|
|
|
|
detailsLink={sitePath(site, '/regions')}
|
|
|
|
query={query}
|
2021-12-01 16:31:50 +03:00
|
|
|
renderIcon={renderIcon}
|
2021-11-25 13:00:17 +03:00
|
|
|
color="bg-orange-50"
|
2021-11-23 12:39:09 +03:00
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function Cities({query, site}) {
|
|
|
|
function fetchData() {
|
|
|
|
return api.get(apiPath(site, '/cities'), query, {limit: 9})
|
|
|
|
}
|
|
|
|
|
2021-12-09 15:21:26 +03:00
|
|
|
function renderIcon(city) {
|
2021-12-31 13:16:25 +03:00
|
|
|
return <span className="mr-1">{city.country_flag}</span>
|
2021-12-09 15:21:26 +03:00
|
|
|
}
|
|
|
|
|
2021-11-23 12:39:09 +03:00
|
|
|
return (
|
|
|
|
<ListReport
|
|
|
|
fetchData={fetchData}
|
|
|
|
filter={{city: 'code', city_name: 'name'}}
|
|
|
|
keyLabel="City"
|
|
|
|
detailsLink={sitePath(site, '/cities')}
|
|
|
|
query={query}
|
2021-12-09 15:21:26 +03:00
|
|
|
renderIcon={renderIcon}
|
2021-11-25 13:00:17 +03:00
|
|
|
color="bg-orange-50"
|
2021-11-23 12:39:09 +03:00
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-14 11:55:43 +03:00
|
|
|
const labelFor = {
|
|
|
|
'countries': 'Countries',
|
|
|
|
'regions': 'Regions',
|
|
|
|
'cities': 'Cities',
|
|
|
|
}
|
|
|
|
|
|
|
|
export default class Locations extends React.Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props)
|
2021-12-13 15:45:19 +03:00
|
|
|
this.onCountryFilter = this.onCountryFilter.bind(this)
|
|
|
|
this.onRegionFilter = this.onRegionFilter.bind(this)
|
2021-10-14 11:55:43 +03:00
|
|
|
this.tabKey = `geoTab__${ props.site.domain}`
|
|
|
|
const storedTab = storage.getItem(this.tabKey)
|
|
|
|
this.state = {
|
|
|
|
mode: storedTab || 'map'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-14 11:27:02 +03:00
|
|
|
componentDidUpdate(prevProps) {
|
|
|
|
const isRemovingFilter = (filterName) => {
|
|
|
|
return prevProps.query.filters[filterName] && !this.props.query.filters[filterName]
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.state.mode === 'cities' && isRemovingFilter('region')) {
|
|
|
|
this.setMode('regions')()
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.state.mode === 'regions' && isRemovingFilter('country')) {
|
2021-12-14 12:54:36 +03:00
|
|
|
this.setMode(this.countriesRestoreMode || 'countries')()
|
2021-12-14 11:27:02 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-14 11:55:43 +03:00
|
|
|
setMode(mode) {
|
|
|
|
return () => {
|
|
|
|
storage.setItem(this.tabKey, mode)
|
|
|
|
this.setState({mode})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-14 12:54:36 +03:00
|
|
|
onCountryFilter(mode) {
|
|
|
|
return () => {
|
|
|
|
this.countriesRestoreMode = mode
|
|
|
|
this.setMode('regions')()
|
|
|
|
}
|
2021-12-13 15:45:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
onRegionFilter() {
|
|
|
|
this.setMode('cities')()
|
|
|
|
}
|
|
|
|
|
2021-10-14 11:55:43 +03:00
|
|
|
renderContent() {
|
|
|
|
switch(this.state.mode) {
|
2021-11-23 12:39:09 +03:00
|
|
|
case "cities":
|
2023-01-02 18:42:57 +03:00
|
|
|
return <Cities site={this.props.site} query={this.props.query} />
|
2021-11-23 12:39:09 +03:00
|
|
|
case "regions":
|
2023-01-02 18:42:57 +03:00
|
|
|
return <Regions onClick={this.onRegionFilter} site={this.props.site} query={this.props.query} />
|
2021-10-14 11:55:43 +03:00
|
|
|
case "countries":
|
2023-01-02 18:42:57 +03:00
|
|
|
return <Countries onClick={this.onCountryFilter('countries')} site={this.props.site} query={this.props.query} />
|
2021-10-14 11:55:43 +03:00
|
|
|
case "map":
|
|
|
|
default:
|
2023-01-02 18:42:57 +03:00
|
|
|
return <CountriesMap onClick={this.onCountryFilter('map')} site={this.props.site} query={this.props.query}/>
|
2021-10-14 11:55:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
renderPill(name, mode) {
|
|
|
|
const isActive = this.state.mode === mode
|
|
|
|
|
|
|
|
if (isActive) {
|
|
|
|
return (
|
|
|
|
<li
|
2021-11-29 17:21:09 +03:00
|
|
|
className="inline-block h-5 text-indigo-700 dark:text-indigo-500 font-bold active-prop-heading"
|
2021-10-14 11:55:43 +03:00
|
|
|
>
|
|
|
|
{name}
|
|
|
|
</li>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<li
|
|
|
|
className="hover:text-indigo-600 cursor-pointer"
|
|
|
|
onClick={this.setMode(mode)}
|
|
|
|
>
|
|
|
|
{name}
|
|
|
|
</li>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className="stats-item flex flex-col w-full mt-6 stats-item--has-header"
|
|
|
|
>
|
|
|
|
<div
|
2021-12-02 12:53:29 +03:00
|
|
|
className="stats-item-header flex flex-col flex-grow bg-white dark:bg-gray-825 shadow-xl rounded p-4 relative"
|
2021-10-14 11:55:43 +03:00
|
|
|
>
|
|
|
|
<div className="w-full flex justify-between">
|
|
|
|
<h3 className="font-bold dark:text-gray-100">
|
|
|
|
{labelFor[this.state.mode] || 'Locations'}
|
|
|
|
</h3>
|
|
|
|
<ul className="flex font-medium text-xs text-gray-500 dark:text-gray-400 space-x-2">
|
|
|
|
{ this.renderPill('Map', 'map') }
|
|
|
|
{ this.renderPill('Countries', 'countries') }
|
2021-12-31 13:16:25 +03:00
|
|
|
{ this.renderPill('Regions', 'regions') }
|
|
|
|
{ this.renderPill('Cities', 'cities') }
|
2021-10-14 11:55:43 +03:00
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
{ this.renderContent() }
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|