+28
-1
public/editor/editor.tsx
+28
-1
public/editor/editor.tsx
···
21
21
import {
22
22
Globe,
23
23
Loader2,
24
-
Trash2
24
+
Trash2,
25
+
LogOut
25
26
} from 'lucide-react'
26
27
import Layout from '@public/layouts'
27
28
import { useUserInfo } from './hooks/useUserInfo'
···
156
157
await fetchSites()
157
158
}
158
159
160
+
const handleLogout = async () => {
161
+
try {
162
+
const response = await fetch('/api/auth/logout', {
163
+
method: 'POST',
164
+
credentials: 'include'
165
+
})
166
+
const result = await response.json()
167
+
if (result.success) {
168
+
// Redirect to home page after successful logout
169
+
window.location.href = '/'
170
+
} else {
171
+
alert('Logout failed: ' + (result.error || 'Unknown error'))
172
+
}
173
+
} catch (err) {
174
+
alert('Logout failed: ' + (err instanceof Error ? err.message : 'Unknown error'))
175
+
}
176
+
}
177
+
159
178
if (loading) {
160
179
return (
161
180
<div className="w-full min-h-screen bg-background flex items-center justify-center">
···
181
200
<span className="text-sm text-muted-foreground">
182
201
{userInfo?.handle || 'Loading...'}
183
202
</span>
203
+
<Button
204
+
variant="ghost"
205
+
size="sm"
206
+
onClick={handleLogout}
207
+
className="h-8 px-2"
208
+
>
209
+
<LogOut className="w-4 h-4" />
210
+
</Button>
184
211
</div>
185
212
</div>
186
213
</header>
+33
-1
public/index.tsx
+33
-1
public/index.tsx
···
16
16
17
17
function App() {
18
18
const [showForm, setShowForm] = useState(false)
19
+
const [checkingAuth, setCheckingAuth] = useState(true)
19
20
const inputRef = useRef<HTMLInputElement>(null)
20
21
21
22
useEffect(() => {
23
+
// Check authentication status on mount
24
+
const checkAuth = async () => {
25
+
try {
26
+
const response = await fetch('/api/auth/status', {
27
+
credentials: 'include'
28
+
})
29
+
const data = await response.json()
30
+
if (data.authenticated) {
31
+
// User is already authenticated, redirect to editor
32
+
window.location.href = '/editor'
33
+
return
34
+
}
35
+
} catch (error) {
36
+
console.error('Auth check failed:', error)
37
+
} finally {
38
+
setCheckingAuth(false)
39
+
}
40
+
}
41
+
42
+
checkAuth()
43
+
}, [])
44
+
45
+
useEffect(() => {
22
46
if (showForm) {
23
47
setTimeout(() => inputRef.current?.focus(), 500)
24
48
}
25
49
}, [showForm])
50
+
51
+
if (checkingAuth) {
52
+
return (
53
+
<div className="min-h-screen bg-background flex items-center justify-center">
54
+
<div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin"></div>
55
+
</div>
56
+
)
57
+
}
26
58
27
59
return (
28
60
<>
···
61
93
<div className="max-w-4xl mx-auto text-center">
62
94
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-accent/10 border border-accent/20 mb-8">
63
95
<span className="w-2 h-2 bg-accent rounded-full animate-pulse"></span>
64
-
<span className="text-sm text-accent-foreground">
96
+
<span className="text-sm text-foreground">
65
97
Built on AT Protocol
66
98
</span>
67
99
</div>