Skip to content

Commit 2c53caf

Browse files
committed
feat: 로그인/로그아웃 아이콘 표시 개선
1 parent e0b534b commit 2c53caf

2 files changed

Lines changed: 44 additions & 19 deletions

File tree

apps/pyconkr-2026/src/components/layout/Header/Mobile/MobileNavigation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export const MobileNavigation: FC<MobileNavigationProps> = ({ isOpen, onClose, s
169169
<LanguageSelector />
170170
<Stack direction="row" alignItems="center">
171171
<CartBadgeButton onClose={handleClose} />
172-
<UserMenuButton onClose={handleClose} />
172+
<UserMenuButton onClose={handleClose} showLabel />
173173
</Stack>
174174
</Stack>
175175
</DrawerContent>

apps/pyconkr-2026/src/components/layout/UserMenuButton/index.tsx

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { UserSignInAccount, UserSignInMethod } from "@frontend/shop/components/c
22
import { useShopClient, useSignOutMutation, useUserStatus } from "@frontend/shop/hooks";
33
import { UserSignedInStatus } from "@frontend/shop/schemas";
44
import { AccountCircle, Login, Logout, Receipt } from "@mui/icons-material";
5-
import { Divider, IconButton, ListItemIcon, ListItemText, Menu, MenuItem, styled, Typography } from "@mui/material";
5+
import { Button, Divider, IconButton, ListItemIcon, ListItemText, Menu, MenuItem, styled, Typography } from "@mui/material";
66
import { ErrorBoundary, Suspense } from "@suspensive/react";
77
import { FC, MouseEvent, useState } from "react";
88
import { useNavigate } from "react-router-dom";
@@ -16,15 +16,32 @@ const ColoredIconButton = styled(IconButton)(({ theme }) => ({
1616
transition: "color 0.4s ease, background-color 0.4s ease",
1717
}));
1818

19-
type UserMenuButtonProps = { onClose?: () => void };
19+
const ColoredTextButton = styled(Button)(({ theme }) => ({
20+
color: theme.palette.primary.nonFocus,
21+
textTransform: "none",
22+
fontWeight: 500,
23+
maxWidth: "12rem",
24+
"& .MuiButton-startIcon": { marginRight: theme.spacing(0.75) },
25+
"&:hover": { color: theme.palette.primary.dark, backgroundColor: "transparent" },
26+
"&:active": { color: theme.palette.primary.main },
27+
transition: "color 0.4s ease, background-color 0.4s ease",
28+
}));
29+
30+
const LabelText = styled("span")({
31+
overflow: "hidden",
32+
textOverflow: "ellipsis",
33+
whiteSpace: "nowrap",
34+
});
35+
36+
type UserMenuButtonProps = { onClose?: () => void; showLabel?: boolean };
2037

2138
type InnerUserMenuButtonPropType = UserMenuButtonProps & {
2239
loading?: boolean;
2340
user?: UserSignedInStatus["data"]["user"];
2441
onSignOut?: () => void;
2542
};
2643

27-
const InnerUserMenuButton: FC<InnerUserMenuButtonPropType> = ({ loading, user, onSignOut, onClose }) => {
44+
const InnerUserMenuButton: FC<InnerUserMenuButtonPropType> = ({ loading, user, onSignOut, onClose, showLabel }) => {
2845
const navigate = useNavigate();
2946
const { language } = useAppContext();
3047
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
@@ -49,17 +66,25 @@ const InnerUserMenuButton: FC<InnerUserMenuButtonPropType> = ({ loading, user, o
4966
onSignOut?.();
5067
};
5168

69+
const triggerIcon = user ? <AccountCircle /> : <Login />;
70+
const triggerLabel = user ? user.display || user.email : signInLabel;
71+
const ariaProps = {
72+
"aria-controls": open ? "user-menu" : undefined,
73+
"aria-haspopup": "true" as const,
74+
"aria-expanded": open ? ("true" as const) : undefined,
75+
};
76+
5277
return (
5378
<>
54-
<ColoredIconButton
55-
loading={loading}
56-
onClick={handleOpen}
57-
aria-controls={open ? "user-menu" : undefined}
58-
aria-haspopup="true"
59-
aria-expanded={open ? "true" : undefined}
60-
>
61-
<AccountCircle />
62-
</ColoredIconButton>
79+
{showLabel ? (
80+
<ColoredTextButton loading={loading} onClick={handleOpen} startIcon={triggerIcon} {...ariaProps}>
81+
<LabelText>{triggerLabel}</LabelText>
82+
</ColoredTextButton>
83+
) : (
84+
<ColoredIconButton loading={loading} onClick={handleOpen} {...ariaProps}>
85+
{triggerIcon}
86+
</ColoredIconButton>
87+
)}
6388
<Menu
6489
id="user-menu"
6590
anchorEl={anchorEl}
@@ -103,18 +128,18 @@ const InnerUserMenuButton: FC<InnerUserMenuButtonPropType> = ({ loading, user, o
103128
);
104129
};
105130

106-
const UserMenuButtonContent: FC<UserMenuButtonProps> = ({ onClose }) => {
131+
const UserMenuButtonContent: FC<UserMenuButtonProps> = ({ onClose, showLabel }) => {
107132
const shopAPIClient = useShopClient();
108133
const signOutMutation = useSignOutMutation(shopAPIClient);
109134
const { data } = useUserStatus(shopAPIClient);
110135

111-
return <InnerUserMenuButton user={data?.data.user} onSignOut={signOutMutation.mutate} onClose={onClose} />;
136+
return <InnerUserMenuButton user={data?.data.user} onSignOut={signOutMutation.mutate} onClose={onClose} showLabel={showLabel} />;
112137
};
113138

114-
export const UserMenuButton: FC<UserMenuButtonProps> = ({ onClose }) => (
115-
<ErrorBoundary fallback={<InnerUserMenuButton onClose={onClose} />}>
116-
<Suspense fallback={<InnerUserMenuButton loading onClose={onClose} />}>
117-
<UserMenuButtonContent onClose={onClose} />
139+
export const UserMenuButton: FC<UserMenuButtonProps> = ({ onClose, showLabel }) => (
140+
<ErrorBoundary fallback={<InnerUserMenuButton onClose={onClose} showLabel={showLabel} />}>
141+
<Suspense fallback={<InnerUserMenuButton loading onClose={onClose} showLabel={showLabel} />}>
142+
<UserMenuButtonContent onClose={onClose} showLabel={showLabel} />
118143
</Suspense>
119144
</ErrorBoundary>
120145
);

0 commit comments

Comments
 (0)