feat: plausible to dashboard
This commit is contained in:
parent
34e8fd2c3f
commit
e47094fbf4
|
|
@ -3,12 +3,13 @@ import interClass from '@gitroom/react/helpers/inter.font';
|
|||
export const dynamic = 'force-dynamic';
|
||||
import './global.css';
|
||||
import 'react-tooltip/dist/react-tooltip.css';
|
||||
import "@copilotkit/react-ui/styles.css";
|
||||
import '@copilotkit/react-ui/styles.css';
|
||||
|
||||
import LayoutContext from '@gitroom/frontend/components/layout/layout.context';
|
||||
import { ReactNode } from 'react';
|
||||
import { Chakra_Petch } from 'next/font/google';
|
||||
import { isGeneral } from '@gitroom/react/helpers/is.general';
|
||||
import PlausibleProvider from 'next-plausible';
|
||||
|
||||
const chakra = Chakra_Petch({ weight: '400', subsets: ['latin'] });
|
||||
|
||||
|
|
@ -16,10 +17,16 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
return (
|
||||
<html className={interClass}>
|
||||
<head>
|
||||
<link rel="icon" href={!isGeneral() ? "/favicon.png" : "/postiz-fav.png"} sizes="any" />
|
||||
<link
|
||||
rel="icon"
|
||||
href={!isGeneral() ? '/favicon.png' : '/postiz-fav.png'}
|
||||
sizes="any"
|
||||
/>
|
||||
</head>
|
||||
<body className={chakra.className}>
|
||||
<LayoutContext>{children}</LayoutContext>
|
||||
<PlausibleProvider domain={isGeneral() ? "postiz.com" : "gitroom.com"}>
|
||||
<LayoutContext>{children}</LayoutContext>
|
||||
</PlausibleProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import interClass from '@gitroom/react/helpers/inter.font';
|
|||
import { isGeneral } from '@gitroom/react/helpers/is.general';
|
||||
import clsx from 'clsx';
|
||||
import { GoogleProvider } from '@gitroom/frontend/components/auth/providers/google.provider';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
|
||||
type Inputs = {
|
||||
email: string;
|
||||
|
|
@ -74,6 +75,7 @@ export function RegisterAfter({
|
|||
const [loading, setLoading] = useState(false);
|
||||
const getQuery = useSearchParams();
|
||||
const router = useRouter();
|
||||
const fireEvents = useFireEvents();
|
||||
|
||||
const isAfterProvider = useMemo(() => {
|
||||
return !!token && !!provider;
|
||||
|
|
@ -107,6 +109,8 @@ export function RegisterAfter({
|
|||
setLoading(false);
|
||||
}
|
||||
|
||||
fireEvents('register');
|
||||
|
||||
if (register.headers.get('activate')) {
|
||||
router.push('/auth/activate');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
'use client';
|
||||
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import { LoadingComponent } from '@gitroom/frontend/components/layout/loading';
|
||||
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
||||
import { MainBillingComponent } from './main.billing.component';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
|
||||
export const BillingComponent = () => {
|
||||
const fetch = useFetch();
|
||||
const searchParams = useSearchParams();
|
||||
const fireEvents = useFireEvents();
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.get('check')) {
|
||||
fireEvents('purchase');
|
||||
}
|
||||
}, []);
|
||||
|
||||
const load = useCallback(async (path: string) => {
|
||||
return await (await fetch(path)).json();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { Button } from '@gitroom/react/form/button';
|
|||
import { useSWRConfig } from 'swr';
|
||||
import { useToaster } from '@gitroom/react/toaster/toaster';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
|
||||
export const LifetimeDeal = () => {
|
||||
const fetch = useFetch();
|
||||
|
|
@ -17,6 +18,7 @@ export const LifetimeDeal = () => {
|
|||
const toast = useToaster();
|
||||
const { mutate } = useSWRConfig();
|
||||
const router = useRouter();
|
||||
const fireEvents = useFireEvents();
|
||||
|
||||
const claim = useCallback(async () => {
|
||||
const { success } = await (
|
||||
|
|
@ -32,6 +34,7 @@ export const LifetimeDeal = () => {
|
|||
if (success) {
|
||||
mutate('/user/self');
|
||||
toast.show('Successfully claimed the code');
|
||||
fireEvents('lifetime_claimed');
|
||||
} else {
|
||||
toast.show('Code already claimed or invalid code', 'warning');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@ import { useRouter, useSearchParams } from 'next/navigation';
|
|||
import { Integration } from '@prisma/client';
|
||||
import ImageWithFallback from '@gitroom/react/helpers/image.with.fallback';
|
||||
import { useToaster } from '@gitroom/react/toaster/toaster';
|
||||
import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events';
|
||||
|
||||
export const LaunchesComponent = () => {
|
||||
const fetch = useFetch();
|
||||
const router = useRouter();
|
||||
const search = useSearchParams();
|
||||
const toast = useToaster();
|
||||
const fireEvents = useFireEvents();
|
||||
|
||||
const [reload, setReload] = useState(false);
|
||||
const load = useCallback(async (path: string) => {
|
||||
|
|
@ -97,6 +99,9 @@ export const LaunchesComponent = () => {
|
|||
if (search.get('scope') === 'missing') {
|
||||
toast.show('You have to approve all the channel permissions', 'warning');
|
||||
}
|
||||
if (search.get('added')) {
|
||||
fireEvents('channel_added');
|
||||
}
|
||||
if (window.opener) {
|
||||
window.close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import {usePlausible} from 'next-plausible'
|
||||
import {useCallback} from "react";
|
||||
|
||||
export const useFireEvents = () => {
|
||||
const plausible = usePlausible();
|
||||
return useCallback((name: string, props?: object) => {
|
||||
plausible(name, {props});
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import {FC, useCallback, useEffect} from "react";
|
||||
import {useSearchParams} from "next/navigation";
|
||||
|
||||
const UtmSaver: FC = () => {
|
||||
const query = useSearchParams();
|
||||
useEffect(() => {
|
||||
const landingUrl = localStorage.getItem('landingUrl');
|
||||
if (landingUrl) {
|
||||
return ;
|
||||
}
|
||||
|
||||
localStorage.setItem('landingUrl', window.location.href);
|
||||
localStorage.setItem('referrer', document.referrer);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const utm = query.get('utm_source') || query.get('utm');
|
||||
const utmMedium = query.get('utm_medium');
|
||||
const utmCampaign = query.get('utm_campaign');
|
||||
|
||||
if (utm) {
|
||||
localStorage.setItem('utm', utm);
|
||||
}
|
||||
if (utmMedium) {
|
||||
localStorage.setItem('utm_medium', utmMedium);
|
||||
}
|
||||
if (utmCampaign) {
|
||||
localStorage.setItem('utm_campaign', utmCampaign);
|
||||
}
|
||||
}, [query]);
|
||||
|
||||
return <></>;
|
||||
}
|
||||
|
||||
export const useUtmSaver = () => {
|
||||
return useCallback(() => {
|
||||
return {
|
||||
utm: localStorage.getItem('utm'),
|
||||
utmMedium: localStorage.getItem('utm_medium'),
|
||||
utmCampaign: localStorage.getItem('utm_campaign'),
|
||||
landingUrl: localStorage.getItem('landingUrl'),
|
||||
referrer: localStorage.getItem('referrer'),
|
||||
}
|
||||
}, []);
|
||||
}
|
||||
|
||||
export default UtmSaver;
|
||||
|
|
@ -84,6 +84,7 @@
|
|||
"multer": "^1.4.5-lts.1",
|
||||
"nestjs-command": "^3.1.4",
|
||||
"next": "^14.2.4",
|
||||
"next-plausible": "^3.12.0",
|
||||
"openai": "^4.47.1",
|
||||
"prisma-paginate": "^5.2.1",
|
||||
"react": "18.2.0",
|
||||
|
|
@ -29566,6 +29567,19 @@
|
|||
"react-dom": ">=16.x <=18.x"
|
||||
}
|
||||
},
|
||||
"node_modules/next-plausible": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/next-plausible/-/next-plausible-3.12.0.tgz",
|
||||
"integrity": "sha512-SSkEqKQ6PgR8fx3sYfIAT69k2xuCUXO5ngkSS19CjxY97lAoZxsfZpYednxB4zo0mHYv87JzhPynrdBPlCBVHg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/4lejandrito/next-plausible?sponsor=1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "^11.1.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/next/node_modules/@swc/helpers": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@
|
|||
"multer": "^1.4.5-lts.1",
|
||||
"nestjs-command": "^3.1.4",
|
||||
"next": "^14.2.4",
|
||||
"next-plausible": "^3.12.0",
|
||||
"openai": "^4.47.1",
|
||||
"prisma-paginate": "^5.2.1",
|
||||
"react": "18.2.0",
|
||||
|
|
|
|||
Loading…
Reference in New Issue