mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
Merge branch 'analytics' into dev
# Conflicts: # .gitignore # src/app/api/share/[slug]/route.ts # src/app/share/[...shareId]/SharePage.tsx
This commit is contained in:
commit
adea3e9b1c
7 changed files with 148 additions and 62 deletions
|
|
@ -6,7 +6,13 @@ import { useMessages, useNavigation, useWebsite } from '@/components/hooks';
|
|||
import { Edit } from '@/components/icons';
|
||||
import { ActiveUsers } from '@/components/metrics/ActiveUsers';
|
||||
|
||||
export function WebsiteHeader({ showActions }: { showActions?: boolean }) {
|
||||
export function WebsiteHeader({
|
||||
showActions,
|
||||
allowLink = true,
|
||||
}: {
|
||||
showActions?: boolean;
|
||||
allowLink?: boolean;
|
||||
}) {
|
||||
const website = useWebsite();
|
||||
const { renderUrl, pathname } = useNavigation();
|
||||
const isSettings = pathname.endsWith('/settings');
|
||||
|
|
@ -21,7 +27,7 @@ export function WebsiteHeader({ showActions }: { showActions?: boolean }) {
|
|||
<PageHeader
|
||||
title={website.name}
|
||||
icon={<Favicon domain={website.domain} />}
|
||||
titleHref={renderUrl(`/websites/${website.id}`, false)}
|
||||
titleHref={allowLink ? renderUrl(`/websites/${website.id}`, false) : undefined}
|
||||
>
|
||||
<Row alignItems="center" gap="6" wrap="wrap">
|
||||
<ActiveUsers websiteId={website.id} />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,52 @@
|
|||
import { ROLES } from '@/lib/constants';
|
||||
import { secret } from '@/lib/crypto';
|
||||
import { createToken } from '@/lib/jwt';
|
||||
import prisma from '@/lib/prisma';
|
||||
import redis from '@/lib/redis';
|
||||
import { json, notFound } from '@/lib/response';
|
||||
import { getShareByCode } from '@/queries/prisma';
|
||||
import { getShareByCode, getWebsite } from '@/queries/prisma';
|
||||
|
||||
export interface WhiteLabel {
|
||||
name: string;
|
||||
url: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
async function getAccountId(website: { userId?: string; teamId?: string }): Promise<string | null> {
|
||||
if (website.userId) {
|
||||
return website.userId;
|
||||
}
|
||||
|
||||
if (website.teamId) {
|
||||
const teamOwner = await prisma.client.teamUser.findFirst({
|
||||
where: {
|
||||
teamId: website.teamId,
|
||||
role: ROLES.teamOwner,
|
||||
},
|
||||
select: {
|
||||
userId: true,
|
||||
},
|
||||
});
|
||||
|
||||
return teamOwner?.userId || null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getWhiteLabel(accountId: string): Promise<WhiteLabel | null> {
|
||||
if (!redis.enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await redis.client.get(`white-label:${accountId}`);
|
||||
|
||||
if (data) {
|
||||
return data as WhiteLabel;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function GET(_request: Request, { params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params;
|
||||
|
|
@ -12,12 +57,25 @@ export async function GET(_request: Request, { params }: { params: Promise<{ slu
|
|||
return notFound();
|
||||
}
|
||||
|
||||
const data = {
|
||||
const website = await getWebsite(share.entityId);
|
||||
|
||||
const data: Record<string, any> = {
|
||||
shareId: share.id,
|
||||
websiteId: share.entityId,
|
||||
parameters: share.parameters,
|
||||
};
|
||||
const token = createToken(data, secret());
|
||||
|
||||
return json({ ...data, token });
|
||||
data.token = createToken(data, secret());
|
||||
|
||||
const accountId = await getAccountId(website);
|
||||
|
||||
if (accountId) {
|
||||
const whiteLabel = await getWhiteLabel(accountId);
|
||||
|
||||
if (whiteLabel) {
|
||||
data.whiteLabel = whiteLabel;
|
||||
}
|
||||
}
|
||||
|
||||
return json(data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,18 @@
|
|||
import { Row, Text } from '@umami/react-zen';
|
||||
import type { WhiteLabel } from '@/app/api/share/[shareId]/route';
|
||||
import { CURRENT_VERSION, HOMEPAGE_URL } from '@/lib/constants';
|
||||
|
||||
export function Footer() {
|
||||
export function Footer({ whiteLabel }: { whiteLabel?: WhiteLabel }) {
|
||||
if (whiteLabel) {
|
||||
return (
|
||||
<Row as="footer" paddingY="6" justifyContent="flex-end">
|
||||
<a href={whiteLabel.url} target="_blank">
|
||||
<Text weight="bold">{whiteLabel.name}</Text>
|
||||
</a>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Row as="footer" paddingY="6" justifyContent="flex-end">
|
||||
<a href={HOMEPAGE_URL} target="_blank">
|
||||
|
|
|
|||
|
|
@ -1,17 +1,26 @@
|
|||
import { Icon, Row, Text, ThemeButton } from '@umami/react-zen';
|
||||
import type { WhiteLabel } from '@/app/api/share/[shareId]/route';
|
||||
import { LanguageButton } from '@/components/input/LanguageButton';
|
||||
import { PreferencesButton } from '@/components/input/PreferencesButton';
|
||||
import { Logo } from '@/components/svg';
|
||||
|
||||
export function Header() {
|
||||
export function Header({ whiteLabel }: { whiteLabel?: WhiteLabel }) {
|
||||
const logoUrl = whiteLabel?.url || 'https://umami.is';
|
||||
const logoName = whiteLabel?.name || 'umami';
|
||||
const logoImage = whiteLabel?.image;
|
||||
|
||||
return (
|
||||
<Row as="header" justifyContent="space-between" alignItems="center" paddingY="3">
|
||||
<a href="https://umami.is" target="_blank" rel="noopener">
|
||||
<a href={logoUrl} target="_blank" rel="noopener">
|
||||
<Row alignItems="center" gap>
|
||||
<Icon>
|
||||
<Logo />
|
||||
</Icon>
|
||||
<Text weight="bold">umami</Text>
|
||||
{logoImage ? (
|
||||
<img src={logoImage} alt={logoName} style={{ height: 24 }} />
|
||||
) : (
|
||||
<Icon>
|
||||
<Logo />
|
||||
</Icon>
|
||||
)}
|
||||
<Text weight="bold">{logoName}</Text>
|
||||
</Row>
|
||||
</a>
|
||||
<Row alignItems="center" gap>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export function SharePage({ shareId, path = '' }: { shareId: string; path?: stri
|
|||
return null;
|
||||
}
|
||||
|
||||
const { websiteId, parameters = {} } = shareToken;
|
||||
const { websiteId, parameters = {}, whiteLabel } = shareToken;
|
||||
|
||||
// Check if the requested path is allowed
|
||||
const pageKey = path || '';
|
||||
|
|
@ -84,10 +84,11 @@ export function SharePage({ shareId, path = '' }: { shareId: string; path?: stri
|
|||
</Column>
|
||||
<PageBody gap>
|
||||
<WebsiteProvider websiteId={websiteId}>
|
||||
<WebsiteHeader showActions={false} />
|
||||
<Header whiteLabel={whiteLabel} />
|
||||
<Column>
|
||||
<PageComponent websiteId={websiteId} />
|
||||
</Column>
|
||||
<Footer whiteLabel={whiteLabel} />
|
||||
</WebsiteProvider>
|
||||
</PageBody>
|
||||
</Grid>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue