import CopyInput from '@/components/forms/copy-input';
import FullPageLoadingState from '@/components/full-page-loading-state';
import Syntax from '@/components/syntax';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
import { useAppContext } from '@/hooks/use-app-context';
import { useAppParams } from '@/hooks/use-app-params';
import { useTRPC } from '@/integrations/trpc/react';
import type {
IRealtimeWidgetOptions,
IWidgetType,
} from '@openpanel/validation';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { createFileRoute } from '@tanstack/react-router';
import { ExternalLinkIcon } from 'lucide-react';
import { useEffect, useState } from 'react';
import { toast } from 'sonner';
export const Route = createFileRoute(
'/_app/$organizationId/$projectId/settings/_tabs/widgets',
)({
component: Component,
});
function Component() {
const { projectId, organizationId } = useAppParams();
const { dashboardUrl } = useAppContext();
const trpc = useTRPC();
const queryClient = useQueryClient();
// Fetch both widget types
const realtimeWidgetQuery = useQuery(
trpc.widget.get.queryOptions({ projectId, type: 'realtime' }),
);
const counterWidgetQuery = useQuery(
trpc.widget.get.queryOptions({ projectId, type: 'counter' }),
);
// Toggle mutation
const toggleMutation = useMutation(
trpc.widget.toggle.mutationOptions({
onSuccess: (_, variables) => {
queryClient.invalidateQueries(
trpc.widget.get.queryFilter({ projectId, type: variables.type }),
);
toast.success(variables.enabled ? 'Widget enabled' : 'Widget disabled');
},
onError: (error) => {
toast.error(error.message || 'Failed to update widget');
},
}),
);
// Update options mutation
const updateOptionsMutation = useMutation(
trpc.widget.updateOptions.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries(
trpc.widget.get.queryFilter({ projectId, type: 'realtime' }),
);
toast.success('Widget options updated');
},
onError: (error) => {
toast.error(error.message || 'Failed to update options');
},
}),
);
const handleToggle = (type: IWidgetType, enabled: boolean) => {
toggleMutation.mutate({
projectId,
organizationId,
type,
enabled,
});
};
if (realtimeWidgetQuery.isLoading || counterWidgetQuery.isLoading) {
return
Embed a realtime visitor counter widget on your website. The widget shows live visitor count, activity histogram, top countries, referrers and paths.
Direct link to the widget. You can open this in a new tab or embed it.
Copy this code and paste it into your website HTML where you want the widget to appear.
A compact live visitor counter badge you can embed anywhere. Shows the current number of unique visitors with a live indicator.
Direct link to the counter widget.
Copy this code and paste it into your website HTML where you want the counter to appear.