Aymeric Rabot 62dde6ef5a feat: add Google OAuth, user profiles, community hub improvements
- Add Google OAuth sign-in alongside magic link authentication
- Username onboarding: require username selection after first sign-in
- Public profile pages at /u/[username] with social links (GitHub, X)
- Settings page for managing username and social links
- Viewer header: unified floating card with project name, @username, breadcrumb
- Guest CTA on viewer page prompting sign-in
- Show owner avatar + username on community project cards
- Redesigned project cards (larger preview, avatar + stats row below)
- Consistent navbar across hub and profile pages with GitHub link
- Footer with links to GitHub repo and npm packages
- Borderless design with natural shadows throughout
- Apple corner smoothing (squircle) progressive enhancement
- cursor:pointer globally on buttons and links
- DB migrations: username, github_url, x_url columns on auth_users
- Root-level db:generate/migrate/push/studio scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:04:37 -05:00

36 lines
934 B
TypeScript

'use client'
import { useEffect, useState } from 'react'
import { useAuth } from '../lib/auth/hooks'
import { getUsername } from '../lib/auth/actions'
import { UsernameOnboardingDialog } from './username-onboarding-dialog'
export function UsernameGate({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useAuth()
const [needsUsername, setNeedsUsername] = useState(false)
const [checking, setChecking] = useState(true)
useEffect(() => {
if (isLoading) return
if (!isAuthenticated) {
setChecking(false)
setNeedsUsername(false)
return
}
getUsername().then((username) => {
setNeedsUsername(!username)
setChecking(false)
})
}, [isAuthenticated, isLoading])
return (
<>
{children}
<UsernameOnboardingDialog
open={needsUsername && !checking}
onComplete={() => setNeedsUsername(false)}
/>
</>
)
}