feat(hackathon): enhance dark mode, city select, and auth-aware navbar

- Apply rose-pine dark theme across all pages for darker appearance
- Update Button component with dark mode variants
- Replace basic city select with searchable CitySelect on create team page
- Show Dashboard button in navbar when user is authenticated
- Apply dark mode styling to onboarding, team pages, and user profile

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Maulana Sodiqin
2025-11-26 16:06:23 +07:00
co-authored by Claude
parent 62780c8889
commit 6e6c361eb8
11 changed files with 288 additions and 271 deletions
+34 -34
View File
@@ -14,26 +14,26 @@ const UserProfilePage: FC = (): ReactElement => {
if (isLoading) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-gray-600">Loading user profile...</div>
<div className="flex items-center justify-center min-h-screen bg-gray-50 dark:bg-neutral-950">
<div className="text-gray-600 dark:text-neutral-400">Loading user profile...</div>
</div>
);
}
if (error || !user) {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<h2 className="text-2xl font-bold text-gray-900 mb-4">User not found</h2>
{error && <p className="text-red-600 mb-4">{String(error)}</p>}
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-50 dark:bg-neutral-950">
<h2 className="text-2xl font-bold text-gray-900 dark:text-white mb-4">User not found</h2>
{error && <p className="text-red-600 dark:text-red-400 mb-4">{String(error)}</p>}
<Button onClick={() => navigate('/dashboard')}>Back to Dashboard</Button>
</div>
);
}
return (
<div className="min-h-screen bg-gray-50">
<div className="min-h-screen bg-gray-50 dark:bg-neutral-950">
{/* Header */}
<div className="bg-white border-b">
<div className="bg-white dark:bg-neutral-900 border-b dark:border-neutral-700">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 md:py-6">
<div className="flex items-start justify-between">
<div className="flex items-center space-x-3 md:space-x-4">
@@ -41,19 +41,19 @@ const UserProfilePage: FC = (): ReactElement => {
<img
src={user.avatar}
alt={user.fullname}
className="w-16 h-16 md:w-20 md:h-20 rounded-full object-cover border-4 border-white shadow-lg"
className="w-16 h-16 md:w-20 md:h-20 rounded-full object-cover border-4 border-white dark:border-neutral-800 shadow-lg"
/>
) : (
<div className="w-16 h-16 md:w-20 md:h-20 rounded-full bg-gray-200 flex items-center justify-center border-4 border-white shadow-lg">
<span className="text-gray-500 text-2xl md:text-3xl">👤</span>
<div className="w-16 h-16 md:w-20 md:h-20 rounded-full bg-gray-200 dark:bg-neutral-700 flex items-center justify-center border-4 border-white dark:border-neutral-800 shadow-lg">
<span className="text-gray-500 dark:text-neutral-400 text-2xl md:text-3xl">👤</span>
</div>
)}
<div>
<h1 className="text-xl md:text-3xl font-bold text-gray-900">{user.fullname}</h1>
<p className="text-sm md:text-base text-gray-600 mt-1">{user.email}</p>
<h1 className="text-xl md:text-3xl font-bold text-gray-900 dark:text-white">{user.fullname}</h1>
<p className="text-sm md:text-base text-gray-600 dark:text-neutral-400 mt-1">{user.email}</p>
{user.location && (
<div className="flex items-center space-x-4 mt-2">
<span className="text-sm text-gray-500">📍 {user.location}</span>
<span className="text-sm text-gray-500 dark:text-neutral-500">📍 {user.location}</span>
</div>
)}
</div>
@@ -71,21 +71,21 @@ const UserProfilePage: FC = (): ReactElement => {
<div className="lg:col-span-2 space-y-4 md:space-y-6">
{/* About Section */}
{user.bio && (
<div className="bg-white rounded-lg shadow-md p-4 md:p-6 overflow-hidden">
<h2 className="text-lg md:text-xl font-bold text-gray-900 mb-3 md:mb-4">About</h2>
<p className="text-gray-700 break-all overflow-wrap-anywhere">{user.bio}</p>
<div className="bg-white dark:bg-neutral-900 rounded-lg shadow-md dark:shadow-neutral-950/50 p-4 md:p-6 overflow-hidden">
<h2 className="text-lg md:text-xl font-bold text-gray-900 dark:text-white mb-3 md:mb-4">About</h2>
<p className="text-gray-700 dark:text-neutral-300 break-all overflow-wrap-anywhere">{user.bio}</p>
</div>
)}
{/* Skills Section */}
{user.skills && user.skills.length > 0 && (
<div className="bg-white rounded-lg shadow-md p-4 md:p-6">
<h2 className="text-lg md:text-xl font-bold text-gray-900 mb-3 md:mb-4">Skills</h2>
<div className="bg-white dark:bg-neutral-900 rounded-lg shadow-md dark:shadow-neutral-950/50 p-4 md:p-6">
<h2 className="text-lg md:text-xl font-bold text-gray-900 dark:text-white mb-3 md:mb-4">Skills</h2>
<div className="flex flex-wrap gap-3">
{user.skills.map((skill: string) => (
<span
key={skill}
className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium shadow-sm hover:bg-blue-700 transition-colors"
className="inline-flex items-center px-4 py-2 bg-blue-600 dark:bg-primary-600 text-white rounded-lg text-sm font-medium shadow-sm hover:bg-blue-700 dark:hover:bg-primary-700 transition-colors"
>
{skill}
</span>
@@ -96,35 +96,35 @@ const UserProfilePage: FC = (): ReactElement => {
{/* Teams Section */}
{userTeams.length > 0 ? (
<div className="bg-white rounded-lg shadow-md p-4 md:p-6">
<h2 className="text-lg md:text-xl font-bold text-gray-900 mb-3 md:mb-4">Teams ({userTeams.length})</h2>
<div className="bg-white dark:bg-neutral-900 rounded-lg shadow-md dark:shadow-neutral-950/50 p-4 md:p-6">
<h2 className="text-lg md:text-xl font-bold text-gray-900 dark:text-white mb-3 md:mb-4">Teams ({userTeams.length})</h2>
<div className="grid gap-4 md:grid-cols-2">
{userTeams.map((team: any) => (
<Link key={team.id} to={'/teams/' + team.id} className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow">
<Link key={team.id} to={'/teams/' + team.id} className="bg-white dark:bg-neutral-800 rounded-lg shadow-md dark:shadow-neutral-950/50 overflow-hidden hover:shadow-lg transition-shadow">
<img src={team.banner || '/images/banner-imphnen.png'} alt={team.name} className="w-full h-24 object-cover" />
<div className="p-4">
<div className="flex items-center space-x-3 mb-2">
{team.logo && <img src={team.logo} alt={team.name} className="w-10 h-10 rounded-full object-cover" />}
<div className="flex-1 min-w-0">
<h3 className="font-bold text-gray-900 line-clamp-2">{team.name}</h3>
<div className="text-sm text-gray-600 flex gap-2">
<h3 className="font-bold text-gray-900 dark:text-white line-clamp-2">{team.name}</h3>
<div className="text-sm text-gray-600 dark:text-neutral-400 flex gap-2">
<p className="truncate flex-1 min-w-0">📍 {team.city}</p>
<p className="whitespace-nowrap shrink-0">👥 {team.members?.length || 0} members</p>
</div>
</div>
</div>
<p className="text-gray-600 text-sm line-clamp-2">{team.description}</p>
<p className="text-gray-600 dark:text-neutral-400 text-sm line-clamp-2">{team.description}</p>
</div>
</Link>
))}
</div>
</div>
) : (
<div className="bg-white rounded-lg shadow-md p-4 md:p-6">
<h2 className="text-lg md:text-xl font-bold text-gray-900 mb-3 md:mb-4">Teams</h2>
<div className="bg-white dark:bg-neutral-900 rounded-lg shadow-md dark:shadow-neutral-950/50 p-4 md:p-6">
<h2 className="text-lg md:text-xl font-bold text-gray-900 dark:text-white mb-3 md:mb-4">Teams</h2>
<div className="text-center py-8">
<div className="text-4xl mb-3">👥</div>
<p className="text-gray-600">Not in any team yet</p>
<p className="text-gray-600 dark:text-neutral-400">Not in any team yet</p>
</div>
</div>
)}
@@ -133,17 +133,17 @@ const UserProfilePage: FC = (): ReactElement => {
{/* Sidebar */}
<div className="space-y-4 md:space-y-6">
{/* Contact Info */}
<div className="bg-white rounded-lg shadow-md p-4 md:p-6">
<h3 className="text-base md:text-lg font-bold text-gray-900 mb-3 md:mb-4">Contact Information</h3>
<div className="bg-white dark:bg-neutral-900 rounded-lg shadow-md dark:shadow-neutral-950/50 p-4 md:p-6">
<h3 className="text-base md:text-lg font-bold text-gray-900 dark:text-white mb-3 md:mb-4">Contact Information</h3>
<div className="space-y-3">
<div>
<p className="text-sm text-gray-600">Email</p>
<p className="text-gray-900 font-medium">{user.email}</p>
<p className="text-sm text-gray-600 dark:text-neutral-400">Email</p>
<p className="text-gray-900 dark:text-white font-medium">{user.email}</p>
</div>
{user.location && (
<div>
<p className="text-sm text-gray-600">Location</p>
<p className="text-gray-900 font-medium">{user.location}</p>
<p className="text-sm text-gray-600 dark:text-neutral-400">Location</p>
<p className="text-gray-900 dark:text-white font-medium">{user.location}</p>
</div>
)}
</div>