Skip to content

Commit baffd77

Browse files
author
wizard-ci[bot]
committed
wizard-ci: react-router/rrv7-starter
1 parent ca0defc commit baffd77

File tree

17 files changed

+569
-146
lines changed

17 files changed

+569
-146
lines changed

apps/react-router/rrv7-starter/app/components/PostCard.tsx

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState, useEffect } from 'react'
2+
import { usePostHog } from '@posthog/react'
23
import type { FakePost } from '@/lib/data/fake-data'
34
import cn from '@/lib/utils/cn'
45
import { getLikedPosts, toggleLikedPost } from '@/lib/utils/localStorage'
@@ -8,6 +9,7 @@ interface PostCardProps {
89
}
910

1011
export function PostCard({ post }: PostCardProps) {
12+
const posthog = usePostHog()
1113
const [liked, setLiked] = useState(false)
1214
const [likes, setLikes] = useState(post.likes)
1315

@@ -19,17 +21,27 @@ export function PostCard({ post }: PostCardProps) {
1921
const handleLike = () => {
2022
const newLikedState = toggleLikedPost(post.id)
2123
setLiked(newLikedState)
22-
setLikes((prev) => (prev + (newLikedState ? 1 : -1)))
24+
setLikes((prev) => prev + (newLikedState ? 1 : -1))
25+
26+
if (newLikedState) {
27+
posthog?.capture('post_liked', {
28+
post_id: post.id,
29+
post_username: post.username,
30+
post_verified: post.verified,
31+
})
32+
} else {
33+
posthog?.capture('post_unliked', {
34+
post_id: post.id,
35+
post_username: post.username,
36+
post_verified: post.verified,
37+
})
38+
}
2339
}
2440

2541
return (
2642
<div className="bg-primary/5 border border-primary/20 rounded-lg p-4 mb-4">
2743
<div className="flex items-center gap-3 mb-3">
28-
<img
29-
src={post.avatar}
30-
alt={post.username}
31-
className="w-10 h-10 rounded-full"
32-
/>
44+
<img src={post.avatar} alt={post.username} className="w-10 h-10 rounded-full" />
3345
<div className="flex-1">
3446
<div className="flex items-center gap-2">
3547
<span className="font-bold text-primary">{post.username}</span>
@@ -47,21 +59,14 @@ export function PostCard({ post }: PostCardProps) {
4759

4860
{post.image && (
4961
<div className="mb-3 rounded-lg overflow-hidden">
50-
<img
51-
src={post.image}
52-
alt="Post"
53-
className="w-full h-auto"
54-
/>
62+
<img src={post.image} alt="Post" className="w-full h-auto" />
5563
</div>
5664
)}
5765

5866
<div className="flex items-center gap-6 text-primary/70">
5967
<button
6068
onClick={handleLike}
61-
className={cn(
62-
'flex items-center gap-2 hover:text-accent transition',
63-
liked && 'text-red-500'
64-
)}
69+
className={cn('flex items-center gap-2 hover:text-accent transition', liked && 'text-red-500')}
6570
>
6671
<span className="text-xl">{liked ? '❤️' : '🤍'}</span>
6772
<span className="text-sm">
@@ -84,4 +89,3 @@ export function PostCard({ post }: PostCardProps) {
8489
</div>
8590
)
8691
}
87-

apps/react-router/rrv7-starter/app/components/StatCard.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,7 @@ export function StatCard({ metric }: StatCardProps) {
1515
{metric.value.toLocaleString()}
1616
{metric.unit && <span className="text-lg ml-1">{metric.unit}</span>}
1717
</div>
18-
<div
19-
className={cn(
20-
'text-sm flex items-center gap-1',
21-
isPositive ? 'text-green-500' : 'text-red-500'
22-
)}
23-
>
18+
<div className={cn('text-sm flex items-center gap-1', isPositive ? 'text-green-500' : 'text-red-500')}>
2419
<span>{isPositive ? '↑' : '↓'}</span>
2520
<span>
2621
{Math.abs(metric.change).toLocaleString()}
@@ -31,4 +26,3 @@ export function StatCard({ metric }: StatCardProps) {
3126
</div>
3227
)
3328
}
34-

apps/react-router/rrv7-starter/app/components/header.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { useState, useEffect } from 'react'
22
import { Link } from 'react-router'
3+
import { usePostHog } from '@posthog/react'
34
import { fakeUser } from '@/lib/data/fake-data'
45
import { getFollowers } from '@/lib/utils/localStorage'
56

67
export const Header = () => {
8+
const posthog = usePostHog()
79
const [followers, setFollowers] = useState(fakeUser.followers)
810

911
useEffect(() => {
@@ -23,6 +25,13 @@ export const Header = () => {
2325
}
2426
}, [])
2527

28+
const handleBuyFollowersClick = () => {
29+
posthog?.capture('buy_followers_header_clicked', {
30+
current_followers: followers,
31+
location: 'header',
32+
})
33+
}
34+
2635
return (
2736
<header className="fixed top-0 z-50 w-full items-center justify-between grid grid-cols-3 p-2 px-4 md:py-4 h-header bg-background/80 backdrop-blur-sm border-b border-primary/10">
2837
<div className="gap-3 contents">
@@ -32,16 +41,24 @@ export const Header = () => {
3241
<nav className="flex items-center justify-center md:justify-self-center">
3342
<ul className="flex items-center gap-3 md:gap-6 font-mono uppercase text-sm">
3443
<li>
35-
<Link to="/" className="hover:text-accent transition">Home</Link>
44+
<Link to="/" className="hover:text-accent transition">
45+
Home
46+
</Link>
3647
</li>
3748
<li>
38-
<Link to="/feed" className="hover:text-accent transition">Feed</Link>
49+
<Link to="/feed" className="hover:text-accent transition">
50+
Feed
51+
</Link>
3952
</li>
4053
<li>
41-
<Link to="/profile" className="hover:text-accent transition">Profile</Link>
54+
<Link to="/profile" className="hover:text-accent transition">
55+
Profile
56+
</Link>
4257
</li>
4358
<li>
44-
<Link to="/analytics" className="hover:text-accent transition">Analytics</Link>
59+
<Link to="/analytics" className="hover:text-accent transition">
60+
Analytics
61+
</Link>
4562
</li>
4663
</ul>
4764
</nav>
@@ -54,16 +71,13 @@ export const Header = () => {
5471
</div>
5572
<Link
5673
to="/buy-followers"
74+
onClick={handleBuyFollowersClick}
5775
className="bg-accent text-primary font-bold px-4 py-2 rounded-lg text-sm hover:opacity-80 transition"
5876
>
5977
Buy Followers
6078
</Link>
6179
<Link to="/profile" className="flex items-center gap-2">
62-
<img
63-
src={fakeUser.avatar}
64-
alt={fakeUser.username}
65-
className="w-8 h-8 rounded-full border-2 border-accent"
66-
/>
80+
<img src={fakeUser.avatar} alt={fakeUser.username} className="w-8 h-8 rounded-full border-2 border-accent" />
6781
</Link>
6882
</div>
6983
</header>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { startTransition, StrictMode } from 'react'
2+
import { hydrateRoot } from 'react-dom/client'
3+
import { HydratedRouter } from 'react-router/dom'
4+
5+
import posthog from 'posthog-js'
6+
import { PostHogProvider } from '@posthog/react'
7+
8+
posthog.init(import.meta.env.VITE_PUBLIC_POSTHOG_KEY, {
9+
api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST,
10+
defaults: '2025-11-30',
11+
__add_tracing_headers: [window.location.host, 'localhost'],
12+
})
13+
14+
startTransition(() => {
15+
hydrateRoot(
16+
document,
17+
<PostHogProvider client={posthog}>
18+
<StrictMode>
19+
<HydratedRouter />
20+
</StrictMode>
21+
</PostHogProvider>
22+
)
23+
})
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState, useEffect } from 'react'
22

33
let hydrated = false
44

55
export const useHydrated = () => {
6-
const [, setIsHydrated] = useState(false);
6+
const [, setIsHydrated] = useState(false)
77

88
useEffect(() => {
99
if (!hydrated) {
10-
hydrated = true;
11-
setIsHydrated(true);
10+
hydrated = true
11+
setIsHydrated(true)
1212
}
13-
}, []);
13+
}, [])
1414

15-
return hydrated;
16-
};
15+
return hydrated
16+
}

apps/react-router/rrv7-starter/app/lib/data/fake-data.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export const fakePosts: FakePost[] = [
8888
id: '4',
8989
username: 'travel_fake',
9090
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=travel',
91-
content: 'Living my best life in Bali! (Stock photo, I\'m actually at home) 🌴 #travel #wanderlust #fake',
91+
content: "Living my best life in Bali! (Stock photo, I'm actually at home) 🌴 #travel #wanderlust #fake",
9292
image: 'https://picsum.photos/800/600?random=4',
9393
likes: 156000,
9494
comments: 5600,
@@ -145,4 +145,3 @@ export const followerPackages = [
145145
{ amount: 50000, price: 299.99, bonus: 15000 },
146146
{ amount: 100000, price: 499.99, bonus: 50000 },
147147
]
148-

apps/react-router/rrv7-starter/app/lib/utils/localStorage.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ export function toggleLikedPost(postId: string): boolean {
1818
if (typeof window === 'undefined') return false
1919
const liked = getLikedPosts()
2020
const isLiked = liked.has(postId)
21-
21+
2222
if (isLiked) {
2323
liked.delete(postId)
2424
} else {
2525
liked.add(postId)
2626
}
27-
27+
2828
localStorage.setItem(STORAGE_KEYS.LIKED_POSTS, JSON.stringify(Array.from(liked)))
2929
return !isLiked
3030
}
@@ -82,4 +82,3 @@ export function setPosts(count: number): void {
8282
if (typeof window === 'undefined') return
8383
localStorage.setItem(STORAGE_KEYS.POSTS, count.toString())
8484
}
85-

apps/react-router/rrv7-starter/app/root.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
useOutlet,
99
type MetaFunction,
1010
} from 'react-router'
11+
import { usePostHog } from '@posthog/react'
1112
import gsap from 'gsap'
1213

1314
import type { Route } from './+types/root'
@@ -136,6 +137,9 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
136137
let details = 'An unexpected error occurred.'
137138
let stack: string | undefined
138139

140+
const posthog = usePostHog()
141+
posthog?.captureException(error)
142+
139143
if (isRouteErrorResponse(error)) {
140144
message = error.status === 404 ? '404' : 'Error'
141145
details = error.status === 404 ? 'The requested page could not be found.' : error.statusText || details

apps/react-router/rrv7-starter/app/routes/analytics.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ export default function Analytics() {
4848
<div className="container mx-auto px-4 py-8 max-w-6xl">
4949
<div className="mb-6">
5050
<h1 className="text-4xl font-bold text-primary mb-2">Analytics Dashboard</h1>
51-
<p className="text-primary/50">
52-
All your metrics are fake, but they look real! 📊
53-
</p>
51+
<p className="text-primary/50">All your metrics are fake, but they look real! 📊</p>
5452
{purchasedFollowers > 0 && (
5553
<p className="text-accent mt-2">
5654
You've purchased {purchasedFollowers.toLocaleString()} fake followers! (Saved in localStorage)
@@ -64,9 +62,8 @@ export default function Analytics() {
6462
<div>
6563
<h2 className="text-xl font-bold text-primary">Disclaimer</h2>
6664
<p className="text-primary/70 text-sm">
67-
All metrics shown are completely fake and generated randomly.
68-
Any resemblance to real engagement is purely coincidental.
69-
(But your follower count is saved in localStorage!)
65+
All metrics shown are completely fake and generated randomly. Any resemblance to real engagement is
66+
purely coincidental. (But your follower count is saved in localStorage!)
7067
</p>
7168
</div>
7269
</div>
@@ -83,9 +80,7 @@ export default function Analytics() {
8380
<div className="bg-background border border-primary/10 rounded-lg p-8 h-64 flex items-center justify-center">
8481
<div className="text-center">
8582
<div className="text-6xl mb-4">📊</div>
86-
<p className="text-primary/50">
87-
This chart would show your fake engagement over time
88-
</p>
83+
<p className="text-primary/50">This chart would show your fake engagement over time</p>
8984
<p className="text-primary/30 text-sm mt-2">
9085
(If we had time to build it, which we don't, because it's fake)
9186
</p>
@@ -96,4 +91,3 @@ export default function Analytics() {
9691
</div>
9792
)
9893
}
99-

0 commit comments

Comments
 (0)