Renamed query hooks. Fixed conversion bugs.

This commit is contained in:
Mike Cao 2025-03-22 03:48:18 -07:00
parent adca3c36d0
commit 7886c3f393
110 changed files with 423 additions and 489 deletions

View file

@ -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();

View file

@ -17,6 +17,7 @@ export function MenuBar(props: RowProps) {
paddingY="3"
paddingX="3"
paddingRight="5"
backgroundColor="1"
>
<Row>
<Button onPress={() => setCollapsed(!isCollapsed)} variant="quiet">

View file

@ -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 = [

View file

@ -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;

View file

@ -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;

View file

@ -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}>

View file

@ -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 (

View file

@ -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 (
<>

View file

@ -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}>

View file

@ -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) => {

View file

@ -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,

View file

@ -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;

View file

@ -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({

View file

@ -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;

View file

@ -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 = [
{

View file

@ -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>
);
}

View file

@ -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 =

View file

@ -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>

View file

@ -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>
);
}

View file

@ -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 = [

View file

@ -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 () => {

View file

@ -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}>

View file

@ -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 (

View file

@ -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>

View file

@ -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}>

View file

@ -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();

View file

@ -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) {

View file

@ -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)}>

View file

@ -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 (

View file

@ -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;

View file

@ -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 &&

View file

@ -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 }) =>

View file

@ -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) {

View file

@ -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 = [
{

View file

@ -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}>

View file

@ -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 =

View file

@ -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),

View file

@ -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 =

View file

@ -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}>

View file

@ -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(

View file

@ -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 (

View file

@ -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 (
<>

View file

@ -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(() => {

View file

@ -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

View file

@ -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;
}
}

View file

@ -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} />
</>
);
}

View file

@ -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 }) => {

View file

@ -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) {

View 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>
);
}

View file

@ -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>

View file

@ -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}>

View file

@ -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 }}>

View file

@ -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} />}

View file

@ -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>
);
}

View file

@ -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)}

View file

@ -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} />;

View file

@ -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 (
<>

View file

@ -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>

View file

@ -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}>

View file

@ -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 }}>

View file

@ -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} />}

View file

@ -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>
);
}

View file

@ -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>
);

View file

@ -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" />;

View file

@ -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 (
<>

View file

@ -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}>

View file

@ -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;

View file

@ -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';

View file

@ -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'>,
) {

View file

@ -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'>,
) {

View file

@ -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,

View file

@ -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 {

View file

@ -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>({

View file

@ -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 } },
) {

View file

@ -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({

View file

@ -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({

View file

@ -1,6 +1,6 @@
import { useApi } from '../useApi';
export function useSessionActivity(
export function useSessionActivityQuery(
websiteId: string,
sessionId: string,
startDate: Date,

View file

@ -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'>,
) {

View file

@ -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({

View file

@ -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'>,

View file

@ -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;

View file

@ -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`);

View file

@ -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],

View file

@ -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`);

View file

@ -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`);

View file

@ -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],

View file

@ -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`);

View file

@ -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'>,
) {

View file

@ -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'>,
) {

View file

@ -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'>,

View file

@ -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'>,

View file

@ -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({

View file

@ -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({

View file

@ -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);

View file

@ -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);

View file

@ -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 },
) {

View file

@ -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 },

View file

@ -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,

View file

@ -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