Feat: 헤더에 유저 프로필 추가
This commit is contained in:
parent
fb718d0f9b
commit
9694787b3a
46
frontend/src/components/Header/UserProfileForm.tsx
Normal file
46
frontend/src/components/Header/UserProfileForm.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import { useState } from 'react';
|
||||
import { Button } from '../ui/button';
|
||||
import useAuthStore from '@/stores/useAuthStore';
|
||||
import useLogoutQuery from '@/queries/auth/useLogoutQuery';
|
||||
export default function UserProfileForm({ onClose }: { onClose: () => void }) {
|
||||
const profile = useAuthStore((state) => state.profile);
|
||||
const { nickname, profileImage } = profile || { nickname: '', profileImage: '' };
|
||||
|
||||
const logoutMutation = useLogoutQuery();
|
||||
const [isLoggingOut, setIsLoggingOut] = useState<boolean>(false);
|
||||
|
||||
const handleLogout = async () => {
|
||||
setIsLoggingOut(true);
|
||||
logoutMutation.mutate(undefined, {
|
||||
onSuccess: () => {
|
||||
onClose();
|
||||
},
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div className="flex flex-col gap-5">
|
||||
<div className="flex items-center gap-4">
|
||||
{profileImage ? (
|
||||
<img
|
||||
src={profileImage}
|
||||
alt={`${nickname}'s profile`}
|
||||
className="h-16 w-16 rounded-full"
|
||||
/>
|
||||
) : (
|
||||
<div className="h-16 w-16 rounded-full bg-gray-300"></div>
|
||||
)}
|
||||
|
||||
<div className="text-lg font-bold">{nickname || 'Guest'}</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleLogout}
|
||||
variant="outlinePrimary"
|
||||
className="mt-4"
|
||||
disabled={isLoggingOut}
|
||||
>
|
||||
{isLoggingOut ? '로그아웃 중...' : '로그아웃'}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
31
frontend/src/components/Header/UserProfileModal.tsx
Normal file
31
frontend/src/components/Header/UserProfileModal.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../ui/dialogCustom';
|
||||
import { User } from 'lucide-react';
|
||||
import UserProfileForm from './UserProfileForm';
|
||||
|
||||
export default function UserProfileModal() {
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
|
||||
const handleOpen = () => setIsOpen(true);
|
||||
const handleClose = () => setIsOpen(false);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onOpenChange={setIsOpen}
|
||||
>
|
||||
<DialogTrigger asChild>
|
||||
<button
|
||||
className="flex items-center justify-center p-2"
|
||||
onClick={handleOpen}
|
||||
>
|
||||
<User className="h-4 w-4 text-black sm:h-5 sm:w-5" />
|
||||
</button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-sm">
|
||||
<DialogHeader title="프로필" />
|
||||
<UserProfileForm onClose={handleClose} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Bell, User } from 'lucide-react';
|
||||
import { Bell } from 'lucide-react';
|
||||
import { useLocation, Link, useParams } from 'react-router-dom';
|
||||
import UserProfileModal from './UserProfileModal';
|
||||
|
||||
export interface HeaderProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
@ -60,7 +61,7 @@ export default function Header({ className, ...props }: HeaderProps) {
|
||||
{!isHomePage && (
|
||||
<div className="flex items-center gap-4 md:gap-5">
|
||||
<Bell className="h-4 w-4 text-black sm:h-5 sm:w-5" />
|
||||
<User className="h-4 w-4 text-black sm:h-5 sm:w-5" />
|
||||
<UserProfileModal />
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
|
Loading…
Reference in New Issue
Block a user