Skip to content

Commit 7b59727

Browse files
authored
Merge pull request #8 from truongnat/feat/todo-tanstack-rewrite
feat: rewrite as TanStack Todo App (beginner-friendly)
2 parents 6304a2f + b5b3e0f commit 7b59727

31 files changed

Lines changed: 194 additions & 6053 deletions

client/src/components/ConnectionStatus.tsx

Lines changed: 0 additions & 63 deletions
This file was deleted.

client/src/components/Navigation.tsx

Lines changed: 23 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,186 +1,40 @@
1-
import React from 'react'
2-
import { Link, useLocation } from '@tanstack/react-router'
1+
import { Link, useNavigate } from '@tanstack/react-router'
32
import { Button } from '@/components/ui/button'
4-
import { ArrowLeft, Home, User, LogOut } from 'lucide-react'
3+
import { CheckCircle, LogOut, User } from 'lucide-react'
54
import { useAuthStore } from '@/stores/authStore'
6-
import { useLogout } from '@/hooks/useAuth'
75

86
interface NavigationProps {
9-
showBackButton?: boolean
107
title?: string
11-
transparent?: boolean
128
}
139

14-
export function Navigation({ showBackButton = false, title, transparent = false }: NavigationProps) {
15-
const location = useLocation()
16-
const { isAuthenticated, user } = useAuthStore()
17-
const logoutMutation = useLogout()
18-
19-
const isActive = (path: string) => {
20-
return location.pathname === path
21-
}
10+
export function Navigation({ title = 'TanStack Todo' }: NavigationProps) {
11+
const { user, logout } = useAuthStore()
12+
const navigate = useNavigate()
2213

2314
const handleLogout = () => {
24-
logoutMutation.mutate()
15+
logout()
16+
navigate({ to: '/login' })
2517
}
2618

2719
return (
28-
<nav className={`${transparent ? 'bg-white/95 backdrop-blur-sm' : 'bg-white'} shadow-sm border-b sticky top-0 z-50`}>
29-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
30-
<div className="flex justify-between items-center h-16">
31-
<div className="flex items-center">
32-
{showBackButton && (
33-
<Link to="/" className="mr-4">
34-
<Button variant="ghost" size="sm">
35-
<ArrowLeft className="w-4 h-4 mr-2" />
36-
Back
37-
</Button>
38-
</Link>
39-
)}
40-
<div className="flex items-center">
41-
<div className="flex-shrink-0">
42-
<div className="w-8 h-8 bg-gradient-to-r from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
43-
<span className="text-white font-bold text-sm">MS</span>
44-
</div>
45-
</div>
46-
<div className="ml-3">
47-
<h1 className="text-xl font-semibold text-gray-900">
48-
{title || 'MERN Stack'}
49-
</h1>
50-
</div>
51-
</div>
52-
</div>
53-
54-
<div className="hidden md:block">
55-
<div className="ml-10 flex items-baseline space-x-4">
56-
<Link
57-
to="/"
58-
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
59-
isActive('/')
60-
? 'text-blue-600 bg-blue-50'
61-
: 'text-gray-600 hover:text-blue-600'
62-
}`}
63-
>
64-
<Home className="w-4 h-4 inline mr-1" />
65-
Home
66-
</Link>
67-
<Link
68-
to="/todo"
69-
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
70-
isActive('/todo')
71-
? 'text-blue-600 bg-blue-50'
72-
: 'text-gray-600 hover:text-blue-600'
73-
}`}
74-
>
75-
Todo
76-
</Link>
77-
<Link
78-
to="/chat"
79-
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
80-
isActive('/chat')
81-
? 'text-blue-600 bg-blue-50'
82-
: 'text-gray-600 hover:text-blue-600'
83-
}`}
84-
>
85-
Chat
86-
</Link>
87-
<Link
88-
to="/profile"
89-
className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${
90-
isActive('/profile')
91-
? 'text-blue-600 bg-blue-50'
92-
: 'text-gray-600 hover:text-blue-600'
93-
}`}
94-
>
95-
Profile
96-
</Link>
20+
<nav className="bg-white border-b border-gray-200 px-4 py-3">
21+
<div className="max-w-2xl mx-auto flex items-center justify-between">
22+
<Link to="/" className="flex items-center gap-2 font-semibold text-gray-900 hover:text-indigo-600 transition-colors">
23+
<CheckCircle className="w-5 h-5 text-indigo-600" />
24+
{title}
25+
</Link>
26+
{user && (
27+
<div className="flex items-center gap-3">
28+
<div className="flex items-center gap-2 text-sm text-gray-600">
29+
<User className="w-4 h-4" />
30+
<span>{user.name}</span>
9731
</div>
32+
<Button variant="ghost" size="sm" onClick={handleLogout}>
33+
<LogOut className="w-4 h-4 mr-1" />
34+
Logout
35+
</Button>
9836
</div>
99-
100-
<div className="flex items-center space-x-4">
101-
{isAuthenticated ? (
102-
<div className="flex items-center space-x-3">
103-
<span className="text-sm text-gray-600">
104-
Welcome, {user?.name}
105-
</span>
106-
<Link to="/profile">
107-
<Button variant="outline" size="sm">
108-
<User className="w-4 h-4 mr-2" />
109-
Profile
110-
</Button>
111-
</Link>
112-
<Button
113-
variant="outline"
114-
size="sm"
115-
onClick={handleLogout}
116-
disabled={logoutMutation.isPending}
117-
>
118-
<LogOut className="w-4 h-4 mr-2" />
119-
{logoutMutation.isPending ? 'Signing Out...' : 'Sign Out'}
120-
</Button>
121-
</div>
122-
) : (
123-
<>
124-
<Link to="/login" search={{ redirect: '/' }}>
125-
<Button variant="outline" size="sm">
126-
Sign In
127-
</Button>
128-
</Link>
129-
<Link to="/register">
130-
<Button size="sm">
131-
Get Started
132-
</Button>
133-
</Link>
134-
</>
135-
)}
136-
</div>
137-
</div>
138-
</div>
139-
140-
{/* Mobile menu */}
141-
<div className="md:hidden">
142-
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3 border-t">
143-
<Link
144-
to="/"
145-
className={`block px-3 py-2 rounded-md text-base font-medium transition-colors ${
146-
isActive('/')
147-
? 'text-blue-600 bg-blue-50'
148-
: 'text-gray-600 hover:text-blue-600'
149-
}`}
150-
>
151-
Home
152-
</Link>
153-
<Link
154-
to="/todo"
155-
className={`block px-3 py-2 rounded-md text-base font-medium transition-colors ${
156-
isActive('/todo')
157-
? 'text-blue-600 bg-blue-50'
158-
: 'text-gray-600 hover:text-blue-600'
159-
}`}
160-
>
161-
Todo
162-
</Link>
163-
<Link
164-
to="/chat"
165-
className={`block px-3 py-2 rounded-md text-base font-medium transition-colors ${
166-
isActive('/chat')
167-
? 'text-blue-600 bg-blue-50'
168-
: 'text-gray-600 hover:text-blue-600'
169-
}`}
170-
>
171-
Chat
172-
</Link>
173-
<Link
174-
to="/profile"
175-
className={`block px-3 py-2 rounded-md text-base font-medium transition-colors ${
176-
isActive('/profile')
177-
? 'text-blue-600 bg-blue-50'
178-
: 'text-gray-600 hover:text-blue-600'
179-
}`}
180-
>
181-
Profile
182-
</Link>
183-
</div>
37+
)}
18438
</div>
18539
</nav>
18640
)

0 commit comments

Comments
 (0)