Files
inbox-negotiator/src/components/Navbar.tsx
Francisco Pessano 0d2ab87519 feat: enhance Navbar with user profile and configuration links
- Updated Navbar component to include a link to the configuration page.
- Added a new Settings icon and link for user configuration.
- Improved user session handling and UI updates based on authentication state.

feat: implement OnboardingDialog for user setup

- Created OnboardingDialog component to guide users through initial setup.
- Added functionality to collect additional email addresses during onboarding.
- Integrated toast notifications for error handling during email addition.

feat: extend Supabase admin functions for user management

- Added functions to retrieve user IDs and full user information by email.
- Implemented error handling and logging for database operations.

feat: update Supabase schema with new user features

- Created new tables: user_profiles, additional_emails, and email_processing_usage.
- Enabled Row Level Security (RLS) on new tables with appropriate policies.
- Added triggers and functions for automatic user profile creation and email usage tracking.

feat: create public users table for simplified access

- Established a public.users table to mirror relevant auth.users data.
- Implemented triggers to automatically populate public.users upon user creation.
- Set up RLS policies to restrict access to user data.

chore: add configuration files for Supabase local development

- Included .gitignore and config.toml for local Supabase setup.
- Configured email testing server and other development settings.

feat: add configuration page for user settings

- Created configuration.astro page to manage user settings.
- Integrated AuthGuard to protect the configuration route.
2025-06-07 04:37:03 -03:00

119 lines
3.5 KiB
TypeScript

import React, { useEffect, useState } from "react";
import { supabase } from "../lib/supabase";
import type { User } from "@supabase/supabase-js";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { BarChart3, LogOut, User as UserIcon, Settings } from "lucide-react";
import { ModeToggle } from "./ModeToggle";
export function Navbar() {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setUser(session?.user ?? null);
});
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user ?? null);
});
return () => subscription.unsubscribe();
}, []);
const handleSignOut = async () => {
await supabase.auth.signOut();
window.location.href = "/";
};
const getInitials = (email: string) => {
return email.substring(0, 2).toUpperCase();
};
return (
<nav className="border-b bg-white dark:bg-background">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
<div className="flex items-center gap-3">
<BarChart3 className="h-8 w-8 text-primary" />
<a
href={user ? "/dashboard" : "/"}
className="text-xl font-bold text-gray-900 dark:text-foreground"
>
InboxNegotiator
</a>
</div>
<div className="flex items-center gap-4">
<ModeToggle />
{user ? (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
className="relative h-8 w-8 rounded-full"
>
<Avatar className="h-8 w-8">
<AvatarFallback className="text-xs">
{getInitials(user.email || "")}
</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="end">
<div className="flex items-center justify-start gap-2 p-2">
<div className="flex flex-col space-y-1 leading-none">
<p className="font-medium text-sm">
{user.user_metadata?.full_name || "User"}
</p>
<p className="w-[200px] truncate text-xs text-muted-foreground">
{user.email}
</p>
</div>
</div>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<a href="/dashboard" className="flex items-center">
<UserIcon className="mr-2 h-4 w-4" />
Dashboard
</a>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<a href="/configuration" className="flex items-center">
<Settings className="mr-2 h-4 w-4" />
Configuration
</a>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleSignOut}>
<LogOut className="mr-2 h-4 w-4" />
Sign out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
) : (
<div className="flex items-center gap-2">
<Button variant="ghost" asChild>
<a href="/login">Sign In</a>
</Button>
<Button asChild>
<a href="/signup">Get Started</a>
</Button>
</div>
)}
</div>
</div>
</div>
</nav>
);
}