Skip to content

Commit

Permalink
Merge pull request #68 from ruru-m07/feat/posthog
Browse files Browse the repository at this point in the history
feat(analytics): integrate posthog for web analytics
  • Loading branch information
ruru-m07 authored Sep 14, 2024
2 parents aae6d56 + f528abe commit a5aae2c
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 44 deletions.
15 changes: 8 additions & 7 deletions apps/www/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { ReactNode } from "react";
import type { Viewport } from "next";
import { ScrollArea } from "@/components/scroll-area";
import { Analytics } from "@vercel/analytics/react";
import { RootProvider } from "fumadocs-ui/provider";
import { RuruProvider } from "ruru-ui/provider";
import { GeistSans } from "geist/font/sans";
Expand All @@ -10,6 +9,7 @@ import { baseUrl, createMetadata } from "@/utils/metadata";
import "./global.css";
import "fumadocs-ui/style.css";
import "fumadocs-ui/twoslash.css";
import { CSPostHogProvider } from "./providers";

export const metadata = createMetadata({
title: {
Expand All @@ -36,12 +36,13 @@ export default function Layout({ children }: { children: ReactNode }) {
suppressHydrationWarning
>
<body>
<Analytics />
<RootProvider>
<RuruProvider>
<ScrollArea className="h-screen">{children}</ScrollArea>
</RuruProvider>
</RootProvider>
<CSPostHogProvider>
<RootProvider>
<RuruProvider>
<ScrollArea className="h-screen">{children}</ScrollArea>
</RuruProvider>
</RootProvider>
</CSPostHogProvider>
</body>
</html>
);
Expand Down
18 changes: 18 additions & 0 deletions apps/www/app/providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use client";

import posthog from "posthog-js";
import { PostHogProvider } from "posthog-js/react";

if (!process.env.NEXT_PUBLIC_POSTHOG_KEY) {
throw new Error("NEXT_PUBLIC_POSTHOG_KEY is required");
}

if (typeof window !== "undefined") {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
person_profiles: "identified_only", // or 'always' to create profiles for anonymous users as well
});
}
export function CSPostHogProvider({ children }: { children: React.ReactNode }) {
return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
}
2 changes: 1 addition & 1 deletion apps/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-toggle-group": "^1.1.0",
"@vercel/analytics": "^1.3.1",
"class-variance-authority": "^0.7.0",
"fs": "0.0.1-security",
"fumadocs-core": "12.4.2",
Expand All @@ -29,6 +28,7 @@
"next": "^14.2.4",
"os": "^0.1.2",
"path": "^0.12.7",
"posthog-js": "^1.161.3",
"process": "^0.11.10",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/registry/components/avatar.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": [
{
"name": "avatar.tsx",
"content": "import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\n\ntype AvatarProps = Omit<\n React.ComponentPropsWithoutRef<\"img\">,\n \"src\" | \"alt\"\n> & {\n \n className?: string;\n \n size?: number;\n \n placeholder?: string;\n \n src: string;\n};\n\nconst Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(\n ({ className, size = 30, src, placeholder, ...props }, ref) => {\n return (\n <img\n className={cn(`rounded-full border`, className)}\n aria-label=\"avatar\"\n ref={ref}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n src={src}\n alt={placeholder}\n {...props}\n />\n );\n },\n);\nAvatar.displayName = \"Avatar\";\n\ntype AvatarGroupProps = Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"children\"\n> & {\n \n className?: string;\n \n members: { src: string; alt: string }[];\n \n size?: number;\n \n limit?: number;\n \n aClassName?: string;\n \n lnClassName?: string;\n};\n\nconst AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n (\n { className, aClassName, lnClassName, size = 30, members, limit, ...props },\n ref,\n ) => {\n const displayedMembers =\n limit && members.length > limit ? members.slice(0, limit - 1) : members;\n const extraMembersCount =\n limit && members.length > limit ? members.length - limit + 1 : 0;\n\n return (\n <div className={cn(`flex`, className)} ref={ref} {...props}>\n {displayedMembers.map((member, index) => (\n <Avatar\n key={index}\n className={cn(`-ml-2 border`, aClassName)}\n size={size}\n src={member.src}\n placeholder={member.alt}\n />\n ))}\n {extraMembersCount > 0 && (\n <div\n className={cn(\n `lastcount -ml-2 flex items-center justify-center rounded-full border bg-primary-foreground`,\n lnClassName,\n )}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n >\n +{extraMembersCount}\n </div>\n )}\n </div>\n );\n },\n);\nAvatarGroup.displayName = \"AvatarGroup\";\n\ntype AvatarWithBadgeProps = Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"children\"\n> & {\n \n className?: string;\n \n size?: number;\n \n src: string;\n \n placeholder?: string;\n \n badgeSrc: string;\n \n iClassName?: string;\n \n sClassName?: string;\n};\n\nconst AvatarWithBadge = React.forwardRef<HTMLDivElement, AvatarWithBadgeProps>(\n (\n {\n className,\n sClassName,\n iClassName,\n size = 30,\n src,\n placeholder,\n badgeSrc,\n ...props\n },\n ref,\n ) => {\n return (\n <div\n className={cn(\"relative inline-block\", className)}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n ref={ref}\n {...props}\n >\n <img\n className={cn(\"rounded-full border\", iClassName)}\n style={{\n width: \"100%\",\n height: \"100%\",\n }}\n src={src}\n alt={placeholder}\n />\n <img\n className={cn(\n \"absolute bottom-0 left-0 rounded-full border\",\n sClassName,\n )}\n style={{\n width: `${size / 3}px`,\n height: `${size / 3}px`,\n }}\n src={badgeSrc}\n alt=\"badge\"\n />\n </div>\n );\n },\n);\nAvatarWithBadge.displayName = \"AvatarWithBadge\";\n\nexport { Avatar, AvatarGroup, AvatarWithBadge };\n"
"content": "import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\n\ntype AvatarProps = Omit<\n React.ComponentPropsWithoutRef<\"img\">,\n \"src\" | \"alt\"\n> & {\n \n className?: string;\n \n size?: number;\n \n placeholder?: string;\n \n src: string;\n};\n\nconst Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(\n ({ className, size = 30, src, placeholder, ...props }, ref) => {\n return (\n <img\n className={cn(`rounded-full border`, className)}\n aria-label=\"avatar\"\n ref={ref}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n src={src}\n alt={placeholder}\n {...props}\n />\n );\n },\n);\nAvatar.displayName = \"Avatar\";\n\ntype AvatarGroupProps = Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"children\"\n> & {\n \n className?: string;\n \n members: { src: string; alt: string }[];\n \n size?: number;\n \n limit?: number;\n \n aClassName?: string;\n \n lnClassName?: string;\n};\n\nconst AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n (\n { className, aClassName, lnClassName, size = 30, members, limit, ...props },\n ref,\n ) => {\n const displayedMembers =\n limit && members.length > limit ? members.slice(0, limit - 1) : members;\n const extraMembersCount =\n limit && members.length > limit ? members.length - limit + 1 : 0;\n\n return (\n <div className={cn(`flex`, className)} ref={ref} {...props}>\n {displayedMembers.map((member, index) => (\n <Avatar\n key={index}\n className={cn(`-ml-2 border`, aClassName)}\n size={size}\n src={member.src}\n placeholder={member.alt}\n />\n ))}\n {extraMembersCount > 0 && (\n <div\n className={cn(\n `lastcount -ml-2 flex items-center justify-center rounded-full border bg-muted`,\n lnClassName,\n )}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n >\n +{extraMembersCount}\n </div>\n )}\n </div>\n );\n },\n);\nAvatarGroup.displayName = \"AvatarGroup\";\n\ntype AvatarWithBadgeProps = Omit<\n React.ComponentPropsWithoutRef<\"div\">,\n \"children\"\n> & {\n \n className?: string;\n \n size?: number;\n \n src: string;\n \n placeholder?: string;\n \n badgeSrc: string;\n \n iClassName?: string;\n \n sClassName?: string;\n};\n\nconst AvatarWithBadge = React.forwardRef<HTMLDivElement, AvatarWithBadgeProps>(\n (\n {\n className,\n sClassName,\n iClassName,\n size = 30,\n src,\n placeholder,\n badgeSrc,\n ...props\n },\n ref,\n ) => {\n return (\n <div\n className={cn(\"relative inline-block\", className)}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n ref={ref}\n {...props}\n >\n <img\n className={cn(\"rounded-full border\", iClassName)}\n style={{\n width: \"100%\",\n height: \"100%\",\n }}\n src={src}\n alt={placeholder}\n />\n <img\n className={cn(\n \"absolute bottom-0 left-0 rounded-full border\",\n sClassName,\n )}\n style={{\n width: `${size / 3}px`,\n height: `${size / 3}px`,\n }}\n src={badgeSrc}\n alt=\"badge\"\n />\n </div>\n );\n },\n);\nAvatarWithBadge.displayName = \"AvatarWithBadge\";\n\nexport { Avatar, AvatarGroup, AvatarWithBadge };\n"
}
],
"type": "components:ui"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/registry/components/badge.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": [
{
"name": "badge.tsx",
"content": "import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/utils/cn\";\n\nconst variants = {\n gray: \"bg-[#8f8f8f] text-white\",\n \"gray-subtle\": \"bg-[#1f1f1f] text-white\",\n blue: \"bg-[#0072f5] text-white\",\n \"blue-subtle\": \"bg-[#10233d] text-[#52a8ff]\",\n purple: \"bg-[#8e4ec6] text-white\",\n \"purple-subtle\": \"bg-[#2e1938] text-[#bf7af0]\",\n amber: \"bg-[#ffb224] text-black\",\n \"amber-subtle\": \"bg-[#331b00] text-[#f2a20d]\",\n red: \"bg-[#e5484d] text-white\",\n \"red-subtle\": \"bg-[#3c1618] text-[#ff6166]\",\n pink: \"bg-[#ea3e83] text-white\",\n \"pink-subtle\": \"bg-[#4f1c31] text-[#f75f8f]\",\n green: \"bg-[#45a557] text-white\",\n \"green-subtle\": \"bg-[#0f2e18] text-[#62c073]\",\n teal: \"bg-[#12a594] text-white\",\n \"teal-subtle\": \"bg-[#083a33] text-[#0ac7b4]\",\n inverted: \"bg-primary text-primary-foreground\",\n};\n\nconst sizes = {\n sm: \"text-xs px-1.5 py-[1.5px]\",\n md: \"text-sm px-2.5 py-[2px]\",\n lg: \"text-lg px-3 py-[2.5px]\",\n};\n\nconst badgeVariants = cva(\n \"w-fit h-fit inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 capitalize\",\n {\n variants: {\n variant: {\n ...variants,\n },\n size: {\n ...sizes,\n },\n },\n defaultVariants: {\n variant: \"gray\",\n size: \"md\",\n },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n \n children: React.ReactNode;\n \n variant: keyof typeof variants;\n \n size?: \"sm\" | \"md\" | \"lg\";\n \n icon?: React.ReactNode;\n}\n\nconst Badge: React.FC<BadgeProps> = ({\n children,\n className,\n variant,\n size = \"md\",\n icon,\n ...props\n}: BadgeProps): React.ReactElement => {\n return (\n <div className={cn(badgeVariants({ variant, size }), className)} {...props}>\n {icon && <span className=\"mr-1\">{icon}</span>}\n {children}\n </div>\n );\n};\n\nexport { Badge, badgeVariants };\n"
"content": "import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/utils/cn\";\n\nconst variants = {\n gray: \"bg-[#8f8f8f] text-white\",\n \"gray-subtle\": \"bg-[#1f1f1f] text-white\",\n blue: \"bg-[#0072f5] text-white\",\n \"blue-subtle\": \"bg-[#10233d] text-[#52a8ff]\",\n purple: \"bg-[#8e4ec6] text-white\",\n \"purple-subtle\": \"bg-[#2e1938] text-[#bf7af0]\",\n amber: \"bg-[#ffb224] text-black\",\n \"amber-subtle\": \"bg-[#331b00] text-[#f2a20d]\",\n red: \"bg-[#e5484d] text-white\",\n \"red-subtle\": \"bg-[#3c1618] text-[#ff6166]\",\n pink: \"bg-[#ea3e83] text-white\",\n \"pink-subtle\": \"bg-[#4f1c31] text-[#f75f8f]\",\n green: \"bg-[#45a557] text-white\",\n \"green-subtle\": \"bg-[#0f2e18] text-[#62c073]\",\n teal: \"bg-[#12a594] text-white\",\n \"teal-subtle\": \"bg-[#083a33] text-[#0ac7b4]\",\n inverted: \"bg-black text-white dark:bg-white dark:text-black\",\n};\n\nconst sizes = {\n sm: \"text-xs px-1.5 py-[1.5px]\",\n md: \"text-sm px-2.5 py-[2px]\",\n lg: \"text-lg px-3 py-[2.5px]\",\n};\n\nconst badgeVariants = cva(\n \"w-fit h-fit inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 capitalize\",\n {\n variants: {\n variant: {\n ...variants,\n },\n size: {\n ...sizes,\n },\n },\n defaultVariants: {\n variant: \"gray\",\n size: \"md\",\n },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n \n children: React.ReactNode;\n \n variant: keyof typeof variants;\n \n size?: \"sm\" | \"md\" | \"lg\";\n \n icon?: React.ReactNode;\n}\n\nconst Badge: React.FC<BadgeProps> = ({\n children,\n className,\n variant,\n size = \"md\",\n icon,\n ...props\n}: BadgeProps): React.ReactElement => {\n return (\n <div className={cn(badgeVariants({ variant, size }), className)} {...props}>\n {icon && <span className=\"mr-1\">{icon}</span>}\n {children}\n </div>\n );\n};\n\nexport { Badge, badgeVariants };\n"
}
],
"type": "components:ui"
Expand Down
Loading

0 comments on commit a5aae2c

Please sign in to comment.