Files
sapiens-web3/client/src/components/Header.tsx
kimjaehyeon0101 325101fd26 Align header and footer elements for better visual consistency
Adjust negative margins on logo links in Header and Footer components to visually align elements with adjacent text and icons.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 930e9607-8d85-4ad9-8702-a48ff4cef074
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/930e9607-8d85-4ad9-8702-a48ff4cef074/cYvjJgC
2025-10-15 10:59:12 +00:00

133 lines
4.2 KiB
TypeScript

import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Search, Settings, User, LogOut } from "lucide-react";
import { useAuth } from "@/hooks/useAuth";
import { useToast } from "@/hooks/use-toast";
import { queryClient } from "@/lib/queryClient";
import LoginModal from "@/components/LoginModal";
export default function Header() {
const { user, isAuthenticated } = useAuth();
const { toast } = useToast();
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
const handleAdminPage = () => {
window.location.href = "/admin";
};
const handleLogout = async () => {
try {
const response = await fetch("/api/logout", {
method: "POST",
credentials: "include",
});
if (response.ok) {
toast({
title: "로그아웃 성공",
description: "안전하게 로그아웃되었습니다.",
});
// Invalidate all auth-related queries
queryClient.invalidateQueries({ queryKey: ["/api/auth/user"] });
// Redirect to home
window.location.href = "/";
} else {
throw new Error("로그아웃 실패");
}
} catch (error) {
toast({
title: "로그아웃 오류",
description: "로그아웃 중 오류가 발생했습니다.",
variant: "destructive",
});
}
};
return (
<>
<header className="bg-white border-b border-gray-200 sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-4 py-4">
<div className="flex items-center justify-between">
<div className="flex items-center">
<a href="/" data-testid="logo-link" className="-ml-2">
<img
src="/attached_assets/sapiens_black_logo.png"
alt="SAPIENS"
className="h-8 w-auto"
data-testid="logo-sapiens"
/>
</a>
</div>
<div className="flex items-center space-x-4">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
<Input
type="text"
placeholder="Search the website"
className="w-80 pl-10 bg-gray-50 border-gray-200"
data-testid="input-search"
/>
</div>
{isAuthenticated && user ? (
<>
<Button
variant="ghost"
size="sm"
onClick={handleAdminPage}
data-testid="button-admin-dashboard"
>
Admin Dashboard
</Button>
<div className="flex items-center space-x-2 px-3 py-1 bg-gray-100 rounded-md">
<User className="h-4 w-4 text-gray-600" />
<span className="text-sm font-medium text-gray-700" data-testid="user-name">
{user.firstName} {user.lastName}
</span>
</div>
<Button
variant="ghost"
size="sm"
onClick={handleLogout}
data-testid="button-logout"
>
<LogOut className="h-4 w-4" />
</Button>
</>
) : (
<Button
variant="ghost"
size="sm"
onClick={() => setIsLoginModalOpen(true)}
data-testid="button-login"
>
Login
</Button>
)}
<Button
variant="ghost"
size="sm"
data-testid="button-settings"
>
<Settings className="h-4 w-4" />
</Button>
</div>
</div>
</div>
</header>
{/* Login Modal */}
<LoginModal
isOpen={isLoginModalOpen}
onClose={() => setIsLoginModalOpen(false)}
/>
</>
);
}