mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 06:07:17 +01:00
Updated session profile page. Added TypeIcon component. Added useRegionNames hook.
This commit is contained in:
parent
ac60d08ee5
commit
c3c3b46ef6
313 changed files with 197 additions and 94 deletions
18
src/components/common/TypeIcon.tsx
Normal file
18
src/components/common/TypeIcon.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export function TypeIcon({
|
||||
type,
|
||||
value,
|
||||
}: {
|
||||
type: 'browser' | 'country' | 'device' | 'os';
|
||||
value: string;
|
||||
}) {
|
||||
return (
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/${type}/${value || 'unknown'}.png`}
|
||||
alt={value}
|
||||
width={type === 'country' ? undefined : 16}
|
||||
height={type === 'country' ? undefined : 16}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default TypeIcon;
|
||||
|
|
@ -32,6 +32,7 @@ export * from './useLocale';
|
|||
export * from './useMessages';
|
||||
export * from './useModified';
|
||||
export * from './useNavigation';
|
||||
export * from './useRegionNames';
|
||||
export * from './useSticky';
|
||||
export * from './useTeamUrl';
|
||||
export * from './useTheme';
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export function useCountryNames(locale: string) {
|
|||
}
|
||||
}, [locale]);
|
||||
|
||||
return list;
|
||||
return { countryNames: list };
|
||||
}
|
||||
|
||||
export default useCountryNames;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import regions from '../../../public/iso-3166-2.json';
|
|||
export function useFormat() {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { locale } = useLocale();
|
||||
const countryNames = useCountryNames(locale);
|
||||
const { countryNames } = useCountryNames(locale);
|
||||
|
||||
const formatOS = (value: string): string => {
|
||||
return OS_NAMES[value] || value;
|
||||
|
|
|
|||
19
src/components/hooks/useRegionNames.ts
Normal file
19
src/components/hooks/useRegionNames.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import useCountryNames from './useCountryNames';
|
||||
import regions from '../../../public/iso-3166-2.json';
|
||||
|
||||
export function useRegionNames(locale: string) {
|
||||
const { countryNames } = useCountryNames(locale);
|
||||
|
||||
const getRegionName = (regionCode: string, countryCode?: string) => {
|
||||
if (!countryCode) {
|
||||
return regions[regionCode];
|
||||
}
|
||||
|
||||
const region = regionCode.includes('-') ? regionCode : `${countryCode}-${regionCode}`;
|
||||
return regions[region] ? `${regions[region]}, ${countryNames[countryCode]}` : region;
|
||||
};
|
||||
|
||||
return { regionNames: regions, getRegionName };
|
||||
}
|
||||
|
||||
export default useRegionNames;
|
||||
|
|
@ -11,6 +11,7 @@ import Dashboard from 'assets/dashboard.svg';
|
|||
import Eye from 'assets/eye.svg';
|
||||
import Gear from 'assets/gear.svg';
|
||||
import Globe from 'assets/globe.svg';
|
||||
import Location from 'assets/location.svg';
|
||||
import Lock from 'assets/lock.svg';
|
||||
import Logo from 'assets/logo.svg';
|
||||
import Magnet from 'assets/magnet.svg';
|
||||
|
|
@ -38,6 +39,7 @@ const icons = {
|
|||
Eye,
|
||||
Gear,
|
||||
Globe,
|
||||
Location,
|
||||
Lock,
|
||||
Logo,
|
||||
Magnet,
|
||||
|
|
|
|||
|
|
@ -272,6 +272,8 @@ export const labels = defineMessages({
|
|||
previous: { id: 'label.previous', defaultMessage: 'Previous' },
|
||||
previousPeriod: { id: 'label.previous-period', defaultMessage: 'Previous period' },
|
||||
previousYear: { id: 'label.previous-year', defaultMessage: 'Previous year' },
|
||||
lastSeen: { id: 'label.last-seen', defaultMessage: 'Last seen' },
|
||||
firstSeen: { id: 'label.first-seen', defaultMessage: 'First seen' },
|
||||
});
|
||||
|
||||
export const messages = defineMessages({
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import FilterLink from 'components/common/FilterLink';
|
|||
import MetricsTable, { MetricsTableProps } from 'components/metrics/MetricsTable';
|
||||
import { useMessages } from 'components/hooks';
|
||||
import { useFormat } from 'components/hooks';
|
||||
import TypeIcon from 'components/common/TypeIcon';
|
||||
|
||||
export function BrowsersTable(props: MetricsTableProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
|
@ -10,12 +11,7 @@ export function BrowsersTable(props: MetricsTableProps) {
|
|||
function renderLink({ x: browser }) {
|
||||
return (
|
||||
<FilterLink id="browser" value={browser} label={formatBrowser(browser)}>
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/browsers/${browser || 'unknown'}.png`}
|
||||
alt={browser}
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
<TypeIcon type="browser" value={browser} />
|
||||
</FilterLink>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import MetricsTable, { MetricsTableProps } from './MetricsTable';
|
||||
import { emptyFilter } from 'lib/filters';
|
||||
import FilterLink from 'components/common/FilterLink';
|
||||
import TypeIcon from 'components/common/TypeIcon';
|
||||
import { useLocale } from 'components/hooks';
|
||||
import { useMessages } from 'components/hooks';
|
||||
import { useCountryNames } from 'components/hooks';
|
||||
|
|
@ -8,7 +9,7 @@ import { useCountryNames } from 'components/hooks';
|
|||
export function CitiesTable(props: MetricsTableProps) {
|
||||
const { locale } = useLocale();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const countryNames = useCountryNames(locale);
|
||||
const { countryNames } = useCountryNames(locale);
|
||||
|
||||
const renderLabel = (city: string, country: string) => {
|
||||
const countryName = countryNames[country];
|
||||
|
|
@ -18,12 +19,7 @@ export function CitiesTable(props: MetricsTableProps) {
|
|||
const renderLink = ({ x: city, country }) => {
|
||||
return (
|
||||
<FilterLink id="city" value={city} label={renderLabel(city, country)}>
|
||||
{country && (
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/flags/${country?.toLowerCase() || 'xx'}.png`}
|
||||
alt={country}
|
||||
/>
|
||||
)}
|
||||
{country && <TypeIcon type="country" value={country} />}
|
||||
</FilterLink>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import FilterLink from 'components/common/FilterLink';
|
|||
import { useCountryNames } from 'components/hooks';
|
||||
import { useLocale, useMessages, useFormat } from 'components/hooks';
|
||||
import MetricsTable, { MetricsTableProps } from './MetricsTable';
|
||||
import TypeIcon from 'components/common/TypeIcon';
|
||||
|
||||
export function CountriesTable({
|
||||
onDataLoad,
|
||||
|
|
@ -10,7 +11,7 @@ export function CountriesTable({
|
|||
onDataLoad: (data: any) => void;
|
||||
} & MetricsTableProps) {
|
||||
const { locale } = useLocale();
|
||||
const countryNames = useCountryNames(locale);
|
||||
const { countryNames } = useCountryNames(locale);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { formatCountry } = useFormat();
|
||||
|
||||
|
|
@ -26,10 +27,7 @@ export function CountriesTable({
|
|||
value={countryNames[code] && code}
|
||||
label={formatCountry(code)}
|
||||
>
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/flags/${code?.toLowerCase() || 'xx'}.png`}
|
||||
alt={code}
|
||||
/>
|
||||
<TypeIcon type="country" value={code?.toLowerCase()} />
|
||||
</FilterLink>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import MetricsTable, { MetricsTableProps } from './MetricsTable';
|
|||
import FilterLink from 'components/common/FilterLink';
|
||||
import { useMessages } from 'components/hooks';
|
||||
import { useFormat } from 'components/hooks';
|
||||
import TypeIcon from 'components/common/TypeIcon';
|
||||
|
||||
export function DevicesTable(props: MetricsTableProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
|
@ -10,14 +11,7 @@ export function DevicesTable(props: MetricsTableProps) {
|
|||
function renderLink({ x: device }) {
|
||||
return (
|
||||
<FilterLink id="device" value={labels[device] && device} label={formatDevice(device)}>
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/device/${
|
||||
device?.toLowerCase() || 'unknown'
|
||||
}.png`}
|
||||
alt={device}
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
<TypeIcon type="device" value={device?.toLowerCase()} />
|
||||
</FilterLink>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import MetricsTable, { MetricsTableProps } from './MetricsTable';
|
||||
import FilterLink from 'components/common/FilterLink';
|
||||
import { useMessages, useFormat } from 'components/hooks';
|
||||
import TypeIcon from 'components/common/TypeIcon';
|
||||
|
||||
export function OSTable(props: MetricsTableProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
|
@ -9,14 +10,7 @@ export function OSTable(props: MetricsTableProps) {
|
|||
function renderLink({ x: os }) {
|
||||
return (
|
||||
<FilterLink id="os" value={os} label={formatOS(os)}>
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/os/${
|
||||
os?.toLowerCase()?.replaceAll(/\W/g, '-') || 'unknown'
|
||||
}.png`}
|
||||
alt={os}
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
<TypeIcon type="os" value={os?.toLowerCase()?.replaceAll(/\W/g, '-')} />
|
||||
</FilterLink>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,18 @@
|
|||
import FilterLink from 'components/common/FilterLink';
|
||||
import { emptyFilter } from 'lib/filters';
|
||||
import { useLocale } from 'components/hooks';
|
||||
import { useMessages } from 'components/hooks';
|
||||
import { useCountryNames } from 'components/hooks';
|
||||
import { useMessages, useLocale, useRegionNames } from 'components/hooks';
|
||||
import MetricsTable, { MetricsTableProps } from './MetricsTable';
|
||||
import regions from '../../../public/iso-3166-2.json';
|
||||
import TypeIcon from 'components/common/TypeIcon';
|
||||
|
||||
export function RegionsTable(props: MetricsTableProps) {
|
||||
const { locale } = useLocale();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const countryNames = useCountryNames(locale);
|
||||
|
||||
const renderLabel = (code: string, country: string) => {
|
||||
const region = code.includes('-') ? code : `${country}-${code}`;
|
||||
return regions[region] ? `${regions[region]}, ${countryNames[country]}` : region;
|
||||
};
|
||||
const { getRegionName } = useRegionNames(locale);
|
||||
|
||||
const renderLink = ({ x: code, country }) => {
|
||||
return (
|
||||
<FilterLink id="region" className={locale} value={code} label={renderLabel(code, country)}>
|
||||
<img
|
||||
src={`${process.env.basePath || ''}/images/flags/${country?.toLowerCase() || 'xx'}.png`}
|
||||
alt={code}
|
||||
/>
|
||||
<FilterLink id="region" className={locale} value={code} label={getRegionName(code, country)}>
|
||||
<TypeIcon type="country" value={country?.toLowerCase()} />
|
||||
</FilterLink>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export function WorldMap({ data = [], className }: { data?: any[]; className?: s
|
|||
const { theme, colors } = useTheme();
|
||||
const { locale } = useLocale();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const countryNames = useCountryNames(locale);
|
||||
const { countryNames } = useCountryNames(locale);
|
||||
const visitorsLabel = formatMessage(labels.visitors).toLocaleLowerCase(locale);
|
||||
const metrics = useMemo(() => (data ? percentFilter(data) : []), [data]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue