Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 사용자 프로필 이미지 없는 경우 기본값 대응 #232

Merged
merged 2 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDropdown } from '@boolti/ui';
import Styled from './HostListItem.styles';
import { HostListItem as IHostListItem, HostType, HostTypeInfo } from '@boolti/api/src/types/host';
import { CheckIcon, ChevronDownIcon } from '@boolti/icon';
import { CheckIcon, ChevronDownIcon, UserIcon } from '@boolti/icon';
import { useAtom } from 'jotai';
import { myHostInfoAtom } from '~/components/ShowDetailLayout';

Expand All @@ -11,25 +11,6 @@ interface HostListItemProps {
onEdit: (host: IHostListItem, type: HostType) => void;
}

const ProfileSVG = () => (
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="18" cy="18" r="18" fill="#E7EAF2" />
<mask id="mask0_7956_29535" maskUnits="userSpaceOnUse" x="0" y="0" width="36" height="36">
<circle cx="18" cy="18" r="18" fill="#2E303A" />
</mask>
<g mask="url(#mask0_7956_29535)">
<path
d="M31.9496 36.9V32.85C31.9496 30.7017 31.0962 28.6415 29.5772 27.1224C28.0581 25.6034 25.9979 24.75 23.8496 24.75H11.6996C9.55136 24.75 7.49109 25.6034 5.97204 27.1224C4.453 28.6415 3.59961 30.7017 3.59961 32.85V36.9"
fill="#C8CCDC"
/>
<path
d="M17.9992 22.05C21.4786 22.05 24.2992 19.2294 24.2992 15.75C24.2992 12.2706 21.4786 9.45001 17.9992 9.45001C14.5198 9.45001 11.6992 12.2706 11.6992 15.75C11.6992 19.2294 14.5198 22.05 17.9992 22.05Z"
fill="#C8CCDC"
/>
</g>
</svg>
);

const dropdownItems: HostTypeInfo[] = [
{
type: HostType.MANAGER,
Expand Down Expand Up @@ -80,11 +61,7 @@ const HostListItem = ({ host, onEdit, onDelete }: HostListItemProps) => {
return (
<Styled.HostListItem key={host.hostId}>
<Styled.HostInfoWrapper>
{host.imagePath ? (
<Styled.HostImage src={host.imagePath} alt="host image" />
) : (
<ProfileSVG />
)}
{host.imagePath ? <Styled.HostImage src={host.imagePath} alt="host image" /> : <UserIcon />}
<Styled.HostName>{host.hostName}</Styled.HostName>
{host.self && <Styled.HostSelfLabel>(나)</Styled.HostSelfLabel>}
</Styled.HostInfoWrapper>
Expand Down
24 changes: 2 additions & 22 deletions apps/admin/src/components/ProfileDropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { queryKeys, useLogout, useQueryClient } from '@boolti/api';
import { ChevronDownIcon, ChevronUpIcon, LogoutIcon, SettingIcon } from '@boolti/icon';
import { ChevronDownIcon, ChevronUpIcon, LogoutIcon, SettingIcon, UserIcon } from '@boolti/icon';
import { useConfirm, useDialog, useDropdown } from '@boolti/ui/src/hooks';
import { useNavigate } from 'react-router-dom';

Expand All @@ -16,26 +16,6 @@ interface ProfileDropdownProps {
onClick?: () => void;
}

// TODO: UserProfile svg 공통화
const ProfileSVG = () => (
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="18" cy="18" r="18" fill="#E7EAF2" />
<mask id="mask0_7956_29535" maskUnits="userSpaceOnUse" x="0" y="0" width="36" height="36">
<circle cx="18" cy="18" r="18" fill="#2E303A" />
</mask>
<g mask="url(#mask0_7956_29535)">
<path
d="M31.9496 36.9V32.85C31.9496 30.7017 31.0962 28.6415 29.5772 27.1224C28.0581 25.6034 25.9979 24.75 23.8496 24.75H11.6996C9.55136 24.75 7.49109 25.6034 5.97204 27.1224C4.453 28.6415 3.59961 30.7017 3.59961 32.85V36.9"
fill="#C8CCDC"
/>
<path
d="M17.9992 22.05C21.4786 22.05 24.2992 19.2294 24.2992 15.75C24.2992 12.2706 21.4786 9.45001 17.9992 9.45001C14.5198 9.45001 11.6992 12.2706 11.6992 15.75C11.6992 19.2294 14.5198 22.05 17.9992 22.05Z"
fill="#C8CCDC"
/>
</g>
</svg>
);

const ProfileDropdown = ({ image, open, disabledDropdown, onClick }: ProfileDropdownProps) => {
const { isOpen, toggleDropdown } = useDropdown();
const { removeToken } = useAuthAtom();
Expand All @@ -58,7 +38,7 @@ const ProfileDropdown = ({ image, open, disabledDropdown, onClick }: ProfileDrop
}}
>
<Styled.UserProfileImageWrapper>
{image ? <Styled.UserProfileImage src={image} alt="유저 프로필 이미지" /> : <ProfileSVG />}
{image ? <Styled.UserProfileImage src={image} alt="유저 프로필 이미지" /> : <UserIcon />}
</Styled.UserProfileImageWrapper>
<Styled.UserProfileIconWrapper className="icon-wrapper">
{dropdownOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
Expand Down
12 changes: 8 additions & 4 deletions apps/admin/src/components/ShowCastInfo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDialog } from '@boolti/ui';

import Styled from './ShowCastInfo.styles';
import { EditIcon, ChevronDownIcon, ChevronUpIcon } from '@boolti/icon';
import { EditIcon, ChevronDownIcon, ChevronUpIcon, UserIcon } from '@boolti/icon';
import { useState } from 'react';
import ShowCastInfoFormDialogContent, {
TempShowCastInfoFormInput,
Expand Down Expand Up @@ -71,9 +71,13 @@ const ShowCastInfo = ({ showCastInfo, onSave, onDelete }: Props) => {
>
{members.map((member) => (
<Styled.CastItem key={member.id}>
<Styled.UserImage
style={{ '--imgPath': `url(${member.userImgPath})` } as React.CSSProperties}
/>
{member.userImgPath ? (
<Styled.UserImage
style={{ '--imgPath': `url(${member.userImgPath})` } as React.CSSProperties}
/>
) : (
<UserIcon size={32} />
)}
<Styled.Username>{member.userNickname}</Styled.Username>
<Styled.Rolename>({member.roleName})</Styled.Rolename>
</Styled.CastItem>
Expand Down
33 changes: 17 additions & 16 deletions apps/admin/src/components/ShowCastInfoFormDialogContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Controller, useFieldArray, useForm } from 'react-hook-form';
import Styled from './ShowCastInfoFormDialogContent.styles';
import { useState } from 'react';
import { useBodyScrollLock } from '~/hooks/useBodyScrollLock';
import { ClearIcon, PlusIcon, TrashIcon } from '@boolti/icon';
import { ClearIcon, PlusIcon, TrashIcon, UserIcon } from '@boolti/icon';
import { Member, queryKeys, useQueryClient } from '@boolti/api';
import { replaceUserCode } from '~/utils/replace';

Expand Down Expand Up @@ -61,9 +61,9 @@ const ShowCastInfoFormDialogContent = ({ onDelete, prevShowCastInfo, onSave }: P
!getValues('name') ||
((memberFieldState.isDirty || memberFieldState.isTouched) &&
controlledFields.some(
({ userImgPath, userNickname, roleName }, index) =>
({ userNickname, roleName }, index) =>
(isMemberFieldBlurred[index].roleName || isMemberFieldBlurred[index].userCode) &&
(!userImgPath || !userNickname || !roleName),
(!userNickname || !roleName),
));

return (
Expand Down Expand Up @@ -102,22 +102,24 @@ const ShowCastInfoFormDialogContent = ({ onDelete, prevShowCastInfo, onSave }: P
render={({ field: { onChange, onBlur } }) => {
const value = field.userCode;
const isError = Boolean(
isMemberFieldBlurred[index].userCode
? !value || !field.userImgPath || !field.userNickname
: false,
isMemberFieldBlurred[index].userCode ? !value || !field.userNickname : false,
);
return (
<Styled.FieldWrap>
<Styled.InputWrapper isError={isError}>
{field.userImgPath && field.userNickname ? (
{field.userNickname ? (
<>
<Styled.UserImage
style={
{
'--imgPath': `url(${field.userImgPath})`,
} as React.CSSProperties
}
/>
{field.userImgPath ? (
<Styled.UserImage
style={
{
'--imgPath': `url(${field.userImgPath})`,
} as React.CSSProperties
}
/>
) : (
<UserIcon size={32} />
)}
<Styled.Username>{field.userNickname}</Styled.Username>
<Styled.RemoveButton
onClick={() => {
Expand Down Expand Up @@ -278,8 +280,7 @@ const ShowCastInfoFormDialogContent = ({ onDelete, prevShowCastInfo, onSave }: P

const name = getValues('name');
const members = (getValues('members') ?? []).filter(
(member) =>
member.userImgPath && member.userNickname && member.roleName && member.userCode,
(member) => member.userNickname && member.roleName && member.userCode,
);

try {
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/types/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export interface UserProfileResponse {
/** 유저코드 (권한 부여 시) */
userCode: string;
/** 유저 프로필 이미지 경로 */
imgPath: string;
imgPath?: string;
/** 유저 소개 */
introduction: string;
/** 유저 링크 */
Expand Down
28 changes: 28 additions & 0 deletions packages/icon/src/components/User.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
interface Props {
size?: number;
}

export const User = ({ size = 36 }: Props) => (
<svg
width={size}
height={size}
viewBox="0 0 36 36"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="18" cy="18" r="18" fill="#E7EAF2" />
<mask id="mask0_7956_29535" maskUnits="userSpaceOnUse" x="0" y="0" width="36" height="36">
<circle cx="18" cy="18" r="18" fill="#2E303A" />
</mask>
<g mask="url(#mask0_7956_29535)">
<path
d="M31.9496 36.9V32.85C31.9496 30.7017 31.0962 28.6415 29.5772 27.1224C28.0581 25.6034 25.9979 24.75 23.8496 24.75H11.6996C9.55136 24.75 7.49109 25.6034 5.97204 27.1224C4.453 28.6415 3.59961 30.7017 3.59961 32.85V36.9"
fill="#C8CCDC"
/>
<path
d="M17.9992 22.05C21.4786 22.05 24.2992 19.2294 24.2992 15.75C24.2992 12.2706 21.4786 9.45001 17.9992 9.45001C14.5198 9.45001 11.6992 12.2706 11.6992 15.75C11.6992 19.2294 14.5198 22.05 17.9992 22.05Z"
fill="#C8CCDC"
/>
</g>
</svg>
);
3 changes: 2 additions & 1 deletion packages/icon/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { BooltiDark } from './BooltiDark';
import { BooltiGrey } from './BooltiGrey';
import { BooltiLightGrey } from './BooltiLightGrey';
import { BooltiSmall } from './BooltiSmall';
import { User } from './User';
import { Calendar } from './Calendar';
import { CB } from './CB';
import { Check } from './Check';
Expand Down Expand Up @@ -107,6 +108,7 @@ export {
ICBC,
Instagram as InstagramIcon,
JPMorgan,
User as UserIcon,
K,
KakaoBank,
Kakaotalk as KakaotalkIcon,
Expand Down Expand Up @@ -141,4 +143,3 @@ export {
Message as MessageIcon,
Discord as DiscordIcon,
};

Loading