diff --git a/src/app/(main)/App.tsx b/src/app/(main)/App.tsx
index 56d50a6a..0ea6799f 100644
--- a/src/app/(main)/App.tsx
+++ b/src/app/(main)/App.tsx
@@ -14,7 +14,7 @@ export function App({ children }) {
const pathname = usePathname();
if (isLoading) {
- return ;
+ return ;
}
if (error) {
diff --git a/src/app/(main)/console/[[...websiteId]]/page.tsx b/src/app/(main)/console/[[...websiteId]]/page.tsx
index 7c3433c5..efb793a4 100644
--- a/src/app/(main)/console/[[...websiteId]]/page.tsx
+++ b/src/app/(main)/console/[[...websiteId]]/page.tsx
@@ -5,7 +5,7 @@ async function getEnabled() {
return !!process.env.ENABLE_TEST_CONSOLE;
}
-export default async function ({ params }: { params: { websiteId: string } }) {
+export default async function ({ params }: { params: Promise<{ websiteId: string }> }) {
const { websiteId } = await params;
const enabled = await getEnabled();
diff --git a/src/app/(main)/reports/ReportsDataTable.tsx b/src/app/(main)/reports/ReportsDataTable.tsx
index dca2aaa2..90fd291d 100644
--- a/src/app/(main)/reports/ReportsDataTable.tsx
+++ b/src/app/(main)/reports/ReportsDataTable.tsx
@@ -1,6 +1,6 @@
import { useReports } from '@/components/hooks';
import { ReportsTable } from './ReportsTable';
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { ReactNode } from 'react';
export function ReportsDataTable({
@@ -15,8 +15,8 @@ export function ReportsDataTable({
const queryResult = useReports({ websiteId, teamId });
return (
- children}>
+ children}>
{({ data }) => }
-
+
);
}
diff --git a/src/app/(main)/reports/[reportId]/page.tsx b/src/app/(main)/reports/[reportId]/page.tsx
index 037e1430..b228896a 100644
--- a/src/app/(main)/reports/[reportId]/page.tsx
+++ b/src/app/(main)/reports/[reportId]/page.tsx
@@ -1,7 +1,7 @@
import { Metadata } from 'next';
import { ReportPage } from './ReportPage';
-export default async function ({ params }: { params: { reportId: string } }) {
+export default async function ({ params }: { params: Promise<{ reportId: string }> }) {
const { reportId } = await params;
return ;
diff --git a/src/app/(main)/settings/layout.tsx b/src/app/(main)/settings/layout.tsx
index 94aed1fd..fcc7392a 100644
--- a/src/app/(main)/settings/layout.tsx
+++ b/src/app/(main)/settings/layout.tsx
@@ -1,5 +1,5 @@
-import { SettingsLayout } from './SettingsLayout';
import { Metadata } from 'next';
+import { SettingsLayout } from './SettingsLayout';
export default function ({ children }) {
if (process.env.cloudMode) {
diff --git a/src/app/(main)/settings/teams/TeamsDataTable.tsx b/src/app/(main)/settings/teams/TeamsDataTable.tsx
index f04edd1b..a02c00c0 100644
--- a/src/app/(main)/settings/teams/TeamsDataTable.tsx
+++ b/src/app/(main)/settings/teams/TeamsDataTable.tsx
@@ -1,4 +1,4 @@
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { TeamsTable } from '@/app/(main)/settings/teams/TeamsTable';
import { useLogin, useTeams } from '@/components/hooks';
import { ReactNode } from 'react';
@@ -16,10 +16,10 @@ export function TeamsDataTable({
const queryResult = useTeams(user.id);
return (
- children}>
+ children}>
{({ data }) => {
return ;
}}
-
+
);
}
diff --git a/src/app/(main)/settings/users/UserAddButton.tsx b/src/app/(main)/settings/users/UserAddButton.tsx
index ce08b05c..3dc312a7 100644
--- a/src/app/(main)/settings/users/UserAddButton.tsx
+++ b/src/app/(main)/settings/users/UserAddButton.tsx
@@ -1,29 +1,40 @@
-import { Button, Icon, Text, Modal, Icons, ModalTrigger, useToasts } from 'react-basics';
+import {
+ Button,
+ Icon,
+ Text,
+ Modal,
+ Icons,
+ DialogTrigger,
+ Dialog,
+ useToast,
+} from '@umami/react-zen';
import { UserAddForm } from './UserAddForm';
import { useMessages, useModified } from '@/components/hooks';
export function UserAddButton({ onSave }: { onSave?: () => void }) {
const { formatMessage, labels, messages } = useMessages();
- const { showToast } = useToasts();
+ const { toast } = useToast();
const { touch } = useModified();
const handleSave = () => {
- showToast({ message: formatMessage(messages.saved), variant: 'success' });
+ toast(formatMessage(messages.saved));
touch('users');
onSave?.();
};
return (
-
+
-
- {(close: () => void) => }
+
+
-
+
);
}
diff --git a/src/app/(main)/settings/users/UserDeleteButton.tsx b/src/app/(main)/settings/users/UserDeleteButton.tsx
index 448f87cf..d40467d2 100644
--- a/src/app/(main)/settings/users/UserDeleteButton.tsx
+++ b/src/app/(main)/settings/users/UserDeleteButton.tsx
@@ -1,4 +1,4 @@
-import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
+import { Button, Icon, Icons, Modal, DialogTrigger, Dialog, Text } from '@umami/react-zen';
import { useMessages, useLogin } from '@/components/hooks';
import { UserDeleteForm } from './UserDeleteForm';
@@ -15,18 +15,20 @@ export function UserDeleteButton({
const { user } = useLogin();
return (
-
-
+
);
}
diff --git a/src/app/(main)/settings/users/UserDeleteForm.tsx b/src/app/(main)/settings/users/UserDeleteForm.tsx
index 6db585cd..4ad54526 100644
--- a/src/app/(main)/settings/users/UserDeleteForm.tsx
+++ b/src/app/(main)/settings/users/UserDeleteForm.tsx
@@ -1,3 +1,4 @@
+import { useToast } from '@umami/react-zen';
import { useApi, useMessages, useModified } from '@/components/hooks';
import { ConfirmationForm } from '@/components/common/ConfirmationForm';
@@ -6,11 +7,13 @@ export function UserDeleteForm({ userId, username, onSave, onClose }) {
const { del, useMutation } = useApi();
const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/users/${userId}`) });
const { touch } = useModified();
+ const { toast } = useToast();
const handleConfirm = async () => {
mutate(null, {
onSuccess: async () => {
touch('users');
+ toast(formatMessage(messages.successMessage));
onSave?.();
onClose?.();
},
@@ -23,6 +26,7 @@ export function UserDeleteForm({ userId, username, onSave, onClose }) {
onConfirm={handleConfirm}
onClose={onClose}
buttonLabel={formatMessage(labels.delete)}
+ buttonVariant="danger"
isLoading={isPending}
error={error}
/>
diff --git a/src/app/(main)/settings/users/UsersDataTable.tsx b/src/app/(main)/settings/users/UsersDataTable.tsx
index 0d3c9df6..86b4df27 100644
--- a/src/app/(main)/settings/users/UsersDataTable.tsx
+++ b/src/app/(main)/settings/users/UsersDataTable.tsx
@@ -1,4 +1,4 @@
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { useUsers } from '@/components/hooks';
import { UsersTable } from './UsersTable';
import { ReactNode } from 'react';
@@ -13,8 +13,8 @@ export function UsersDataTable({
const queryResult = useUsers();
return (
- children}>
+ children}>
{({ data }) => }
-
+
);
}
diff --git a/src/app/(main)/settings/users/UsersTable.tsx b/src/app/(main)/settings/users/UsersTable.tsx
index 1e5aa1d3..dcfc74c8 100644
--- a/src/app/(main)/settings/users/UsersTable.tsx
+++ b/src/app/(main)/settings/users/UsersTable.tsx
@@ -1,9 +1,9 @@
-import { Text, Icon, Icons, GridTable, GridColumn } from 'react-basics';
+import { Row, Button, Text, Icon, Icons, DataTable, DataColumn } from '@umami/react-zen';
+import Link from 'next/link';
import { formatDistance } from 'date-fns';
import { ROLES } from '@/lib/constants';
import { useMessages, useLocale } from '@/components/hooks';
import { UserDeleteButton } from './UserDeleteButton';
-import { LinkButton } from '@/components/common/LinkButton';
export function UsersTable({
data = [],
@@ -16,44 +16,46 @@ export function UsersTable({
const { dateLocale } = useLocale();
return (
-
-
-
- {row =>
+
+
+
+ {(row: any) =>
formatMessage(
labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown,
)
}
-
-
- {row =>
+
+
+ {(row: any) =>
formatDistance(new Date(row.createdAt), new Date(), {
addSuffix: true,
locale: dateLocale,
})
}
-
-
- {row => row._count.website}
-
+
+
+ {(row: any) => row._count.websiteUser}
+
{showActions && (
-
- {row => {
+
+ {(row: any) => {
const { id, username } = row;
return (
- <>
+
-
-
-
-
- {formatMessage(labels.edit)}
-
- >
+
+
+
+
+
+ {formatMessage(labels.edit)}
+
+
+
);
}}
-
+
)}
-
+
);
}
diff --git a/src/app/(main)/settings/users/[userId]/UserEditForm.tsx b/src/app/(main)/settings/users/[userId]/UserEditForm.tsx
index a10a5f4b..94a6acd6 100644
--- a/src/app/(main)/settings/users/[userId]/UserEditForm.tsx
+++ b/src/app/(main)/settings/users/[userId]/UserEditForm.tsx
@@ -1,22 +1,27 @@
import {
- Dropdown,
- Item,
+ Select,
+ ListItem,
Form,
- FormRow,
+ FormField,
FormButtons,
- FormInput,
TextField,
- SubmitButton,
+ FormSubmitButton,
PasswordField,
-} from 'react-basics';
-import { useApi, useLogin, useMessages } from '@/components/hooks';
+ useToast,
+} from '@umami/react-zen';
+import { useApi, useLogin, useMessages, useModified } from '@/components/hooks';
import { ROLES } from '@/lib/constants';
-import { useContext, useRef } from 'react';
+import { useContext } from 'react';
import { UserContext } from './UserProvider';
export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () => void }) {
- const { formatMessage, labels, messages } = useMessages();
+ const { formatMessage, labels, messages, getMessage } = useMessages();
const { post, useMutation } = useApi();
+ const user = useContext(UserContext);
+ const { user: login } = useLogin();
+ const { toast } = useToast();
+ const { touch } = useModified();
+
const { mutate, error } = useMutation({
mutationFn: ({
username,
@@ -28,61 +33,47 @@ export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () =
role: string;
}) => post(`/users/${userId}`, { username, password, role }),
});
- const ref = useRef(null);
- const user = useContext(UserContext);
- const { user: login } = useLogin();
const handleSubmit = async (data: any) => {
mutate(data, {
onSuccess: async () => {
- ref.current.reset(data);
+ toast(formatMessage(messages.saved));
+ touch(`user:${user.id}`);
onSave?.();
},
});
};
- const renderValue = (value: string) => {
- if (value === ROLES.user) {
- return formatMessage(labels.user);
- }
- if (value === ROLES.admin) {
- return formatMessage(labels.admin);
- }
- if (value === ROLES.viewOnly) {
- return formatMessage(labels.viewOnly);
- }
- };
-
return (
-
);
diff --git a/src/app/(main)/settings/users/[userId]/UserPage.tsx b/src/app/(main)/settings/users/[userId]/UserPage.tsx
index ab784dc9..56812c0c 100644
--- a/src/app/(main)/settings/users/[userId]/UserPage.tsx
+++ b/src/app/(main)/settings/users/[userId]/UserPage.tsx
@@ -2,7 +2,7 @@
import { UserSettings } from './UserSettings';
import { UserProvider } from './UserProvider';
-export default function ({ userId }: { userId: string }) {
+export function UserPage({ userId }: { userId: string }) {
return (
diff --git a/src/app/(main)/settings/users/[userId]/UserProvider.tsx b/src/app/(main)/settings/users/[userId]/UserProvider.tsx
index 58ecc36c..0b87e63a 100644
--- a/src/app/(main)/settings/users/[userId]/UserProvider.tsx
+++ b/src/app/(main)/settings/users/[userId]/UserProvider.tsx
@@ -1,6 +1,6 @@
import { createContext, ReactNode, useEffect } from 'react';
+import { Loading } from '@umami/react-zen';
import { useModified, useUser } from '@/components/hooks';
-import { Loading } from 'react-basics';
export const UserContext = createContext(null);
@@ -18,5 +18,5 @@ export function UserProvider({ userId, children }: { userId: string; children: R
return ;
}
- return {children};
+ return {children};
}
diff --git a/src/app/(main)/settings/users/[userId]/UserSettings.tsx b/src/app/(main)/settings/users/[userId]/UserSettings.tsx
index 9af656b8..505e8ea4 100644
--- a/src/app/(main)/settings/users/[userId]/UserSettings.tsx
+++ b/src/app/(main)/settings/users/[userId]/UserSettings.tsx
@@ -1,46 +1,31 @@
-import { Key, useContext, useState } from 'react';
-import { Item, Tabs, useToasts } from 'react-basics';
+import { useContext } from 'react';
+import { Tabs, Tab, TabList, TabPanel } from '@umami/react-zen';
import { Icons } from '@/components/icons';
import { UserEditForm } from './UserEditForm';
import { PageHeader } from '@/components/layout/PageHeader';
import { useMessages } from '@/components/hooks';
import { UserWebsites } from './UserWebsites';
import { UserContext } from './UserProvider';
-import { Breadcrumb } from '@/components/common/Breadcrumb';
export function UserSettings({ userId }: { userId: string }) {
- const { formatMessage, labels, messages } = useMessages();
- const [tab, setTab] = useState('details');
+ const { formatMessage, labels } = useMessages();
const user = useContext(UserContext);
- const { showToast } = useToasts();
-
- const handleSave = () => {
- showToast({ message: formatMessage(messages.saved), variant: 'success' });
- };
-
- const breadcrumb = (
-
- );
return (
<>
- } breadcrumb={breadcrumb} />
-
- - {formatMessage(labels.details)}
- - {formatMessage(labels.websites)}
+ } />
+
+
+ {formatMessage(labels.details)}
+ {formatMessage(labels.websites)}
+
+
+
+
+
+
+
- {tab === 'details' && }
- {tab === 'websites' && }
>
);
}
diff --git a/src/app/(main)/settings/users/[userId]/UserWebsites.tsx b/src/app/(main)/settings/users/[userId]/UserWebsites.tsx
index d53a50f2..023b3420 100644
--- a/src/app/(main)/settings/users/[userId]/UserWebsites.tsx
+++ b/src/app/(main)/settings/users/[userId]/UserWebsites.tsx
@@ -1,15 +1,15 @@
import { WebsitesTable } from '@/app/(main)/settings/websites/WebsitesTable';
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { useWebsites } from '@/components/hooks';
export function UserWebsites({ userId }) {
const queryResult = useWebsites({ userId });
return (
-
+
{({ data }) => (
)}
-
+
);
}
diff --git a/src/app/(main)/settings/users/[userId]/page.tsx b/src/app/(main)/settings/users/[userId]/page.tsx
index b410643c..47bd3531 100644
--- a/src/app/(main)/settings/users/[userId]/page.tsx
+++ b/src/app/(main)/settings/users/[userId]/page.tsx
@@ -1,7 +1,7 @@
import { UserPage } from './UserPage';
import { Metadata } from 'next';
-export default async function ({ params }: { params: { userId: string } }) {
+export default async function ({ params }: { params: Promise<{ userId: string }> }) {
const { userId } = await params;
return ;
diff --git a/src/app/(main)/settings/websites/WebsitesDataTable.tsx b/src/app/(main)/settings/websites/WebsitesDataTable.tsx
index f62bb9e6..48bb0922 100644
--- a/src/app/(main)/settings/websites/WebsitesDataTable.tsx
+++ b/src/app/(main)/settings/websites/WebsitesDataTable.tsx
@@ -1,6 +1,6 @@
import { ReactNode } from 'react';
import { WebsitesTable } from '@/app/(main)/settings/websites/WebsitesTable';
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { useWebsites } from '@/components/hooks';
export function WebsitesDataTable({
@@ -19,7 +19,7 @@ export function WebsitesDataTable({
const queryResult = useWebsites({ teamId });
return (
- children}>
+ children}>
{({ data }) => (
)}
-
+
);
}
diff --git a/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx b/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx
index 6965f4fe..a5bdfe30 100644
--- a/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx
+++ b/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx
@@ -10,7 +10,7 @@ export function WebsitesSettingsPage({ teamId }: { teamId: string }) {
return (
<>
-
+
>
);
diff --git a/src/app/(main)/settings/websites/WebsitesTable.tsx b/src/app/(main)/settings/websites/WebsitesTable.tsx
index 0d9ea11b..6211b00b 100644
--- a/src/app/(main)/settings/websites/WebsitesTable.tsx
+++ b/src/app/(main)/settings/websites/WebsitesTable.tsx
@@ -1,7 +1,7 @@
import { ReactNode } from 'react';
-import { Text, Icon, Icons, GridTable, GridColumn } from 'react-basics';
+import { Row, Text, Icon, Icons, DataTable, DataColumn, Button } from '@umami/react-zen';
+import Link from 'next/link';
import { useMessages, useTeamUrl } from '@/components/hooks';
-import { LinkButton } from '@/components/common/LinkButton';
export interface WebsitesTableProps {
data: any[];
@@ -27,37 +27,41 @@ export function WebsitesTable({
}
return (
-
-
-
+
+
+
{showActions && (
-
- {row => {
- const { id: websiteId } = row;
+
+ {(row: any) => {
+ const websiteId = row.id;
return (
- <>
+
{allowEdit && (
-
-
-
-
- {formatMessage(labels.edit)}
-
+
+
+
+
+
+ {formatMessage(labels.edit)}
+
+
)}
{allowView && (
-
-
-
-
- {formatMessage(labels.view)}
-
+
+
+
+
+
+ {formatMessage(labels.view)}
+
+
)}
- >
+
);
}}
-
+
)}
-
+
);
}
diff --git a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx
index 96006268..8e9c6d7c 100644
--- a/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx
+++ b/src/app/(main)/settings/websites/[websiteId]/WebsiteEditForm.tsx
@@ -1,5 +1,12 @@
-import { useContext, useRef } from 'react';
-import { SubmitButton, Form, FormInput, FormRow, FormButtons, TextField } from 'react-basics';
+import { useContext } from 'react';
+import {
+ FormSubmitButton,
+ Form,
+ FormField,
+ FormButtons,
+ TextField,
+ useToast,
+} from '@umami/react-zen';
import { useApi, useMessages, useModified } from '@/components/hooks';
import { DOMAIN_REGEX } from '@/lib/constants';
import { WebsiteContext } from '@/app/(main)/websites/[websiteId]/WebsiteProvider';
@@ -8,16 +15,17 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa
const website = useContext(WebsiteContext);
const { formatMessage, labels, messages } = useMessages();
const { post, useMutation } = useApi();
+ const { toast } = useToast();
+ const { touch } = useModified();
+
const { mutate, error } = useMutation({
mutationFn: (data: any) => post(`/websites/${websiteId}`, data),
});
- const ref = useRef(null);
- const { touch } = useModified();
const handleSubmit = async (data: any) => {
mutate(data, {
onSuccess: async () => {
- ref.current.reset(data);
+ toast(formatMessage(messages.saved));
touch(`website:${website.id}`);
onSave?.();
},
@@ -25,38 +33,36 @@ export function WebsiteEditForm({ websiteId, onSave }: { websiteId: string; onSa
};
return (
-
);
diff --git a/src/app/(main)/settings/websites/[websiteId]/WebsiteSettings.tsx b/src/app/(main)/settings/websites/[websiteId]/WebsiteSettings.tsx
index d4a8d5d3..8cb96182 100644
--- a/src/app/(main)/settings/websites/[websiteId]/WebsiteSettings.tsx
+++ b/src/app/(main)/settings/websites/[websiteId]/WebsiteSettings.tsx
@@ -1,11 +1,10 @@
+import { useContext } from 'react';
+import { Button, Icon, Tabs, TabList, Tab, TabPanel, Text } from '@umami/react-zen';
+import Link from 'next/link';
import { WebsiteContext } from '@/app/(main)/websites/[websiteId]/WebsiteProvider';
-import { Breadcrumb } from '@/components/common/Breadcrumb';
import { useMessages } from '@/components/hooks';
import { Icons } from '@/components/icons';
import { PageHeader } from '@/components/layout/PageHeader';
-import Link from 'next/link';
-import { Key, useContext, useState } from 'react';
-import { Button, Icon, Item, Tabs, Text, useToasts } from 'react-basics';
import { ShareUrl } from './ShareUrl';
import { TrackingCode } from './TrackingCode';
import { WebsiteData } from './WebsiteData';
@@ -19,31 +18,11 @@ export function WebsiteSettings({
openExternal?: boolean;
}) {
const website = useContext(WebsiteContext);
- const { formatMessage, labels, messages } = useMessages();
- const [tab, setTab] = useState('details');
- const { showToast } = useToasts();
-
- const handleSave = () => {
- showToast({ message: formatMessage(messages.saved), variant: 'success' });
- };
-
- const breadcrumb = (
-
- );
+ const { formatMessage, labels } = useMessages();
return (
<>
- } breadcrumb={breadcrumb}>
+ }>
@@ -53,16 +32,26 @@ export function WebsiteSettings({
-
- - {formatMessage(labels.details)}
- - {formatMessage(labels.trackingCode)}
- - {formatMessage(labels.shareUrl)}
- - {formatMessage(labels.data)}
+
+
+ {formatMessage(labels.details)}
+ {formatMessage(labels.trackingCode)}
+ {formatMessage(labels.shareUrl)}
+ {formatMessage(labels.data)}
+
+
+
+
+
+
+
+
+
+
+
+
+
- {tab === 'details' && }
- {tab === 'tracking' && }
- {tab === 'share' && }
- {tab === 'data' && }
>
);
}
diff --git a/src/app/(main)/settings/websites/[websiteId]/page.tsx b/src/app/(main)/settings/websites/[websiteId]/page.tsx
index ce83c7ba..a65a5a9f 100644
--- a/src/app/(main)/settings/websites/[websiteId]/page.tsx
+++ b/src/app/(main)/settings/websites/[websiteId]/page.tsx
@@ -1,7 +1,7 @@
import { WebsiteSettingsPage } from './WebsiteSettingsPage';
import { Metadata } from 'next';
-export default async function ({ params }: { params: { websiteId: string } }) {
+export default async function ({ params }: { params: Promise<{ websiteId: string }> }) {
const { websiteId } = await params;
return ;
diff --git a/src/app/(main)/settings/websites/page.tsx b/src/app/(main)/settings/websites/page.tsx
index 1200d912..cc8f886a 100644
--- a/src/app/(main)/settings/websites/page.tsx
+++ b/src/app/(main)/settings/websites/page.tsx
@@ -1,7 +1,7 @@
import { Metadata } from 'next';
import { WebsitesSettingsPage } from './WebsitesSettingsPage';
-export default async function ({ params }: { params: { teamId: string } }) {
+export default async function ({ params }: { params: Promise<{ teamId: string }> }) {
const { teamId } = await params;
return ;
diff --git a/src/app/(main)/teams/[teamId]/settings/members/TeamMembersDataTable.tsx b/src/app/(main)/teams/[teamId]/settings/members/TeamMembersDataTable.tsx
index 44757349..339c1f3e 100644
--- a/src/app/(main)/teams/[teamId]/settings/members/TeamMembersDataTable.tsx
+++ b/src/app/(main)/teams/[teamId]/settings/members/TeamMembersDataTable.tsx
@@ -1,4 +1,4 @@
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { TeamMembersTable } from './TeamMembersTable';
import { useTeamMembers } from '@/components/hooks';
@@ -12,8 +12,8 @@ export function TeamMembersDataTable({
const queryResult = useTeamMembers(teamId);
return (
-
+
{({ data }) => }
-
+
);
}
diff --git a/src/app/(main)/teams/[teamId]/settings/team/page.tsx b/src/app/(main)/teams/[teamId]/settings/team/page.tsx
index 1d3d4565..4767b1c4 100644
--- a/src/app/(main)/teams/[teamId]/settings/team/page.tsx
+++ b/src/app/(main)/teams/[teamId]/settings/team/page.tsx
@@ -1,7 +1,7 @@
import { Metadata } from 'next';
import { TeamPage } from './TeamPage';
-export default async function ({ params }: { params: { teamId: string } }) {
+export default async function ({ params }: { params: Promise<{ teamId: string }> }) {
const { teamId } = await params;
return ;
diff --git a/src/app/(main)/teams/[teamId]/settings/websites/TeamWebsitesDataTable.tsx b/src/app/(main)/teams/[teamId]/settings/websites/TeamWebsitesDataTable.tsx
index af2dbf58..68f853ac 100644
--- a/src/app/(main)/teams/[teamId]/settings/websites/TeamWebsitesDataTable.tsx
+++ b/src/app/(main)/teams/[teamId]/settings/websites/TeamWebsitesDataTable.tsx
@@ -1,4 +1,4 @@
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { useTeamWebsites } from '@/components/hooks';
import { TeamWebsitesTable } from './TeamWebsitesTable';
@@ -12,8 +12,8 @@ export function TeamWebsitesDataTable({
const queryResult = useTeamWebsites(teamId);
return (
-
+
{({ data }) => }
-
+
);
}
diff --git a/src/app/(main)/teams/[teamId]/settings/websites/page.tsx b/src/app/(main)/teams/[teamId]/settings/websites/page.tsx
index 2ae8e23e..e34c35d5 100644
--- a/src/app/(main)/teams/[teamId]/settings/websites/page.tsx
+++ b/src/app/(main)/teams/[teamId]/settings/websites/page.tsx
@@ -1,7 +1,7 @@
import { TeamWebsitesPage } from './TeamWebsitesPage';
import { Metadata } from 'next';
-export default async function ({ params }: { params: { teamId: string } }) {
+export default async function ({ params }: { params: Promise<{ teamId: string }> }) {
const { teamId } = await params;
return ;
diff --git a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx
index adc45f37..7ca072c3 100644
--- a/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx
+++ b/src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx
@@ -1,7 +1,7 @@
import { Dropdown, Icon, Icons, Item, Text } from 'react-basics';
import { LinkButton } from '@/components/common/LinkButton';
import { useLocale, useMessages, useNavigation } from '@/components/hooks';
-import { SideNav } from '@/components/layout/SideNav';
+import { MenuNav } from '@/components/layout/MenuNav';
import { BrowsersTable } from '@/components/metrics/BrowsersTable';
import { CitiesTable } from '@/components/metrics/CitiesTable';
import { CountriesTable } from '@/components/metrics/CountriesTable';
@@ -156,7 +156,7 @@ export function WebsiteExpandedView({
{formatMessage(labels.back)}
-
+
-
+
{formatMessage(labels.previous)}
}) {
const { websiteId } = await params;
return ;
diff --git a/src/app/(main)/websites/[websiteId]/events/EventsDataTable.tsx b/src/app/(main)/websites/[websiteId]/events/EventsDataTable.tsx
index b81b51cb..d17406c7 100644
--- a/src/app/(main)/websites/[websiteId]/events/EventsDataTable.tsx
+++ b/src/app/(main)/websites/[websiteId]/events/EventsDataTable.tsx
@@ -1,6 +1,6 @@
import { useWebsiteEvents } from '@/components/hooks';
import { EventsTable } from './EventsTable';
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { ReactNode } from 'react';
export function EventsDataTable({
@@ -13,8 +13,8 @@ export function EventsDataTable({
const queryResult = useWebsiteEvents(websiteId);
return (
-
+
{({ data }) => }
-
+
);
}
diff --git a/src/app/(main)/websites/[websiteId]/events/page.tsx b/src/app/(main)/websites/[websiteId]/events/page.tsx
index 23cd5464..2bfc1401 100644
--- a/src/app/(main)/websites/[websiteId]/events/page.tsx
+++ b/src/app/(main)/websites/[websiteId]/events/page.tsx
@@ -1,7 +1,7 @@
import { Metadata } from 'next';
import { EventsPage } from './EventsPage';
-export default async function ({ params }: { params: { websiteId: string } }) {
+export default async function ({ params }: { params: Promise<{ websiteId: string }> }) {
const { websiteId } = await params;
return ;
diff --git a/src/app/(main)/websites/[websiteId]/realtime/page.tsx b/src/app/(main)/websites/[websiteId]/realtime/page.tsx
index 09945b7f..e6f82f7d 100644
--- a/src/app/(main)/websites/[websiteId]/realtime/page.tsx
+++ b/src/app/(main)/websites/[websiteId]/realtime/page.tsx
@@ -1,7 +1,7 @@
import { WebsiteRealtimePage } from './WebsiteRealtimePage';
import { Metadata } from 'next';
-export default async function ({ params }: { params: { websiteId: string } }) {
+export default async function ({ params }: { params: Promise<{ websiteId: string }> }) {
const { websiteId } = await params;
return ;
diff --git a/src/app/(main)/websites/[websiteId]/reports/page.tsx b/src/app/(main)/websites/[websiteId]/reports/page.tsx
index c307ae05..e760dc9a 100644
--- a/src/app/(main)/websites/[websiteId]/reports/page.tsx
+++ b/src/app/(main)/websites/[websiteId]/reports/page.tsx
@@ -1,7 +1,7 @@
import { WebsiteReportsPage } from './WebsiteReportsPage';
import { Metadata } from 'next';
-export default async function ({ params }: { params: { websiteId: string } }) {
+export default async function ({ params }: { params: Promise<{ websiteId: string }> }) {
const { websiteId } = await params;
return ;
diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx
index dd6a98af..6cc7eff4 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx
@@ -1,6 +1,6 @@
import { useWebsiteSessions } from '@/components/hooks';
import { SessionsTable } from './SessionsTable';
-import { DataTable } from '@/components/common/DataTable';
+import { DataGrid } from '@/components/common/DataGrid';
import { ReactNode } from 'react';
export function SessionsDataTable({
@@ -14,8 +14,8 @@ export function SessionsDataTable({
const queryResult = useWebsiteSessions(websiteId);
return (
- children}>
+ children}>
{({ data }) => }
-
+
);
}
diff --git a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/page.tsx b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/page.tsx
index a14a70c7..8d85a7c7 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/page.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/page.tsx
@@ -4,7 +4,7 @@ import { Metadata } from 'next';
export default async function WebsitePage({
params,
}: {
- params: { websiteId: string; sessionId: string };
+ params: Promise<{ websiteId: string; sessionId: string }>;
}) {
const { websiteId, sessionId } = await params;
diff --git a/src/app/(main)/websites/[websiteId]/sessions/page.tsx b/src/app/(main)/websites/[websiteId]/sessions/page.tsx
index 1012b6d1..7bf8216b 100644
--- a/src/app/(main)/websites/[websiteId]/sessions/page.tsx
+++ b/src/app/(main)/websites/[websiteId]/sessions/page.tsx
@@ -1,7 +1,7 @@
import { SessionsPage } from './SessionsPage';
import { Metadata } from 'next';
-export default async function ({ params }: { params: { websiteId: string } }) {
+export default async function ({ params }: { params: Promise<{ websiteId: string }> }) {
const { websiteId } = await params;
return ;
diff --git a/src/app/api/users/[userId]/route.ts b/src/app/api/users/[userId]/route.ts
index abb3331d..3dd88aab 100644
--- a/src/app/api/users/[userId]/route.ts
+++ b/src/app/api/users/[userId]/route.ts
@@ -27,7 +27,7 @@ export async function POST(request: Request, { params }: { params: Promise<{ use
const schema = z.object({
username: z.string().max(255),
password: z.string().max(255),
- role: z.string().regex(/admin|user|view-only/i),
+ role: z.enum(['admin', 'user', 'view-only']),
});
const { auth, body, error } = await parseRequest(request, schema);
diff --git a/src/app/login/LoginForm.tsx b/src/app/login/LoginForm.tsx
index e71fe6fc..129fd920 100644
--- a/src/app/login/LoginForm.tsx
+++ b/src/app/login/LoginForm.tsx
@@ -35,15 +35,7 @@ export function LoginForm() {
};
return (
-
+
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
index b1395313..384c4f80 100644
--- a/src/assets/logo.svg
+++ b/src/assets/logo.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
diff --git a/src/components/common/ConfirmationForm.tsx b/src/components/common/ConfirmationForm.tsx
index e532e6bb..5924bef3 100644
--- a/src/components/common/ConfirmationForm.tsx
+++ b/src/components/common/ConfirmationForm.tsx
@@ -1,11 +1,11 @@
import { ReactNode } from 'react';
-import { Button, LoadingButton, Form, FormButtons } from 'react-basics';
+import { Row, Button, FormSubmitButton, Form, FormButtons } from '@umami/react-zen';
import { useMessages } from '@/components/hooks';
export interface ConfirmationFormProps {
message: ReactNode;
buttonLabel?: ReactNode;
- buttonVariant?: 'none' | 'primary' | 'secondary' | 'quiet' | 'danger';
+ buttonVariant?: 'primary' | 'quiet' | 'danger';
isLoading?: boolean;
error?: string | Error;
onConfirm?: () => void;
@@ -24,13 +24,13 @@ export function ConfirmationForm({
const { formatMessage, labels } = useMessages();
return (
-
);
diff --git a/src/components/common/DataTable.module.css b/src/components/common/DataGrid.module.css
similarity index 100%
rename from src/components/common/DataTable.module.css
rename to src/components/common/DataGrid.module.css
diff --git a/src/components/common/DataTable.tsx b/src/components/common/DataGrid.tsx
similarity index 64%
rename from src/components/common/DataTable.tsx
rename to src/components/common/DataGrid.tsx
index 91f02516..ef652b70 100644
--- a/src/components/common/DataTable.tsx
+++ b/src/components/common/DataGrid.tsx
@@ -1,12 +1,10 @@
import { ReactNode } from 'react';
-import classNames from 'classnames';
-import { Loading, SearchField } from 'react-basics';
+import { Loading, SearchField, Row, Column } from '@umami/react-zen';
import { useMessages, useNavigation } from '@/components/hooks';
import { Empty } from '@/components/common/Empty';
import { Pager } from '@/components/common/Pager';
-import { PagedQueryResult } from '@/lib/types';
-import styles from './DataTable.module.css';
import { LoadingPanel } from '@/components/common/LoadingPanel';
+import { PagedQueryResult } from '@/lib/types';
const DEFAULT_SEARCH_DELAY = 600;
@@ -20,7 +18,7 @@ export interface DataTableProps {
children: ReactNode | ((data: any) => ReactNode);
}
-export function DataTable({
+export function DataGrid({
queryResult,
searchDelay = 600,
allowSearch = true,
@@ -30,12 +28,8 @@ export function DataTable({
children,
}: DataTableProps) {
const { formatMessage, labels, messages } = useMessages();
- const {
- result,
- params,
- setParams,
- query: { error, isLoading, isFetched },
- } = queryResult || {};
+ const { result, params, setParams, query } = queryResult || {};
+ const { error, isLoading, isFetched } = query || {};
const { page, pageSize, count, data } = result || {};
const { search } = params || {};
const hasData = Boolean(!isLoading && data?.length);
@@ -43,45 +37,38 @@ export function DataTable({
const { router, renderUrl } = useNavigation();
const handleSearch = (search: string) => {
- setParams({ ...params, search, page: params.page ? page : 1 });
+ setParams({ ...params, search });
};
const handlePageChange = (page: number) => {
- setParams({ ...params, search, page });
+ setParams({ ...params, page });
router.push(renderUrl({ page }));
};
return (
<>
{allowSearch && (hasData || search) && (
-
+
+
+
)}
-
+
{hasData ? (typeof children === 'function' ? children(result) : children) : null}
{isLoading && }
{!isLoading && !hasData && !search && (renderEmpty ? renderEmpty() : )}
{!isLoading && noResults && }
-
+
{allowPaging && hasData && (
-
+
+
+
)}
>
diff --git a/src/components/common/LoadingPanel.tsx b/src/components/common/LoadingPanel.tsx
index 0cdbd075..fd42b884 100644
--- a/src/components/common/LoadingPanel.tsx
+++ b/src/components/common/LoadingPanel.tsx
@@ -1,6 +1,6 @@
import { ReactNode } from 'react';
import classNames from 'classnames';
-import { Loading } from 'react-basics';
+import { Loading } from '@umami/react-zen';
import { ErrorMessage } from '@/components/common/ErrorMessage';
import { Empty } from '@/components/common/Empty';
import styles from './LoadingPanel.module.css';
diff --git a/src/components/common/Pager.tsx b/src/components/common/Pager.tsx
index 9301850c..2706c107 100644
--- a/src/components/common/Pager.tsx
+++ b/src/components/common/Pager.tsx
@@ -1,7 +1,5 @@
-import classNames from 'classnames';
-import { Button, Icon, Icons } from 'react-basics';
+import { Button, Icon, Icons, Row, Text } from '@umami/react-zen';
import { useMessages } from '@/components/hooks';
-import styles from './Pager.module.css';
export interface PagerProps {
page: string | number;
@@ -11,7 +9,7 @@ export interface PagerProps {
className?: string;
}
-export function Pager({ page, pageSize, count, onPageChange, className }: PagerProps) {
+export function Pager({ page, pageSize, count, onPageChange }: PagerProps) {
const { formatMessage, labels } = useMessages();
const maxPage = pageSize && count ? Math.ceil(+count / +pageSize) : 0;
const lastPage = page === maxPage;
@@ -34,24 +32,21 @@ export function Pager({ page, pageSize, count, onPageChange, className }: PagerP
}
return (
-
-
{formatMessage(labels.numberOfRecords, { x: count })}
-
-
handlePageChange(-1)} disabled={firstPage}>
-
-
+
+ {formatMessage(labels.numberOfRecords, { x: count })}
+
+ {formatMessage(labels.pageOf, { current: page, total: maxPage })}
+ handlePageChange(-1)} isDisabled={firstPage}>
+
+
-
- {formatMessage(labels.pageOf, { current: page, total: maxPage })}
-
- handlePageChange(1)} disabled={lastPage}>
-
-
+ handlePageChange(1)} isDisabled={lastPage}>
+
+
-
-
-
+
+
);
}
diff --git a/src/components/hooks/useApi.ts b/src/components/hooks/useApi.ts
index 17b83e5f..bd46d6c3 100644
--- a/src/components/hooks/useApi.ts
+++ b/src/components/hooks/useApi.ts
@@ -8,7 +8,7 @@ import { useApp } from '@/store/app';
const selector = (state: { shareToken: { token?: string } }) => state.shareToken;
async function handleResponse(res: FetchResponse): Promise {
- if (!res.ok) {
+ if (res.error) {
const { message, code } = res?.error?.error || {};
return Promise.reject(new Error(code || message || 'Unexpectd error.'));
}
diff --git a/src/components/input/LanguageButton.module.css b/src/components/input/LanguageButton.module.css
index dccb098d..d73bcb77 100644
--- a/src/components/input/LanguageButton.module.css
+++ b/src/components/input/LanguageButton.module.css
@@ -24,6 +24,7 @@
}
.selected {
+ color: var(--font-color);
font-weight: 700;
background: var(--blue100);
}
diff --git a/src/components/layout/MenuLayout.tsx b/src/components/layout/MenuLayout.tsx
index d8840122..493d8e55 100644
--- a/src/components/layout/MenuLayout.tsx
+++ b/src/components/layout/MenuLayout.tsx
@@ -1,22 +1,18 @@
import { ReactNode } from 'react';
-import { usePathname } from 'next/navigation';
-import { SideNav } from '@/components/layout/SideNav';
-import styles from './MenuLayout.module.css';
+import { Grid, Column } from '@umami/react-zen';
+import { MenuNav } from '@/components/layout/MenuNav';
export function MenuLayout({ items = [], children }: { items: any[]; children: ReactNode }) {
- const pathname = usePathname();
const cloudMode = !!process.env.cloudMode;
- const getKey = () => items.find(({ url }) => pathname === url)?.key;
-
return (
-
+
{!cloudMode && (
-
-
-
+
+
+
)}
- {children}
-
+ {children}
+
);
}
diff --git a/src/components/layout/SideNav.module.css b/src/components/layout/MenuNav.module.css
similarity index 100%
rename from src/components/layout/SideNav.module.css
rename to src/components/layout/MenuNav.module.css
diff --git a/src/components/layout/MenuNav.tsx b/src/components/layout/MenuNav.tsx
new file mode 100644
index 00000000..82e697cf
--- /dev/null
+++ b/src/components/layout/MenuNav.tsx
@@ -0,0 +1,29 @@
+import { List, ListItem, Text } from '@umami/react-zen';
+import { usePathname } from 'next/navigation';
+import Link from 'next/link';
+
+export interface SideNavProps {
+ items: any[];
+ shallow?: boolean;
+ scroll?: boolean;
+}
+
+export function MenuNav({ items, shallow = true, scroll = false }: SideNavProps) {
+ const pathname = usePathname();
+
+ return (
+
+ {items.map(({ key, label, url }) => {
+ const isSelected = pathname.startsWith(url);
+
+ return (
+
+
+ {label}
+
+
+ );
+ })}
+
+ );
+}
diff --git a/src/components/layout/NavGroup.module.css b/src/components/layout/NavGroup.module.css
deleted file mode 100644
index 4979210a..00000000
--- a/src/components/layout/NavGroup.module.css
+++ /dev/null
@@ -1,80 +0,0 @@
-.group {
- display: flex;
- flex-direction: column;
- width: 100%;
-}
-
-.header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- color: var(--base600);
- font-size: 11px;
- font-weight: 600;
- padding: 10px 20px;
- text-transform: uppercase;
- cursor: pointer;
-}
-
-.body {
- display: none;
-}
-
-.expanded .body {
- display: block;
-}
-
-.item {
- position: relative;
- display: flex;
- flex-direction: row;
- align-items: center;
- border-inline-end: 2px solid var(--base200);
- padding: 1rem 2rem;
- gap: var(--size500);
- font-weight: 600;
- width: 200px;
- margin-inline-end: -2px;
-}
-
-a.item {
- color: var(--base700);
-}
-
-.item.selected {
- color: var(--base900);
- border-inline-end-color: var(--primary400);
- background: var(--blue100);
-}
-
-.item:hover {
- color: var(--base900);
-}
-
-.minimized .text,
-.minimized .header {
- display: none;
-}
-
-.minimized .item {
- width: 60px;
- padding: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.divider:before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- margin: auto;
- border-top: 1px solid var(--base300);
- width: 160px;
-}
-
-.minimized .divider:before {
- width: 60px;
-}
diff --git a/src/components/layout/NavGroup.tsx b/src/components/layout/NavGroup.tsx
deleted file mode 100644
index c5a25893..00000000
--- a/src/components/layout/NavGroup.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { useState } from 'react';
-import { Icon, Text, TooltipPopup } from 'react-basics';
-import classNames from 'classnames';
-import { usePathname } from 'next/navigation';
-import Link from 'next/link';
-import { Icons } from '@/components/icons';
-import styles from './NavGroup.module.css';
-
-export interface NavGroupProps {
- title: string;
- items: any[];
- defaultExpanded?: boolean;
- allowExpand?: boolean;
- minimized?: boolean;
-}
-
-export function NavGroup({
- title,
- items,
- defaultExpanded = true,
- allowExpand = true,
- minimized = false,
-}: NavGroupProps) {
- const pathname = usePathname();
- const [expanded, setExpanded] = useState(defaultExpanded);
-
- const handleExpand = () => setExpanded(state => !state);
-
- return (
-
- {title && (
-
- {title}
-
-
-
-
- )}
-
- {items.map(({ label, url, icon, divider }) => {
- return (
-
-
- {icon}
- {label}
-
-
- );
- })}
-
-
- );
-}
diff --git a/src/components/layout/PageHeader.tsx b/src/components/layout/PageHeader.tsx
index db1608cd..cbbe12aa 100644
--- a/src/components/layout/PageHeader.tsx
+++ b/src/components/layout/PageHeader.tsx
@@ -1,29 +1,23 @@
import { ReactNode } from 'react';
-import { Heading, Icon, Breadcrumbs, Breadcrumb, Row } from '@umami/react-zen';
+import { Heading, Icon, Row } from '@umami/react-zen';
export function PageHeader({
title,
icon,
- breadcrumb,
children,
}: {
title?: ReactNode;
icon?: ReactNode;
className?: string;
- breadcrumb?: ReactNode;
children?: ReactNode;
}) {
return (
- <>
-
- {breadcrumb}
-
-
+
+
{icon && {icon}}
-
{title && {title}}
- {children}
- >
+ {children}
+
);
}
diff --git a/src/components/layout/SideNav.tsx b/src/components/layout/SideNav.tsx
deleted file mode 100644
index 4be70c2f..00000000
--- a/src/components/layout/SideNav.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import classNames from 'classnames';
-import { Menu, Item } from 'react-basics';
-import { usePathname } from 'next/navigation';
-import Link from 'next/link';
-import styles from './SideNav.module.css';
-
-export interface SideNavProps {
- selectedKey: string;
- items: any[];
- shallow?: boolean;
- scroll?: boolean;
- className?: string;
- onSelect?: () => void;
-}
-
-export function SideNav({
- selectedKey,
- items,
- shallow = true,
- scroll = false,
- className,
- onSelect = () => {},
-}: SideNavProps) {
- const pathname = usePathname();
- return (
-
- );
-}
diff --git a/src/index.ts b/src/index.ts
index e7b0e6c6..8cc8bcbc 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -44,7 +44,7 @@ export * from '@/app/(main)/teams/[teamId]/TeamProvider';
export * from '@/app/(main)/websites/[websiteId]/WebsiteProvider';
export * from '@/components/common/ConfirmationForm';
-export * from '@/components/common/DataTable';
+export * from '@/components/common/DataGrid';
export * from '@/components/common/Empty';
export * from '@/components/common/ErrorBoundary';
export * from '@/components/common/ErrorMessage';
@@ -59,6 +59,5 @@ export * from '@/components/common/Pager';
export * from '@/components/common/TypeConfirmationForm';
export * from '@/components/input/TeamsButton';
-export * from '@/components/input/ThemeButton';
export { ROLES } from '@/lib/constants';
diff --git a/src/lib/fetch.ts b/src/lib/fetch.ts
index ee9e160f..37056899 100644
--- a/src/lib/fetch.ts
+++ b/src/lib/fetch.ts
@@ -1,10 +1,18 @@
import { buildUrl } from '@/lib/url';
+export interface ErrorResponse {
+ error: {
+ status: number;
+ message: string;
+ code?: string;
+ };
+}
+
export interface FetchResponse {
ok: boolean;
status: number;
data?: any;
- error?: any;
+ error?: ErrorResponse;
}
export async function request(
diff --git a/src/styles/global.css b/src/styles/global.css
index 5639ecb2..aeadce51 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -4,6 +4,7 @@ body {
color: var(--font-color);
font-size: var(--font-size);
background-color: var(--background-color);
+ width: 100%;
min-height: 100vh;
}
diff --git a/src/styles/variables.css b/src/styles/variables.css
index 7852d78b..f7ebb028 100644
--- a/src/styles/variables.css
+++ b/src/styles/variables.css
@@ -1,3 +1,4 @@
html body {
--primary-color: #147af3;
+ --primary-font-color: var(--light-color);
}