mirror of
https://github.com/umami-software/umami.git
synced 2025-12-08 05:12:36 +01:00
Renamed query hooks. Fixed conversion bugs.
This commit is contained in:
parent
adca3c36d0
commit
7886c3f393
110 changed files with 423 additions and 489 deletions
|
|
@ -6,10 +6,10 @@ import { UpdateNotice } from './UpdateNotice';
|
|||
import { Nav } from '@/app/(main)/Nav';
|
||||
import { MenuBar } from '@/app/(main)/MenuBar';
|
||||
import { Page } from '@/components/layout/Page';
|
||||
import { useLogin, useConfig } from '@/components/hooks';
|
||||
import { useLoginQuery, useConfig } from '@/components/hooks';
|
||||
|
||||
export function App({ children }) {
|
||||
const { user, isLoading, error } = useLogin();
|
||||
const { user, isLoading, error } = useLoginQuery();
|
||||
const config = useConfig();
|
||||
const pathname = usePathname();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export function MenuBar(props: RowProps) {
|
|||
paddingY="3"
|
||||
paddingX="3"
|
||||
paddingRight="5"
|
||||
backgroundColor="1"
|
||||
>
|
||||
<Row>
|
||||
<Button onPress={() => setCollapsed(!isCollapsed)} variant="quiet">
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import Link from 'next/link';
|
||||
import { SideNav, SideNavHeader, SideNavSection, SideNavItem } from '@umami/react-zen';
|
||||
import { Lucide, Icons } from '@/components/icons';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import useGlobalState from '@/components/hooks/useGlobalState';
|
||||
|
||||
export function Nav(props: any) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl, pathname } = useTeamUrl();
|
||||
const { renderTeamUrl, pathname } = useNavigation();
|
||||
const [isCollapsed] = useGlobalState('sidenav-collapsed');
|
||||
|
||||
const links = [
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ import { WebsiteChartList } from '../websites/[websiteId]/WebsiteChartList';
|
|||
import { DashboardSettingsButton } from '@/app/(main)/dashboard/DashboardSettingsButton';
|
||||
import { DashboardEdit } from '@/app/(main)/dashboard/DashboardEdit';
|
||||
import { EmptyPlaceholder } from '@/components/common/EmptyPlaceholder';
|
||||
import { useMessages, useTeamUrl, useWebsites } from '@/components/hooks';
|
||||
import { useMessages, useNavigation, useWebsites } from '@/components/hooks';
|
||||
import { useDashboard } from '@/store/dashboard';
|
||||
import { LinkButton } from '@/components/common/LinkButton';
|
||||
|
||||
export function DashboardPage() {
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const { teamId, renderTeamUrl } = useTeamUrl();
|
||||
const { teamId, renderTeamUrl } = useNavigation();
|
||||
const { showCharts, editing, isEdited } = useDashboard();
|
||||
const pageSize = isEdited ? 200 : 10;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { Form, FormField, Column, Label } from '@umami/react-zen';
|
||||
import { Column, Label } from '@umami/react-zen';
|
||||
import { TimezoneSetting } from '@/app/(main)/profile/TimezoneSetting';
|
||||
import { DateRangeSetting } from '@/app/(main)/profile/DateRangeSetting';
|
||||
import { LanguageSetting } from '@/app/(main)/profile/LanguageSetting';
|
||||
import { ThemeSetting } from '@/app/(main)/profile/ThemeSetting';
|
||||
import { PasswordChangeButton } from './PasswordChangeButton';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
|
||||
export function ProfileSettings() {
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const cloudMode = !!process.env.cloudMode;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { useReports } from '@/components/hooks';
|
||||
import { useReportsQuery } from '@/components/hooks';
|
||||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { ReportsTable } from './ReportsTable';
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ export function ReportsDataTable({
|
|||
teamId?: string;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const queryResult = useReports({ websiteId, teamId });
|
||||
const queryResult = useReportsQuery({ websiteId, teamId });
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult} renderEmpty={() => children}>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { Icon, Icons, Text } from '@umami/react-zen';
|
||||
import { useLogin, useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages, useNavigation } from '@/components/hooks';
|
||||
import { LinkButton } from '@/components/common/LinkButton';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
|
||||
export function ReportsHeader() {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { user } = useLogin();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
const { user } = useLoginQuery();
|
||||
const canEdit = user.role !== ROLES.viewOnly;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
import { Metadata } from 'next';
|
||||
import { ReportsHeader } from './ReportsHeader';
|
||||
import { ReportsDataTable } from './ReportsDataTable';
|
||||
import { useTeamUrl } from '@/components/hooks';
|
||||
import { useNavigation } from '@/components/hooks';
|
||||
|
||||
export function ReportsPage() {
|
||||
const { teamId } = useTeamUrl();
|
||||
const { teamId } = useNavigation();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { Icon, Icons, Text, DataTable, DataColumn, Row } from '@umami/react-zen';
|
||||
import { LinkButton } from '@/components/common/LinkButton';
|
||||
import { useMessages, useLogin, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useLoginQuery, useNavigation } from '@/components/hooks';
|
||||
import { REPORT_TYPES } from '@/lib/constants';
|
||||
import { ReportDeleteButton } from './ReportDeleteButton';
|
||||
|
||||
export function ReportsTable({ data = [], showDomain }: { data: any[]; showDomain?: boolean }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { user } = useLoginQuery();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
return (
|
||||
<DataTable data={data}>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Column, Label } from '@umami/react-zen';
|
|||
import { parseDateRange } from '@/lib/date';
|
||||
import { DateFilter } from '@/components/input/DateFilter';
|
||||
import { WebsiteSelect } from '@/components/input/WebsiteSelect';
|
||||
import { useMessages, useTeamUrl, useWebsite } from '@/components/hooks';
|
||||
import { useMessages, useNavigation, useWebsiteQuery } from '@/components/hooks';
|
||||
import { ReportContext } from './Report';
|
||||
import styles from './BaseParameters.module.css';
|
||||
|
||||
|
|
@ -22,11 +22,11 @@ export function BaseParameters({
|
|||
}: BaseParametersProps) {
|
||||
const { report, updateReport } = useContext(ReportContext);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { teamId } = useTeamUrl();
|
||||
const { teamId } = useNavigation();
|
||||
const { parameters } = report || {};
|
||||
const { websiteId, dateRange } = parameters || {};
|
||||
const { value, startDate, endDate } = dateRange || {};
|
||||
const { data: website } = useWebsite(websiteId);
|
||||
const { data: website } = useWebsiteQuery(websiteId);
|
||||
const { name } = website || {};
|
||||
|
||||
const handleWebsiteSelect = (websiteId: string) => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { useFilters, useFormat, useMessages, useWebsiteValues } from '@/components/hooks';
|
||||
import { useFilters, useFormat, useMessages, useWebsiteValuesQuery } from '@/components/hooks';
|
||||
import { OPERATORS } from '@/lib/constants';
|
||||
import { isEqualsOperator } from '@/lib/params';
|
||||
import {
|
||||
|
|
@ -62,7 +62,7 @@ export function FieldFilterEditForm({
|
|||
data: values = [],
|
||||
isLoading,
|
||||
refetch,
|
||||
} = useWebsiteValues({
|
||||
} = useWebsiteValuesQuery({
|
||||
websiteId,
|
||||
type: name,
|
||||
startDate,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { createContext, ReactNode } from 'react';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import classNames from 'classnames';
|
||||
import { useReport } from '@/components/hooks';
|
||||
import { useReportQuery } from '@/components/hooks';
|
||||
import styles from './Report.module.css';
|
||||
|
||||
export const ReportContext = createContext(null);
|
||||
|
|
@ -17,7 +17,7 @@ export function Report({
|
|||
children: ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
const report = useReport(reportId, defaultParameters);
|
||||
const report = useReportQuery(reportId, defaultParameters);
|
||||
|
||||
if (!report) {
|
||||
return reportId ? <Loading position="page" /> : null;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useContext } from 'react';
|
||||
import { Icon, LoadingButton, InlineEditField, useToast } from '@umami/react-zen';
|
||||
import { useMessages, useApi, useNavigation, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useApi, useNavigation } from '@/components/hooks';
|
||||
import { ReportContext } from './Report';
|
||||
import styles from './ReportHeader.module.css';
|
||||
import { REPORT_TYPES } from '@/lib/constants';
|
||||
|
|
@ -10,8 +10,7 @@ export function ReportHeader({ icon }) {
|
|||
const { report, updateReport } = useContext(ReportContext);
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const { toast } = useToast();
|
||||
const { router } = useNavigation();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { router, renderTeamUrl } = useNavigation();
|
||||
|
||||
const { post, useMutation } = useApi();
|
||||
const { mutate: create, isPending: isCreating } = useMutation({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
'use client';
|
||||
import { useReport } from '@/components/hooks';
|
||||
import { useReportQuery } from '@/components/hooks';
|
||||
import { EventDataReport } from '../event-data/EventDataReport';
|
||||
import { FunnelReport } from '../funnel/FunnelReport';
|
||||
import { GoalsReport } from '../goals/GoalsReport';
|
||||
|
|
@ -21,7 +21,7 @@ const reports = {
|
|||
};
|
||||
|
||||
export function ReportPage({ reportId }: { reportId: string }) {
|
||||
const { report } = useReport(reportId);
|
||||
const { report } = useReportQuery(reportId);
|
||||
|
||||
if (!report) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { Icon, Text, Row, Column, Grid } from '@umami/react-zen';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { LinkButton } from '@/components/common/LinkButton';
|
||||
|
||||
export function ReportTemplates({ showHeader = true }: { showHeader?: boolean }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
const reports = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useContext } from 'react';
|
||||
import { GridTable, GridColumn } from '@umami/react-zen';
|
||||
import { DataTable, DataColumn } from '@umami/react-zen';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { ReportContext } from '../[reportId]/Report';
|
||||
|
||||
|
|
@ -8,10 +8,10 @@ export function EventDataTable() {
|
|||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
return (
|
||||
<GridTable data={report?.data || []}>
|
||||
<GridColumn name="field" label={formatMessage(labels.field)} />
|
||||
<GridColumn name="value" label={formatMessage(labels.value)} />
|
||||
<GridColumn name="total" label={formatMessage(labels.total)} />
|
||||
</GridTable>
|
||||
<DataTable data={report?.data || []}>
|
||||
<DataColumn id="field" label={formatMessage(labels.field)} />
|
||||
<DataColumn id="value" label={formatMessage(labels.value)} />
|
||||
<DataColumn id="total" label={formatMessage(labels.total)} />
|
||||
</DataTable>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useContext, useMemo, useState } from 'react';
|
||||
import { TextOverflow, TooltipPopup } from '@umami/react-zen';
|
||||
import { TooltipTrigger, Tooltip, Focusable } from '@umami/react-zen';
|
||||
import { firstBy } from 'thenby';
|
||||
import classNames from 'classnames';
|
||||
import { useEscapeKey, useMessages } from '@/components/hooks';
|
||||
|
|
@ -192,13 +192,18 @@ export function JourneyView() {
|
|||
onClick={() => handleClick(name, columnIndex, paths)}
|
||||
>
|
||||
<div className={styles.name} title={name}>
|
||||
<TextOverflow> {name}</TextOverflow>
|
||||
{name}
|
||||
</div>
|
||||
<TooltipPopup label={dropOffPercent} isDisabled={!selected}>
|
||||
<TooltipTrigger isDisabled={!selected}>
|
||||
<Focusable>
|
||||
<div>{dropOffPercent}</div>
|
||||
</Focusable>
|
||||
<Tooltip>
|
||||
<div className={styles.count} title={nodeCount}>
|
||||
{formatLongNumber(nodeCount)}
|
||||
</div>
|
||||
</TooltipPopup>
|
||||
</Tooltip>
|
||||
</TooltipTrigger>
|
||||
{columnIndex < columns.length &&
|
||||
lines.map(([fromIndex, nodeIndex], i) => {
|
||||
const height =
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useMessages } from '@/components/hooks';
|
||||
import { useRevenueValues } from '@/components/hooks/queries/useRevenueValues';
|
||||
import { useRevenueValuesQuery } from '@/components/hooks/queries/useRevenueValuesQuery';
|
||||
import { useContext } from 'react';
|
||||
import { Select, Form, FormButtons, FormField, ListItem, FormSubmitButton } from '@umami/react-zen';
|
||||
import { BaseParameters } from '../[reportId]/BaseParameters';
|
||||
|
|
@ -11,7 +11,7 @@ export function RevenueParameters() {
|
|||
const { id, parameters } = report || {};
|
||||
const { websiteId, dateRange } = parameters || {};
|
||||
const queryEnabled = websiteId && dateRange;
|
||||
const { data: values = [] } = useRevenueValues(
|
||||
const { data: values = [] } = useRevenueValuesQuery(
|
||||
websiteId,
|
||||
dateRange?.startDate,
|
||||
dateRange?.endDate,
|
||||
|
|
@ -34,7 +34,7 @@ export function RevenueParameters() {
|
|||
rules={{ required: formatMessage(labels.required) }}
|
||||
>
|
||||
<Select items={values.map(item => item.currency)}>
|
||||
{item => <ListItem key={item}>{item}</ListItem>}
|
||||
{(item: any) => <ListItem key={item}>{item}</ListItem>}
|
||||
</Select>
|
||||
</FormField>
|
||||
<FormButtons>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { EmptyPlaceholder } from '@/components/common/EmptyPlaceholder';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { useContext } from 'react';
|
||||
import { GridColumn, GridTable } from '@umami/react-zen';
|
||||
import { DataColumn, DataTable } from '@umami/react-zen';
|
||||
import { ReportContext } from '../[reportId]/Report';
|
||||
import { formatLongCurrency } from '@/lib/format';
|
||||
|
||||
|
|
@ -15,22 +15,22 @@ export function RevenueTable() {
|
|||
}
|
||||
|
||||
return (
|
||||
<GridTable data={data.table || []}>
|
||||
<GridColumn name="currency" label={formatMessage(labels.currency)} alignment="end">
|
||||
{row => row.currency}
|
||||
</GridColumn>
|
||||
<GridColumn name="currency" label={formatMessage(labels.total)} width="300px" alignment="end">
|
||||
{row => formatLongCurrency(row.sum, row.currency)}
|
||||
</GridColumn>
|
||||
<GridColumn name="currency" label={formatMessage(labels.average)} alignment="end">
|
||||
{row => formatLongCurrency(row.count ? row.sum / row.count : 0, row.currency)}
|
||||
</GridColumn>
|
||||
<GridColumn name="currency" label={formatMessage(labels.transactions)} alignment="end">
|
||||
{row => row.count}
|
||||
</GridColumn>
|
||||
<GridColumn name="currency" label={formatMessage(labels.uniqueCustomers)} alignment="end">
|
||||
{row => row.unique_count}
|
||||
</GridColumn>
|
||||
</GridTable>
|
||||
<DataTable data={data.table || []}>
|
||||
<DataColumn id="currency" label={formatMessage(labels.currency)} align="end">
|
||||
{(row: any) => row.currency}
|
||||
</DataColumn>
|
||||
<DataColumn id="currency" label={formatMessage(labels.total)} align="end">
|
||||
{(row: any) => formatLongCurrency(row.sum, row.currency)}
|
||||
</DataColumn>
|
||||
<DataColumn id="currency" label={formatMessage(labels.average)} align="end">
|
||||
{(row: any) => formatLongCurrency(row.count ? row.sum / row.count : 0, row.currency)}
|
||||
</DataColumn>
|
||||
<DataColumn id="currency" label={formatMessage(labels.transactions)} align="end">
|
||||
{(row: any) => row.count}
|
||||
</DataColumn>
|
||||
<DataColumn id="currency" label={formatMessage(labels.uniqueCustomers)} align="end">
|
||||
{(row: any) => row.unique_count}
|
||||
</DataColumn>
|
||||
</DataTable>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
'use client';
|
||||
import { ReactNode } from 'react';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { MenuLayout } from '@/components/layout/MenuLayout';
|
||||
|
||||
export function SettingsLayout({ children }: { children: ReactNode }) {
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
const items = [
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useLogin, useMessages, useModified } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages, useModified } from '@/components/hooks';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Button, Icon, Icons, Modal, DialogTrigger, Dialog, Text } from '@umami/react-zen';
|
||||
import { TeamLeaveForm } from './TeamLeaveForm';
|
||||
|
|
@ -6,7 +6,7 @@ import { TeamLeaveForm } from './TeamLeaveForm';
|
|||
export function TeamLeaveButton({ teamId, teamName }: { teamId: string; teamName: string }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const router = useRouter();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { touch } = useModified();
|
||||
|
||||
const handleLeave = async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { TeamsTable } from '@/app/(main)/settings/teams/TeamsTable';
|
||||
import { useLogin, useTeams } from '@/components/hooks';
|
||||
import { useLoginQuery, useTeamsQuery } from '@/components/hooks';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export function TeamsDataTable({
|
||||
|
|
@ -12,8 +12,8 @@ export function TeamsDataTable({
|
|||
showActions?: boolean;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const { user } = useLogin();
|
||||
const queryResult = useTeams(user.id);
|
||||
const { user } = useLoginQuery();
|
||||
const queryResult = useTeamsQuery(user.id);
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult} renderEmpty={() => children}>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { Row } from '@umami/react-zen';
|
||||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { TeamsJoinButton } from './TeamsJoinButton';
|
||||
import { TeamsAddButton } from './TeamsAddButton';
|
||||
|
||||
export function TeamsHeader({ allowCreate = true }: { allowCreate?: boolean }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const cloudMode = !!process.env.cloudMode;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Button, Icon, Icons, Modal, DialogTrigger, Dialog, Text } from '@umami/react-zen';
|
||||
import { useMessages, useLogin } from '@/components/hooks';
|
||||
import { useMessages, useLoginQuery } from '@/components/hooks';
|
||||
import { UserDeleteForm } from './UserDeleteForm';
|
||||
|
||||
export function UserDeleteButton({
|
||||
|
|
@ -12,7 +12,7 @@ export function UserDeleteButton({
|
|||
onDelete?: () => void;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
|
||||
return (
|
||||
<DialogTrigger>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { useUsers } from '@/components/hooks';
|
||||
import { useUsersQuery } from '@/components/hooks';
|
||||
import { UsersTable } from './UsersTable';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ export function UsersDataTable({
|
|||
showActions?: boolean;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const queryResult = useUsers();
|
||||
const queryResult = useUsersQuery();
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult} renderEmpty={() => children}>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
PasswordField,
|
||||
useToast,
|
||||
} from '@umami/react-zen';
|
||||
import { useApi, useLogin, useMessages, useModified } from '@/components/hooks';
|
||||
import { useApi, useLoginQuery, useMessages, useModified } from '@/components/hooks';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
import { useContext } from 'react';
|
||||
import { UserContext } from './UserProvider';
|
||||
|
|
@ -18,7 +18,7 @@ export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () =
|
|||
const { formatMessage, labels, messages, getMessage } = useMessages();
|
||||
const { post, useMutation } = useApi();
|
||||
const user = useContext(UserContext);
|
||||
const { user: login } = useLogin();
|
||||
const { user: login } = useLoginQuery();
|
||||
const { toast } = useToast();
|
||||
const { touch } = useModified();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { createContext, ReactNode, useEffect } from 'react';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
import { useModified, useUser } from '@/components/hooks';
|
||||
import { useModified, useUserQuery } from '@/components/hooks';
|
||||
|
||||
export const UserContext = createContext(null);
|
||||
|
||||
export function UserProvider({ userId, children }: { userId: string; children: ReactNode }) {
|
||||
const { modified } = useModified(`user:${userId}`);
|
||||
const { data: user, isFetching, isLoading, refetch } = useUser(userId);
|
||||
const { data: user, isFetching, isLoading, refetch } = useUserQuery(userId);
|
||||
|
||||
useEffect(() => {
|
||||
if (modified) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { WebsiteAddButton } from './WebsiteAddButton';
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ export interface WebsitesHeaderProps {
|
|||
|
||||
export function WebsitesHeader({ allowCreate = true }: WebsitesHeaderProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { teamId } = useTeamUrl();
|
||||
const { teamId } = useNavigation();
|
||||
|
||||
return (
|
||||
<PageHeader title={formatMessage(labels.websites)}>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
'use client';
|
||||
import { useLogin } from '@/components/hooks';
|
||||
import { useLoginQuery } from '@/components/hooks';
|
||||
import { WebsitesDataTable } from './WebsitesDataTable';
|
||||
import { WebsitesHeader } from './WebsitesHeader';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
|
||||
export function WebsitesSettingsPage({ teamId }: { teamId: string }) {
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const canCreate = user.role !== ROLES.viewOnly;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { Row, Text, Icon, Icons, DataTable, DataColumn, Button } from '@umami/react-zen';
|
||||
import Link from 'next/link';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
|
||||
export interface WebsitesTableProps {
|
||||
data: any[];
|
||||
|
|
@ -20,7 +20,7 @@ export function WebsitesTable({
|
|||
children,
|
||||
}: WebsitesTableProps) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
if (!data?.length) {
|
||||
return children;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import { Button, Modal, DialogTrigger, Dialog, Column } from '@umami/react-zen';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useLogin, useMessages, useModified, useTeams, useTeamUrl } from '@/components/hooks';
|
||||
import {
|
||||
useLoginQuery,
|
||||
useMessages,
|
||||
useModified,
|
||||
useTeamsQuery,
|
||||
useNavigation,
|
||||
} from '@/components/hooks';
|
||||
import { WebsiteDeleteForm } from './WebsiteDeleteForm';
|
||||
import { WebsiteResetForm } from './WebsiteResetForm';
|
||||
import { WebsiteTransferForm } from './WebsiteTransferForm';
|
||||
|
|
@ -9,11 +15,11 @@ import { ROLES } from '@/lib/constants';
|
|||
|
||||
export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) {
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { touch } = useModified();
|
||||
const { teamId, renderTeamUrl } = useTeamUrl();
|
||||
const { teamId, renderTeamUrl } = useNavigation();
|
||||
const router = useRouter();
|
||||
const { result } = useTeams(user.id);
|
||||
const { result } = useTeamsQuery(user.id);
|
||||
const canTransferWebsite =
|
||||
(
|
||||
!teamId &&
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
ListItem,
|
||||
Text,
|
||||
} from '@umami/react-zen';
|
||||
import { useApi, useLogin, useMessages, useTeams } from '@/components/hooks';
|
||||
import { useApi, useLoginQuery, useMessages, useTeamsQuery } from '@/components/hooks';
|
||||
import { WebsiteContext } from '@/app/(main)/websites/[websiteId]/WebsiteProvider';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ export function WebsiteTransferForm({
|
|||
onSave?: () => void;
|
||||
onClose?: () => void;
|
||||
}) {
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const website = useContext(WebsiteContext);
|
||||
const [teamId, setTeamId] = useState<string>(null);
|
||||
const { formatMessage, labels, messages } = useMessages();
|
||||
|
|
@ -31,7 +31,7 @@ export function WebsiteTransferForm({
|
|||
const { mutate, error } = useMutation({
|
||||
mutationFn: (data: any) => post(`/websites/${websiteId}/transfer`, data),
|
||||
});
|
||||
const { result, query } = useTeams(user.id);
|
||||
const { result, query } = useTeamsQuery(user.id);
|
||||
const isTeamWebsite = !!website?.teamId;
|
||||
|
||||
const items = result.data.filter(({ teamUser }) =>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
'use client';
|
||||
import { createContext, ReactNode, useEffect } from 'react';
|
||||
import { useTeam, useModified } from '@/components/hooks';
|
||||
import { useTeamQuery, useModified } from '@/components/hooks';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
|
||||
export const TeamContext = createContext(null);
|
||||
|
||||
export function TeamProvider({ teamId, children }: { teamId?: string; children: ReactNode }) {
|
||||
const { modified } = useModified(`teams`);
|
||||
const { data: team, isLoading, isFetching, refetch } = useTeam(teamId);
|
||||
const { data: team, isLoading, isFetching, refetch } = useTeamQuery(teamId);
|
||||
|
||||
useEffect(() => {
|
||||
if (teamId && modified) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
'use client';
|
||||
import { ReactNode } from 'react';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { MenuLayout } from '@/components/layout/MenuLayout';
|
||||
|
||||
export function TeamSettingsLayout({ children }: { children: ReactNode }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { teamId } = useTeamUrl();
|
||||
const { teamId } = useNavigation();
|
||||
|
||||
const items = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { TeamMembersTable } from './TeamMembersTable';
|
||||
import { useTeamMembers } from '@/components/hooks';
|
||||
import { useTeamMembersQuery } from '@/components/hooks';
|
||||
|
||||
export function TeamMembersDataTable({
|
||||
teamId,
|
||||
|
|
@ -9,7 +9,7 @@ export function TeamMembersDataTable({
|
|||
teamId: string;
|
||||
allowEdit?: boolean;
|
||||
}) {
|
||||
const queryResult = useTeamMembers(teamId);
|
||||
const queryResult = useTeamMembersQuery(teamId);
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult}>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
import { TeamContext } from '@/app/(main)/teams/[teamId]/TeamProvider';
|
||||
import { TeamMembersDataTable } from './TeamMembersDataTable';
|
||||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export function TeamMembersPage({ teamId }: { teamId: string }) {
|
||||
const team = useContext(TeamContext);
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
const canEdit =
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DataColumn, DataTable } from '@umami/react-zen';
|
||||
import { useMessages, useLogin } from '@/components/hooks';
|
||||
import { useMessages, useLoginQuery } from '@/components/hooks';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
import { TeamMemberRemoveButton } from './TeamMemberRemoveButton';
|
||||
import { TeamMemberEditButton } from './TeamMemberEditButton';
|
||||
|
|
@ -14,7 +14,7 @@ export function TeamMembersTable({
|
|||
allowEdit: boolean;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
|
||||
const roles = {
|
||||
[ROLES.teamOwner]: formatMessage(labels.teamOwner),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { TeamContext } from '@/app/(main)/teams/[teamId]/TeamProvider';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
|
|
@ -13,7 +13,7 @@ import { Panel } from '@/components/layout/Panel';
|
|||
export function TeamDetails({ teamId }: { teamId: string }) {
|
||||
const team = useContext(TeamContext);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const [tab, setTab] = useState('details');
|
||||
|
||||
const isTeamOwner =
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { useTeamWebsites } from '@/components/hooks';
|
||||
import { useTeamWebsitesQuery } from '@/components/hooks';
|
||||
import { TeamWebsitesTable } from './TeamWebsitesTable';
|
||||
|
||||
export function TeamWebsitesDataTable({
|
||||
|
|
@ -9,7 +9,7 @@ export function TeamWebsitesDataTable({
|
|||
teamId: string;
|
||||
allowEdit?: boolean;
|
||||
}) {
|
||||
const queryResult = useTeamWebsites(teamId);
|
||||
const queryResult = useTeamWebsitesQuery(teamId);
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult}>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
import { TeamContext } from '@/app/(main)/teams/[teamId]/TeamProvider';
|
||||
import { WebsiteAddButton } from '@/app/(main)/settings/websites/WebsiteAddButton';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { PageHeader } from '@/components/layout/PageHeader';
|
||||
import { TeamWebsitesDataTable } from './TeamWebsitesDataTable';
|
||||
import { ROLES } from '@/lib/constants';
|
||||
|
|
@ -10,7 +10,7 @@ import { useContext } from 'react';
|
|||
export function TeamWebsitesPage({ teamId }: { teamId: string }) {
|
||||
const team = useContext(TeamContext);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
|
||||
const canEdit =
|
||||
!!team?.teamUser?.find(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DataColumn, DataTable, Icon, Text } from '@umami/react-zen';
|
||||
import { useLogin, useMessages } from '@/components/hooks';
|
||||
import { useLoginQuery, useMessages } from '@/components/hooks';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { LinkButton } from '@/components/common/LinkButton';
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ export function TeamWebsitesTable({
|
|||
data: any[];
|
||||
allowEdit?: boolean;
|
||||
}) {
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
'use client';
|
||||
import { WebsitesHeader } from '@/app/(main)/settings/websites/WebsitesHeader';
|
||||
import { WebsitesDataTable } from '@/app/(main)/settings/websites/WebsitesDataTable';
|
||||
import { useTeamUrl } from '@/components/hooks';
|
||||
import { useNavigation } from '@/components/hooks';
|
||||
|
||||
export function WebsitesPage() {
|
||||
const { teamId } = useTeamUrl();
|
||||
const { teamId } = useNavigation();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useMemo } from 'react';
|
||||
import { PageviewsChart } from '@/components/metrics/PageviewsChart';
|
||||
import { useWebsitePageviews } from '@/components/hooks/queries/useWebsitePageviews';
|
||||
import { useWebsitePageviewsQuery } from '@/components/hooks/queries/useWebsitePageviewsQuery';
|
||||
import { useDateRange } from '@/components/hooks';
|
||||
|
||||
export function WebsiteChart({
|
||||
|
|
@ -12,7 +12,10 @@ export function WebsiteChart({
|
|||
}) {
|
||||
const { dateRange, dateCompare } = useDateRange(websiteId);
|
||||
const { startDate, endDate, unit, value } = dateRange;
|
||||
const { data, isLoading } = useWebsitePageviews(websiteId, compareMode ? dateCompare : undefined);
|
||||
const { data, isLoading } = useWebsitePageviewsQuery(
|
||||
websiteId,
|
||||
compareMode ? dateCompare : undefined,
|
||||
);
|
||||
const { pageviews, sessions, compare } = (data || {}) as any;
|
||||
|
||||
const chartData = useMemo(() => {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { WebsiteChart } from './WebsiteChart';
|
|||
import { useDashboard } from '@/store/dashboard';
|
||||
import { WebsiteHeader } from './WebsiteHeader';
|
||||
import { WebsiteMetricsBar } from './WebsiteMetricsBar';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { LinkButton } from '@/components/common/LinkButton';
|
||||
|
||||
export function WebsiteChartList({
|
||||
|
|
@ -19,7 +19,7 @@ export function WebsiteChartList({
|
|||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { websiteOrder, websiteActive } = useDashboard();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
const ordered = useMemo(() => {
|
||||
return websites
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
.header {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 20px 0px;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
overflow: hidden;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 30px;
|
||||
min-height: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.selected {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.header {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.links {
|
||||
justify-content: space-evenly;
|
||||
flex: 1;
|
||||
border-bottom: 1px solid var(--base300);
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.icon,
|
||||
.icon svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +1,31 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { Button, Icon, Text } from '@umami/react-zen';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import classNames from 'classnames';
|
||||
import { Row, Heading } from '@umami/react-zen';
|
||||
import { Favicon } from '@/components/common/Favicon';
|
||||
import { useMessages, useTeamUrl, useWebsite } from '@/components/hooks';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { useWebsiteQuery } from '@/components/hooks';
|
||||
import { ActiveUsers } from '@/components/metrics/ActiveUsers';
|
||||
import styles from './WebsiteHeader.module.css';
|
||||
import { WebsiteTabs } from '@/app/(main)/websites/[websiteId]/WebsiteTabs';
|
||||
|
||||
export function WebsiteHeader({
|
||||
websiteId,
|
||||
showLinks = true,
|
||||
children,
|
||||
}: {
|
||||
websiteId: string;
|
||||
showLinks?: boolean;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const pathname = usePathname();
|
||||
const { data: website } = useWebsite(websiteId);
|
||||
const { data: website } = useWebsiteQuery(websiteId);
|
||||
const { name, domain } = website || {};
|
||||
|
||||
const links = [
|
||||
{
|
||||
label: formatMessage(labels.overview),
|
||||
icon: <Icons.Overview />,
|
||||
path: '',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.events),
|
||||
icon: <Icons.Lightning />,
|
||||
path: '/events',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.sessions),
|
||||
icon: <Icons.User />,
|
||||
path: '/sessions',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.realtime),
|
||||
icon: <Icons.Clock />,
|
||||
path: '/realtime',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.compare),
|
||||
icon: <Icons.Compare />,
|
||||
path: '/compare',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.reports),
|
||||
icon: <Icons.Reports />,
|
||||
path: '/reports',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>
|
||||
<>
|
||||
<Row alignItems="center" gap="3" marginY="6">
|
||||
<Favicon domain={domain} />
|
||||
<Text>{name}</Text>
|
||||
<Heading>
|
||||
{name}
|
||||
<ActiveUsers websiteId={websiteId} />
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
{showLinks && (
|
||||
<div className={styles.links}>
|
||||
{links.map(({ label, icon, path }) => {
|
||||
const selected = path
|
||||
? pathname.includes(path)
|
||||
: pathname.match(/^\/websites\/[\w-]+$/);
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={label}
|
||||
href={renderTeamUrl(`/websites/${websiteId}${path}`)}
|
||||
shallow={true}
|
||||
>
|
||||
<Button
|
||||
variant="quiet"
|
||||
className={classNames({
|
||||
[styles.selected]: selected,
|
||||
})}
|
||||
>
|
||||
<Icon className={styles.icon}>{icon}</Icon>
|
||||
<Text className={styles.label}>{label}</Text>
|
||||
</Button>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</Heading>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
<WebsiteTabs websiteId={websiteId} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { WebsiteDateFilter } from '@/components/input/WebsiteDateFilter';
|
|||
import { MetricCard } from '@/components/metrics/MetricCard';
|
||||
import { MetricsBar } from '@/components/metrics/MetricsBar';
|
||||
import { formatShortTime, formatLongNumber } from '@/lib/format';
|
||||
import { useWebsiteStats } from '@/components/hooks/queries/useWebsiteStats';
|
||||
import { useWebsiteStatsQuery } from '@/components/hooks/queries/useWebsiteStatsQuery';
|
||||
import { useWebsites, setWebsiteDateCompare } from '@/store/websites';
|
||||
import { WebsiteFilterButton } from './WebsiteFilterButton';
|
||||
import styles from './WebsiteMetricsBar.module.css';
|
||||
|
|
@ -26,8 +26,8 @@ export function WebsiteMetricsBar({
|
|||
const { dateRange } = useDateRange(websiteId);
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const dateCompare = useWebsites(state => state[websiteId]?.dateCompare);
|
||||
const { ref, isSticky } = useSticky({ enabled: sticky });
|
||||
const { data, isLoading, isFetched, error } = useWebsiteStats(
|
||||
const { ref } = useSticky({ enabled: sticky });
|
||||
const { data, isLoading, isFetched, error } = useWebsiteStatsQuery(
|
||||
websiteId,
|
||||
compareMode && dateCompare,
|
||||
);
|
||||
|
|
@ -82,13 +82,7 @@ export function WebsiteMetricsBar({
|
|||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={classNames(styles.container, {
|
||||
[styles.sticky]: sticky,
|
||||
[styles.isSticky]: sticky && isSticky,
|
||||
})}
|
||||
>
|
||||
<div ref={ref} className={classNames(styles.container)}>
|
||||
<div>
|
||||
<MetricsBar isLoading={isLoading} isFetched={isFetched} error={error}>
|
||||
{metrics.map(({ label, value, prev, change, formatValue, reverseColors }) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
import { createContext, ReactNode, useEffect } from 'react';
|
||||
import { useModified, useWebsite } from '@/components/hooks';
|
||||
import { useModified, useWebsiteQuery } from '@/components/hooks';
|
||||
import { Loading } from '@umami/react-zen';
|
||||
|
||||
export const WebsiteContext = createContext(null);
|
||||
|
|
@ -13,7 +13,7 @@ export function WebsiteProvider({
|
|||
children: ReactNode;
|
||||
}) {
|
||||
const { modified } = useModified(`website:${websiteId}`);
|
||||
const { data: website, isFetching, isLoading, refetch } = useWebsite(websiteId);
|
||||
const { data: website, isFetching, isLoading, refetch } = useWebsiteQuery(websiteId);
|
||||
|
||||
useEffect(() => {
|
||||
if (modified) {
|
||||
|
|
|
|||
58
src/app/(main)/websites/[websiteId]/WebsiteTabs.tsx
Normal file
58
src/app/(main)/websites/[websiteId]/WebsiteTabs.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { Tabs, TabList, Tab, Icon, Text, Row } from '@umami/react-zen';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
|
||||
export function WebsiteTabs({ websiteId }: { websiteId: string }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
const links = [
|
||||
{
|
||||
label: formatMessage(labels.overview),
|
||||
icon: <Icons.Overview />,
|
||||
path: '',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.events),
|
||||
icon: <Icons.Lightning />,
|
||||
path: '/events',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.sessions),
|
||||
icon: <Icons.User />,
|
||||
path: '/sessions',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.realtime),
|
||||
icon: <Icons.Clock />,
|
||||
path: '/realtime',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.compare),
|
||||
icon: <Icons.Compare />,
|
||||
path: '/compare',
|
||||
},
|
||||
{
|
||||
label: formatMessage(labels.reports),
|
||||
icon: <Icons.Reports />,
|
||||
path: '/reports',
|
||||
},
|
||||
].map((link, index) => ({ ...link, id: index }));
|
||||
|
||||
return (
|
||||
<Tabs>
|
||||
<TabList items={links}>
|
||||
{({ label, icon, path }) => {
|
||||
return (
|
||||
<Tab key={path} href={renderTeamUrl(`/websites/${websiteId}/${path}`)}>
|
||||
<Row gap="3" alignItems="center">
|
||||
<Icon fillColor="currentColor">{icon}</Icon>
|
||||
<Text>{label}</Text>
|
||||
</Row>
|
||||
</Tab>
|
||||
);
|
||||
}}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
import { GridColumn, GridTable } from '@umami/react-zen';
|
||||
import { useEventDataProperties, useEventDataValues, useMessages } from '@/components/hooks';
|
||||
import { DataColumn, DataTable } from '@umami/react-zen';
|
||||
import {
|
||||
useEventDataPropertiesQuery,
|
||||
useEventDataValuesQuery,
|
||||
useMessages,
|
||||
} from '@/components/hooks';
|
||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||
import { PieChart } from '@/components/charts/PieChart';
|
||||
import { useState } from 'react';
|
||||
|
|
@ -10,8 +14,8 @@ export function EventProperties({ websiteId }: { websiteId: string }) {
|
|||
const [propertyName, setPropertyName] = useState('');
|
||||
const [eventName, setEventName] = useState('');
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { data, isLoading, isFetched, error } = useEventDataProperties(websiteId);
|
||||
const { data: values } = useEventDataValues(websiteId, eventName, propertyName);
|
||||
const { data, isLoading, isFetched, error } = useEventDataPropertiesQuery(websiteId);
|
||||
const { data: values } = useEventDataValuesQuery(websiteId, eventName, propertyName);
|
||||
const chartData =
|
||||
propertyName && values
|
||||
? {
|
||||
|
|
@ -34,23 +38,23 @@ export function EventProperties({ websiteId }: { websiteId: string }) {
|
|||
return (
|
||||
<LoadingPanel isLoading={isLoading} isFetched={isFetched} data={data} error={error}>
|
||||
<div className={styles.container}>
|
||||
<GridTable data={data} cardMode={false} className={styles.table}>
|
||||
<GridColumn name="eventName" label={formatMessage(labels.name)}>
|
||||
<DataTable data={data} cardMode={false} className={styles.table}>
|
||||
<DataColumn name="eventName" label={formatMessage(labels.name)}>
|
||||
{row => (
|
||||
<div className={styles.link} onClick={() => handleRowClick(row)}>
|
||||
{row.eventName}
|
||||
</div>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="propertyName" label={formatMessage(labels.property)}>
|
||||
</DataColumn>
|
||||
<DataColumn name="propertyName" label={formatMessage(labels.property)}>
|
||||
{row => (
|
||||
<div className={styles.link} onClick={() => handleRowClick(row)}>
|
||||
{row.propertyName}
|
||||
</div>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="total" label={formatMessage(labels.count)} alignment="end" />
|
||||
</GridTable>
|
||||
</DataColumn>
|
||||
<DataColumn name="total" label={formatMessage(labels.count)} alignment="end" />
|
||||
</DataTable>
|
||||
{propertyName && (
|
||||
<div className={styles.chart}>
|
||||
<div className={styles.title}>{propertyName}</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useWebsiteEvents } from '@/components/hooks';
|
||||
import { useWebsiteEventsQuery } from '@/components/hooks';
|
||||
import { EventsTable } from './EventsTable';
|
||||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { ReactNode } from 'react';
|
||||
|
|
@ -10,7 +10,7 @@ export function EventsDataTable({
|
|||
teamId?: string;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const queryResult = useWebsiteEvents(websiteId);
|
||||
const queryResult = useWebsiteEventsQuery(websiteId);
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult} allowSearch={true} autoFocus={false}>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useMessages } from '@/components/hooks';
|
||||
import { useWebsiteSessionStats } from '@/components/hooks/queries/useWebsiteSessionStats';
|
||||
import { useWebsiteSessionStatsQuery } from '@/components/hooks/queries/useWebsiteSessionStatsQuery';
|
||||
import { WebsiteDateFilter } from '@/components/input/WebsiteDateFilter';
|
||||
import { MetricCard } from '@/components/metrics/MetricCard';
|
||||
import { MetricsBar } from '@/components/metrics/MetricsBar';
|
||||
|
|
@ -8,7 +8,7 @@ import { Flexbox } from '@umami/react-zen';
|
|||
|
||||
export function EventsMetricsBar({ websiteId }: { websiteId: string }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { data, isLoading, isFetched, error } = useWebsiteSessionStats(websiteId);
|
||||
const { data, isLoading, isFetched, error } = useWebsiteSessionStatsQuery(websiteId);
|
||||
|
||||
return (
|
||||
<Flexbox direction="row" justifyContent="space-between" style={{ minHeight: 120 }}>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { EventsChart } from '@/components/metrics/EventsChart';
|
|||
import { GridRow } from '@/components/layout/Grid';
|
||||
import { MetricsTable } from '@/components/metrics/MetricsTable';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { Item, Tabs } from '@umami/react-zen';
|
||||
import { TabList, Tab, Tabs } from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { EventProperties } from './EventProperties';
|
||||
|
||||
|
|
@ -30,11 +30,13 @@ export function EventsPage({ websiteId }) {
|
|||
<div>
|
||||
<Tabs
|
||||
selectedKey={tab}
|
||||
onSelect={(value: any) => setTab(value)}
|
||||
onSelectionChange={(value: any) => setTab(value)}
|
||||
style={{ marginBottom: 30 }}
|
||||
>
|
||||
<Item key="activity">{formatMessage(labels.activity)}</Item>
|
||||
<Item key="properties">{formatMessage(labels.properties)}</Item>
|
||||
<TabList>
|
||||
<Tab key="activity">{formatMessage(labels.activity)}</Tab>
|
||||
<Tab key="properties">{formatMessage(labels.properties)}</Tab>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
{tab === 'activity' && <EventsDataTable websiteId={websiteId} />}
|
||||
{tab === 'properties' && <EventProperties websiteId={websiteId} />}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { GridTable, GridColumn, Icon } from '@umami/react-zen';
|
||||
import { useMessages, useTeamUrl, useTimezone } from '@/components/hooks';
|
||||
import { DataTable, DataColumn, Icon } from '@umami/react-zen';
|
||||
import { useMessages, useNavigation, useTimezone } from '@/components/hooks';
|
||||
import { Empty } from '@/components/common/Empty';
|
||||
import { Avatar } from '@/components/common/Avatar';
|
||||
import Link from 'next/link';
|
||||
|
|
@ -8,23 +8,23 @@ import { Icons } from '@/components/icons';
|
|||
export function EventsTable({ data = [] }) {
|
||||
const { formatTimezoneDate } = useTimezone();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
if (data.length === 0) {
|
||||
return <Empty />;
|
||||
}
|
||||
|
||||
return (
|
||||
<GridTable data={data}>
|
||||
<GridColumn name="session" label={formatMessage(labels.session)} width={'100px'}>
|
||||
{row => (
|
||||
<DataTable data={data}>
|
||||
<DataColumn id="session" label={formatMessage(labels.session)}>
|
||||
{(row: any) => (
|
||||
<Link href={renderTeamUrl(`/websites/${row.websiteId}/sessions/${row.sessionId}`)}>
|
||||
<Avatar seed={row.sessionId} size={64} />
|
||||
</Link>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="event" label={formatMessage(labels.event)}>
|
||||
{row => {
|
||||
</DataColumn>
|
||||
<DataColumn id="event" label={formatMessage(labels.event)}>
|
||||
{(row: any) => {
|
||||
return (
|
||||
<>
|
||||
<Icon>{row.eventName ? <Icons.Bolt /> : <Icons.Eye />}</Icon>
|
||||
|
|
@ -33,10 +33,10 @@ export function EventsTable({ data = [] }) {
|
|||
</>
|
||||
);
|
||||
}}
|
||||
</GridColumn>
|
||||
<GridColumn name="created" label={formatMessage(labels.created)} width={'300px'}>
|
||||
{row => formatTimezoneDate(row.createdAt, 'PPPpp')}
|
||||
</GridColumn>
|
||||
</GridTable>
|
||||
</DataColumn>
|
||||
<DataColumn id="created" label={formatMessage(labels.created)}>
|
||||
{(row: any) => formatTimezoneDate(row.createdAt, 'PPPpp')}
|
||||
</DataColumn>
|
||||
</DataTable>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Key, useContext, useState } from 'react';
|
||||
import { ButtonGroup, Button, Flexbox } from '@umami/react-zen';
|
||||
import thenby from 'thenby';
|
||||
import { percentFilter } from '@/lib/filters';
|
||||
import { ListTable } from '@/components/metrics/ListTable';
|
||||
|
|
@ -7,6 +6,7 @@ import { FILTER_PAGES, FILTER_REFERRERS } from '@/lib/constants';
|
|||
import { useMessages } from '@/components/hooks';
|
||||
import { RealtimeData } from '@/lib/types';
|
||||
import { WebsiteContext } from '../WebsiteProvider';
|
||||
import { FilterButtons } from '@/components/common/FilterButtons';
|
||||
|
||||
export function RealtimeUrls({ data }: { data: RealtimeData }) {
|
||||
const website = useContext(WebsiteContext);
|
||||
|
|
@ -17,10 +17,12 @@ export function RealtimeUrls({ data }: { data: RealtimeData }) {
|
|||
|
||||
const buttons = [
|
||||
{
|
||||
id: 1,
|
||||
label: formatMessage(labels.referrers),
|
||||
key: FILTER_REFERRERS,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: formatMessage(labels.pages),
|
||||
key: FILTER_PAGES,
|
||||
},
|
||||
|
|
@ -61,11 +63,7 @@ export function RealtimeUrls({ data }: { data: RealtimeData }) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Flexbox justifyContent="center">
|
||||
<ButtonGroup items={buttons} selectedKey={filter} onSelect={setFilter}>
|
||||
{({ key, label }) => <Button key={key}>{label}</Button>}
|
||||
</ButtonGroup>
|
||||
</Flexbox>
|
||||
<FilterButtons items={buttons} onSelect={setFilter} />
|
||||
{filter === FILTER_REFERRERS && (
|
||||
<ListTable
|
||||
title={formatMessage(labels.referrers)}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Grid, GridRow } from '@/components/layout/Grid';
|
|||
import { Page } from '@/components/layout/Page';
|
||||
import { RealtimeChart } from '@/components/metrics/RealtimeChart';
|
||||
import { WorldMap } from '@/components/metrics/WorldMap';
|
||||
import { useRealtime } from '@/components/hooks';
|
||||
import { useRealtimeQuery } from '@/components/hooks';
|
||||
import { RealtimeLog } from './RealtimeLog';
|
||||
import { RealtimeHeader } from './RealtimeHeader';
|
||||
import { RealtimeUrls } from './RealtimeUrls';
|
||||
|
|
@ -13,7 +13,7 @@ import { WebsiteHeader } from '../WebsiteHeader';
|
|||
import { percentFilter } from '@/lib/filters';
|
||||
|
||||
export function WebsiteRealtimePage({ websiteId }) {
|
||||
const { data, isLoading, error } = useRealtime(websiteId);
|
||||
const { data, isLoading, error } = useRealtimeQuery(websiteId);
|
||||
|
||||
if (isLoading || error) {
|
||||
return <Page isLoading={isLoading} error={error} />;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
'use client';
|
||||
import Link from 'next/link';
|
||||
import { Button, Flexbox, Icon, Icons, Text } from '@umami/react-zen';
|
||||
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||
import { useMessages, useNavigation } from '@/components/hooks';
|
||||
import { WebsiteHeader } from '../WebsiteHeader';
|
||||
import { ReportsDataTable } from '@/app/(main)/reports/ReportsDataTable';
|
||||
|
||||
export function WebsiteReportsPage({ websiteId }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { renderTeamUrl } = useTeamUrl();
|
||||
const { renderTeamUrl } = useNavigation();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { GridColumn, GridTable } from '@umami/react-zen';
|
||||
import { useSessionDataProperties, useSessionDataValues, useMessages } from '@/components/hooks';
|
||||
import { DataColumn, DataTable } from '@umami/react-zen';
|
||||
import {
|
||||
useSessionDataPropertiesQuery,
|
||||
useSessionDataValuesQuery,
|
||||
useMessages,
|
||||
} from '@/components/hooks';
|
||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||
import { PieChart } from '@/components/charts/PieChart';
|
||||
import { useState } from 'react';
|
||||
|
|
@ -9,8 +13,8 @@ import styles from './SessionProperties.module.css';
|
|||
export function SessionProperties({ websiteId }: { websiteId: string }) {
|
||||
const [propertyName, setPropertyName] = useState('');
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { data, isLoading, isFetched, error } = useSessionDataProperties(websiteId);
|
||||
const { data: values } = useSessionDataValues(websiteId, propertyName);
|
||||
const { data, isLoading, isFetched, error } = useSessionDataPropertiesQuery(websiteId);
|
||||
const { data: values } = useSessionDataValuesQuery(websiteId, propertyName);
|
||||
const chartData =
|
||||
propertyName && values
|
||||
? {
|
||||
|
|
@ -28,16 +32,16 @@ export function SessionProperties({ websiteId }: { websiteId: string }) {
|
|||
return (
|
||||
<LoadingPanel isLoading={isLoading} isFetched={isFetched} data={data} error={error}>
|
||||
<div className={styles.container}>
|
||||
<GridTable data={data} cardMode={false} className={styles.table}>
|
||||
<GridColumn name="propertyName" label={formatMessage(labels.property)}>
|
||||
{row => (
|
||||
<DataTable data={data} className={styles.table}>
|
||||
<DataColumn id="propertyName" label={formatMessage(labels.property)}>
|
||||
{(row: any) => (
|
||||
<div className={styles.link} onClick={() => setPropertyName(row.propertyName)}>
|
||||
{row.propertyName}
|
||||
</div>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="total" label={formatMessage(labels.count)} alignment="end" />
|
||||
</GridTable>
|
||||
</DataColumn>
|
||||
<DataColumn id="total" label={formatMessage(labels.count)} align="end" />
|
||||
</DataTable>
|
||||
{propertyName && (
|
||||
<div className={styles.chart}>
|
||||
<div className={styles.title}>{propertyName}</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useWebsiteSessions } from '@/components/hooks';
|
||||
import { useWebsiteSessionsQuery } from '@/components/hooks';
|
||||
import { SessionsTable } from './SessionsTable';
|
||||
import { DataGrid } from '@/components/common/DataGrid';
|
||||
import { ReactNode } from 'react';
|
||||
|
|
@ -11,7 +11,7 @@ export function SessionsDataTable({
|
|||
teamId?: string;
|
||||
children?: ReactNode;
|
||||
}) {
|
||||
const queryResult = useWebsiteSessions(websiteId);
|
||||
const queryResult = useWebsiteSessionsQuery(websiteId);
|
||||
|
||||
return (
|
||||
<DataGrid queryResult={queryResult} allowSearch={false} renderEmpty={() => children}>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useMessages } from '@/components/hooks';
|
||||
import { useWebsiteSessionStats } from '@/components/hooks/queries/useWebsiteSessionStats';
|
||||
import { useWebsiteSessionStatsQuery } from '@/components/hooks/queries/useWebsiteSessionStatsQuery';
|
||||
import { WebsiteDateFilter } from '@/components/input/WebsiteDateFilter';
|
||||
import { MetricCard } from '@/components/metrics/MetricCard';
|
||||
import { MetricsBar } from '@/components/metrics/MetricsBar';
|
||||
|
|
@ -8,7 +8,7 @@ import { Flexbox } from '@umami/react-zen';
|
|||
|
||||
export function SessionsMetricsBar({ websiteId }: { websiteId: string }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { data, isLoading, isFetched, error } = useWebsiteSessionStats(websiteId);
|
||||
const { data, isLoading, isFetched, error } = useWebsiteSessionStatsQuery(websiteId);
|
||||
|
||||
return (
|
||||
<Flexbox direction="row" justifyContent="space-between" style={{ minHeight: 120 }}>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { SessionsMetricsBar } from './SessionsMetricsBar';
|
|||
import { SessionProperties } from './SessionProperties';
|
||||
import { WorldMap } from '@/components/metrics/WorldMap';
|
||||
import { GridRow } from '@/components/layout/Grid';
|
||||
import { Item, Tabs } from '@umami/react-zen';
|
||||
import { TabList, Tab, Tabs } from '@umami/react-zen';
|
||||
import { useState } from 'react';
|
||||
import { useMessages } from '@/components/hooks';
|
||||
import { SessionsWeekly } from './SessionsWeekly';
|
||||
|
|
@ -22,9 +22,15 @@ export function SessionsPage({ websiteId }) {
|
|||
<WorldMap websiteId={websiteId} />
|
||||
<SessionsWeekly websiteId={websiteId} />
|
||||
</GridRow>
|
||||
<Tabs selectedKey={tab} onSelect={(value: any) => setTab(value)} style={{ marginBottom: 30 }}>
|
||||
<Item key="activity">{formatMessage(labels.activity)}</Item>
|
||||
<Item key="properties">{formatMessage(labels.properties)}</Item>
|
||||
<Tabs
|
||||
selectedKey={tab}
|
||||
onSelectionChange={(value: any) => setTab(value)}
|
||||
style={{ marginBottom: 30 }}
|
||||
>
|
||||
<TabList>
|
||||
<Tab key="activity">{formatMessage(labels.activity)}</Tab>
|
||||
<Tab key="properties">{formatMessage(labels.properties)}</Tab>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
{tab === 'activity' && <SessionsDataTable websiteId={websiteId} />}
|
||||
{tab === 'properties' && <SessionProperties websiteId={websiteId} />}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import Link from 'next/link';
|
||||
import { GridColumn, GridTable } from '@umami/react-zen';
|
||||
import { DataColumn, DataTable } from '@umami/react-zen';
|
||||
import { useFormat, useMessages, useTimezone } from '@/components/hooks';
|
||||
import { Avatar } from '@/components/common/Avatar';
|
||||
import styles from './SessionsTable.module.css';
|
||||
|
|
@ -11,48 +11,48 @@ export function SessionsTable({ data = [] }: { data: any[]; showDomain?: boolean
|
|||
const { formatValue } = useFormat();
|
||||
|
||||
return (
|
||||
<GridTable data={data}>
|
||||
<GridColumn name="id" label={formatMessage(labels.session)} width="100px">
|
||||
{row => (
|
||||
<DataTable data={data}>
|
||||
<DataColumn id="id" label={formatMessage(labels.session)}>
|
||||
{(row: any) => (
|
||||
<Link href={`sessions/${row.id}`} className={styles.link}>
|
||||
<Avatar key={row.id} seed={row.id} size={64} />
|
||||
</Link>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="visits" label={formatMessage(labels.visits)} width="100px" />
|
||||
<GridColumn name="views" label={formatMessage(labels.views)} width="100px" />
|
||||
<GridColumn name="country" label={formatMessage(labels.country)}>
|
||||
{row => (
|
||||
</DataColumn>
|
||||
<DataColumn id="visits" label={formatMessage(labels.visits)} />
|
||||
<DataColumn id="views" label={formatMessage(labels.views)} />
|
||||
<DataColumn id="country" label={formatMessage(labels.country)}>
|
||||
{(row: any) => (
|
||||
<TypeIcon type="country" value={row.country}>
|
||||
{formatValue(row.country, 'country')}
|
||||
</TypeIcon>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="city" label={formatMessage(labels.city)} />
|
||||
<GridColumn name="browser" label={formatMessage(labels.browser)}>
|
||||
{row => (
|
||||
</DataColumn>
|
||||
<DataColumn id="city" label={formatMessage(labels.city)} />
|
||||
<DataColumn id="browser" label={formatMessage(labels.browser)}>
|
||||
{(row: any) => (
|
||||
<TypeIcon type="browser" value={row.browser}>
|
||||
{formatValue(row.browser, 'browser')}
|
||||
</TypeIcon>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="os" label={formatMessage(labels.os)}>
|
||||
{row => (
|
||||
</DataColumn>
|
||||
<DataColumn id="os" label={formatMessage(labels.os)}>
|
||||
{(row: any) => (
|
||||
<TypeIcon type="os" value={row.os}>
|
||||
{formatValue(row.os, 'os')}
|
||||
</TypeIcon>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="device" label={formatMessage(labels.device)}>
|
||||
{row => (
|
||||
</DataColumn>
|
||||
<DataColumn id="device" label={formatMessage(labels.device)}>
|
||||
{(row: any) => (
|
||||
<TypeIcon type="device" value={row.device}>
|
||||
{formatValue(row.device, 'device')}
|
||||
</TypeIcon>
|
||||
)}
|
||||
</GridColumn>
|
||||
<GridColumn name="lastAt" label={formatMessage(labels.lastSeen)}>
|
||||
{row => formatTimezoneDate(row.createdAt, 'PPPpp')}
|
||||
</GridColumn>
|
||||
</GridTable>
|
||||
</DataColumn>
|
||||
<DataColumn id="lastAt" label={formatMessage(labels.lastSeen)}>
|
||||
{(row: any) => formatTimezoneDate(row.createdAt, 'PPPpp')}
|
||||
</DataColumn>
|
||||
</DataTable>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { format, startOfDay, addHours } from 'date-fns';
|
||||
import { useLocale, useMessages, useWebsiteSessionsWeekly } from '@/components/hooks';
|
||||
import { useLocale, useMessages, useWebsiteSessionsWeeklyQuery } from '@/components/hooks';
|
||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||
import { getDayOfWeekAsDate } from '@/lib/date';
|
||||
import styles from './SessionsWeekly.module.css';
|
||||
import classNames from 'classnames';
|
||||
import { TooltipPopup } from '@umami/react-zen';
|
||||
import { Tooltip, TooltipTrigger } from '@umami/react-zen';
|
||||
|
||||
export function SessionsWeekly({ websiteId }: { websiteId: string }) {
|
||||
const { data, ...props } = useWebsiteSessionsWeekly(websiteId);
|
||||
const { data, ...props } = useWebsiteSessionsWeeklyQuery(websiteId);
|
||||
const { dateLocale } = useLocale();
|
||||
const { labels, formatMessage } = useMessages();
|
||||
const { weekStartsOn } = dateLocale.options;
|
||||
|
|
@ -67,15 +67,13 @@ export function SessionsWeekly({ websiteId }: { websiteId: string }) {
|
|||
return (
|
||||
<div key={j} className={classNames(styles.cell)}>
|
||||
{hour > 0 && (
|
||||
<TooltipPopup
|
||||
label={`${formatMessage(labels.visitors)}: ${hour}`}
|
||||
position="right"
|
||||
>
|
||||
<TooltipTrigger>
|
||||
<div
|
||||
className={styles.block}
|
||||
style={{ opacity: pct, transform: `scale(${pct})` }}
|
||||
/>
|
||||
</TooltipPopup>
|
||||
<Tooltip>{`${formatMessage(labels.visitors)}: ${hour}`}</Tooltip>
|
||||
</TooltipTrigger>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { isSameDay } from 'date-fns';
|
||||
import { Loading, Icon, StatusLight } from '@umami/react-zen';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { useSessionActivity, useTimezone } from '@/components/hooks';
|
||||
import { useSessionActivityQuery, useTimezone } from '@/components/hooks';
|
||||
import styles from './SessionActivity.module.css';
|
||||
import { Fragment } from 'react';
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ export function SessionActivity({
|
|||
endDate: Date;
|
||||
}) {
|
||||
const { formatTimezoneDate } = useTimezone();
|
||||
const { data, isLoading } = useSessionActivity(websiteId, sessionId, startDate, endDate);
|
||||
const { data, isLoading } = useSessionActivityQuery(websiteId, sessionId, startDate, endDate);
|
||||
|
||||
if (isLoading) {
|
||||
return <Loading position="page" />;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { TextOverflow } from '@umami/react-zen';
|
||||
import { useMessages, useSessionData } from '@/components/hooks';
|
||||
import { useMessages, useSessionDataQuery } from '@/components/hooks';
|
||||
import { Empty } from '@/components/common/Empty';
|
||||
import { DATA_TYPES } from '@/lib/constants';
|
||||
import styles from './SessionData.module.css';
|
||||
|
|
@ -7,7 +7,7 @@ import { LoadingPanel } from '@/components/common/LoadingPanel';
|
|||
|
||||
export function SessionData({ websiteId, sessionId }: { websiteId: string; sessionId: string }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { data, ...query } = useSessionData(websiteId, sessionId);
|
||||
const { data, ...query } = useSessionDataQuery(websiteId, sessionId);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
import { Avatar } from '@/components/common/Avatar';
|
||||
import { LoadingPanel } from '@/components/common/LoadingPanel';
|
||||
import { useWebsiteSession } from '@/components/hooks';
|
||||
import { useWebsiteSessionQuery } from '@/components/hooks';
|
||||
import { WebsiteHeader } from '../../WebsiteHeader';
|
||||
import { SessionActivity } from './SessionActivity';
|
||||
import { SessionData } from './SessionData';
|
||||
|
|
@ -16,7 +16,7 @@ export function SessionDetailsPage({
|
|||
websiteId: string;
|
||||
sessionId: string;
|
||||
}) {
|
||||
const { data, ...query } = useWebsiteSession(websiteId, sessionId);
|
||||
const { data, ...query } = useWebsiteSessionQuery(websiteId, sessionId);
|
||||
|
||||
return (
|
||||
<LoadingPanel {...query} loadingIcon="spinner" data={data}>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
import { WebsiteDetailsPage } from '../../(main)/websites/[websiteId]/WebsiteDetailsPage';
|
||||
import { useShareToken } from '@/components/hooks';
|
||||
import { useShareTokenQuery } from '@/components/hooks';
|
||||
import { Page } from '@/components/layout/Page';
|
||||
import { Header } from './Header';
|
||||
import { Footer } from './Footer';
|
||||
|
|
@ -8,7 +8,7 @@ import styles from './SharePage.module.css';
|
|||
import { WebsiteProvider } from '@/app/(main)/websites/[websiteId]/WebsiteProvider';
|
||||
|
||||
export function SharePage({ shareId }) {
|
||||
const { shareToken, isLoading } = useShareToken(shareId);
|
||||
const { shareToken, isLoading } = useShareTokenQuery(shareId);
|
||||
|
||||
if (isLoading || !shareToken) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,32 +1,32 @@
|
|||
export * from './queries/useConfig';
|
||||
export * from './queries/useEventDataEvents';
|
||||
export * from './queries/useEventDataProperties';
|
||||
export * from './queries/useEventDataValues';
|
||||
export * from './queries/useLogin';
|
||||
export * from './queries/useRealtime';
|
||||
export * from './queries/useReport';
|
||||
export * from './queries/useReports';
|
||||
export * from './queries/useSessionActivity';
|
||||
export * from './queries/useSessionData';
|
||||
export * from './queries/useSessionDataProperties';
|
||||
export * from './queries/useSessionDataValues';
|
||||
export * from './queries/useWebsiteSession';
|
||||
export * from './queries/useWebsiteSessions';
|
||||
export * from './queries/useWebsiteSessionsWeekly';
|
||||
export * from './queries/useShareToken';
|
||||
export * from './queries/useTeam';
|
||||
export * from './queries/useTeams';
|
||||
export * from './queries/useTeamWebsites';
|
||||
export * from './queries/useTeamMembers';
|
||||
export * from './queries/useUser';
|
||||
export * from './queries/useUsers';
|
||||
export * from './queries/useWebsite';
|
||||
export * from './queries/useEventDataEventsQuery';
|
||||
export * from './queries/useEventDataPropertiesQuery';
|
||||
export * from './queries/useEventDataValuesQuery';
|
||||
export * from './queries/useLoginQuery';
|
||||
export * from './queries/useRealtimeQuery';
|
||||
export * from './queries/useReportQuery';
|
||||
export * from './queries/useReportsQuery';
|
||||
export * from './queries/useSessionActivityQuery';
|
||||
export * from './queries/useSessionDataQuery';
|
||||
export * from './queries/useSessionDataPropertiesQuery';
|
||||
export * from './queries/useSessionDataValuesQuery';
|
||||
export * from './queries/useWebsiteSessionQuery';
|
||||
export * from './queries/useWebsiteSessionsQuery';
|
||||
export * from './queries/useWebsiteSessionsWeeklyQuery';
|
||||
export * from './queries/useShareTokenQuery';
|
||||
export * from './queries/useTeamQuery';
|
||||
export * from './queries/useTeamsQuery';
|
||||
export * from './queries/useTeamWebsitesQuery';
|
||||
export * from './queries/useTeamMembersQuery';
|
||||
export * from './queries/useUserQuery';
|
||||
export * from './queries/useUsersQuery';
|
||||
export * from './queries/useWebsiteQuery';
|
||||
export * from './queries/useWebsites';
|
||||
export * from './queries/useWebsiteEvents';
|
||||
export * from './queries/useWebsiteEventsSeries';
|
||||
export * from './queries/useWebsiteMetrics';
|
||||
export * from './queries/useWebsiteValues';
|
||||
export * from './queries/useWebsiteEventsQuery';
|
||||
export * from './queries/useWebsiteEventsSeriesQuery';
|
||||
export * from './queries/useWebsiteMetricsQuery';
|
||||
export * from './queries/useWebsiteValuesQuery';
|
||||
export * from './useApi';
|
||||
export * from './useConfig';
|
||||
export * from './useCountryNames';
|
||||
export * from './useDateRange';
|
||||
export * from './useDocumentClick';
|
||||
|
|
@ -39,10 +39,9 @@ export * from './useLanguageNames';
|
|||
export * from './useLocale';
|
||||
export * from './useMessages';
|
||||
export * from './useModified';
|
||||
export * from './useNavigation';
|
||||
export * from './usePagedQuery';
|
||||
export * from './useRegionNames';
|
||||
export * from './useSticky';
|
||||
export * from './useTeamUrl';
|
||||
export * from './useNavigation';
|
||||
export * from './useTheme';
|
||||
export * from './useTimezone';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { UseQueryOptions } from '@tanstack/react-query';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useEventDataEvents(
|
||||
export function useEventDataEventsQuery(
|
||||
websiteId: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
|
|
@ -2,7 +2,7 @@ import { UseQueryOptions } from '@tanstack/react-query';
|
|||
import { useApi } from '../useApi';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useEventDataProperties(
|
||||
export function useEventDataPropertiesQuery(
|
||||
websiteId: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
|
|
@ -2,7 +2,7 @@ import { UseQueryOptions } from '@tanstack/react-query';
|
|||
import { useApi } from '../useApi';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useEventDataValues(
|
||||
export function useEventDataValuesQuery(
|
||||
websiteId: string,
|
||||
eventName: string,
|
||||
propertyName: string,
|
||||
|
|
@ -4,7 +4,7 @@ import { useApi } from '../useApi';
|
|||
|
||||
const selector = (state: { user: any }) => state.user;
|
||||
|
||||
export function useLogin(): {
|
||||
export function useLoginQuery(): {
|
||||
user: any;
|
||||
setUser: (data: any) => void;
|
||||
} & UseQueryResult {
|
||||
|
|
@ -3,7 +3,7 @@ import { REALTIME_INTERVAL } from '@/lib/constants';
|
|||
import { RealtimeData } from '@/lib/types';
|
||||
import { useApi } from '../useApi';
|
||||
|
||||
export function useRealtime(websiteId: string) {
|
||||
export function useRealtimeQuery(websiteId: string) {
|
||||
const { get, useQuery } = useApi();
|
||||
const { timezone } = useTimezone();
|
||||
const { data, isLoading, error } = useQuery<RealtimeData>({
|
||||
|
|
@ -5,7 +5,7 @@ import { useTimezone } from '../useTimezone';
|
|||
import { useMessages } from '../useMessages';
|
||||
import { parseDateRange } from '@/lib/date';
|
||||
|
||||
export function useReport(
|
||||
export function useReportQuery(
|
||||
reportId: string,
|
||||
defaultParameters?: { type: string; parameters: { [key: string]: any } },
|
||||
) {
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useReports({ websiteId, teamId }: { websiteId?: string; teamId?: string }) {
|
||||
export function useReportsQuery({ websiteId, teamId }: { websiteId?: string; teamId?: string }) {
|
||||
const { modified } = useModified(`reports`);
|
||||
const { get, del, useMutation } = useApi();
|
||||
const queryResult = usePagedQuery({
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useRevenueValues(websiteId: string, startDate: Date, endDate: Date) {
|
||||
export function useRevenueValuesQuery(websiteId: string, startDate: Date, endDate: Date) {
|
||||
const { get, useQuery } = useApi();
|
||||
|
||||
return useQuery({
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useSessionActivity(
|
||||
export function useSessionActivityQuery(
|
||||
websiteId: string,
|
||||
sessionId: string,
|
||||
startDate: Date,
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { UseQueryOptions } from '@tanstack/react-query';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useSessionDataProperties(
|
||||
export function useSessionDataPropertiesQuery(
|
||||
websiteId: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useSessionData(websiteId: string, sessionId: string) {
|
||||
export function useSessionDataQuery(websiteId: string, sessionId: string) {
|
||||
const { get, useQuery } = useApi();
|
||||
|
||||
return useQuery({
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { UseQueryOptions } from '@tanstack/react-query';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useSessionDataValues(
|
||||
export function useSessionDataValuesQuery(
|
||||
websiteId: string,
|
||||
propertyName: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
|
|
@ -3,7 +3,7 @@ import { useApi } from '../useApi';
|
|||
|
||||
const selector = (state: { shareToken: string }) => state.shareToken;
|
||||
|
||||
export function useShareToken(shareId: string): {
|
||||
export function useShareTokenQuery(shareId: string): {
|
||||
shareToken: any;
|
||||
isLoading?: boolean;
|
||||
error?: Error;
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useTeamMembers(teamId: string) {
|
||||
export function useTeamMembersQuery(teamId: string) {
|
||||
const { get } = useApi();
|
||||
const { modified } = useModified(`teams:members`);
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useTeam(teamId: string) {
|
||||
export function useTeamQuery(teamId: string) {
|
||||
const { get, useQuery } = useApi();
|
||||
return useQuery({
|
||||
queryKey: ['teams', teamId],
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useTeamWebsites(teamId: string) {
|
||||
export function useTeamWebsitesQuery(teamId: string) {
|
||||
const { get } = useApi();
|
||||
const { modified } = useModified(`websites`);
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useTeams(userId: string) {
|
||||
export function useTeamsQuery(userId: string) {
|
||||
const { get } = useApi();
|
||||
const { modified } = useModified(`teams`);
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useUser(userId: string, options?: { [key: string]: any }) {
|
||||
export function useUserQuery(userId: string, options?: { [key: string]: any }) {
|
||||
const { get, useQuery } = useApi();
|
||||
return useQuery({
|
||||
queryKey: ['users', userId],
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useUsers() {
|
||||
export function useUsersQuery() {
|
||||
const { get } = useApi();
|
||||
const { modified } = useModified(`users`);
|
||||
|
||||
|
|
@ -3,7 +3,7 @@ import { UseQueryOptions } from '@tanstack/react-query';
|
|||
import { useFilterParams } from '../useFilterParams';
|
||||
import { usePagedQuery } from '../usePagedQuery';
|
||||
|
||||
export function useWebsiteEvents(
|
||||
export function useWebsiteEventsQuery(
|
||||
websiteId: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { UseQueryOptions } from '@tanstack/react-query';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useWebsiteEventsSeries(
|
||||
export function useWebsiteEventsSeriesQuery(
|
||||
websiteId: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
) {
|
||||
|
|
@ -3,7 +3,7 @@ import { useApi } from '../useApi';
|
|||
import { useFilterParams } from '../useFilterParams';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
|
||||
export function useWebsiteMetrics(
|
||||
export function useWebsiteMetricsQuery(
|
||||
websiteId: string,
|
||||
queryParams: { type: string; limit?: number; search?: string; startAt?: number; endAt?: number },
|
||||
options?: Omit<UseQueryOptions & { onDataLoad?: (data: any) => void }, 'queryKey' | 'queryFn'>,
|
||||
|
|
@ -2,7 +2,7 @@ import { UseQueryOptions } from '@tanstack/react-query';
|
|||
import { useApi } from '../useApi';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useWebsitePageviews(
|
||||
export function useWebsitePageviewsQuery(
|
||||
websiteId: string,
|
||||
compare?: string,
|
||||
options?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>,
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useWebsite(websiteId: string, options?: { [key: string]: any }) {
|
||||
export function useWebsiteQuery(websiteId: string, options?: { [key: string]: any }) {
|
||||
const { get, useQuery } = useApi();
|
||||
|
||||
return useQuery({
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
|
||||
export function useWebsiteSession(websiteId: string, sessionId: string) {
|
||||
export function useWebsiteSessionQuery(websiteId: string, sessionId: string) {
|
||||
const { get, useQuery } = useApi();
|
||||
|
||||
return useQuery({
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
import { useApi } from '../useApi';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useWebsiteSessionStats(websiteId: string, options?: { [key: string]: string }) {
|
||||
export function useWebsiteSessionStatsQuery(
|
||||
websiteId: string,
|
||||
options?: { [key: string]: string },
|
||||
) {
|
||||
const { get, useQuery } = useApi();
|
||||
const params = useFilterParams(websiteId);
|
||||
|
||||
|
|
@ -3,7 +3,10 @@ import { usePagedQuery } from '../usePagedQuery';
|
|||
import { useModified } from '../useModified';
|
||||
import { useFilterParams } from '@/components/hooks/useFilterParams';
|
||||
|
||||
export function useWebsiteSessions(websiteId: string, params?: { [key: string]: string | number }) {
|
||||
export function useWebsiteSessionsQuery(
|
||||
websiteId: string,
|
||||
params?: { [key: string]: string | number },
|
||||
) {
|
||||
const { get } = useApi();
|
||||
const { modified } = useModified(`sessions`);
|
||||
const filters = useFilterParams(websiteId);
|
||||
|
|
@ -2,7 +2,7 @@ import { useApi } from '../useApi';
|
|||
import { useModified } from '../useModified';
|
||||
import { useFilterParams } from '@/components/hooks/useFilterParams';
|
||||
|
||||
export function useWebsiteSessionsWeekly(
|
||||
export function useWebsiteSessionsWeeklyQuery(
|
||||
websiteId: string,
|
||||
params?: { [key: string]: string | number },
|
||||
) {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { useApi } from '../useApi';
|
||||
import { useFilterParams } from '../useFilterParams';
|
||||
|
||||
export function useWebsiteStats(
|
||||
export function useWebsiteStatsQuery(
|
||||
websiteId: string,
|
||||
compare?: string,
|
||||
options?: { [key: string]: string },
|
||||
|
|
@ -3,7 +3,7 @@ import { useCountryNames } from '@/components/hooks/useCountryNames';
|
|||
import { useRegionNames } from '@/components/hooks/useRegionNames';
|
||||
import { useLocale } from '../useLocale';
|
||||
|
||||
export function useWebsiteValues({
|
||||
export function useWebsiteValuesQuery({
|
||||
websiteId,
|
||||
type,
|
||||
startDate,
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useApi } from '../useApi';
|
||||
import { usePagedQuery } from '../usePagedQuery';
|
||||
import { useLogin } from './useLogin';
|
||||
import { useLoginQuery } from './useLoginQuery';
|
||||
import { useModified } from '../useModified';
|
||||
|
||||
export function useWebsites(
|
||||
|
|
@ -8,7 +8,7 @@ export function useWebsites(
|
|||
params?: { [key: string]: string | number },
|
||||
) {
|
||||
const { get } = useApi();
|
||||
const { user } = useLogin();
|
||||
const { user } = useLoginQuery();
|
||||
const { modified } = useModified(`websites`);
|
||||
|
||||
return usePagedQuery({
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue