Skip to content

Commit

Permalink
포지션 설명 토스트 구현 및 정보 입력 페이지 포지션 설명 추가 (#407)
Browse files Browse the repository at this point in the history
* feat: 포지션 뱃지 클릭 토스트 훅 작성

* feat: 로그인 페이지 클릭된 포지션 설명 추가

* feat: 정보입력 페이지 포지션 추가 설명 구현
  • Loading branch information
1g2g authored Nov 29, 2023
1 parent bd90a77 commit 58ded94
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 52 deletions.
35 changes: 26 additions & 9 deletions src/components/shared/ToggleButton/ToggleButtons.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,52 @@ type ToggleButtonsProps<T> = {
initialValues?: T[];
onToggle: (value: T[]) => void;
isMultipleSelect: boolean;
noValue?: T;
};

export const useToggleButtons = <T>({
initialValues = [] as T[],
isMultipleSelect,
onToggle,
noValue,
}: ToggleButtonsProps<T>) => {
const [selectedItem, setSelectedItem] = useState<T | null>(null);
const [selectedItems, setSelectedItems] = useState<T[]>(initialValues);

const handleToggle = (value: T) => {
if (!value) {
setSelectedItems([]);
onToggle([]);
setSelectedItem(null);
return;
}

const handleMultipleSelect = () => {
if (value === noValue) {
return [noValue];
}

if (selectedItems.includes(value)) {
return selectedItems.filter((item) => item !== value);
}

return [...selectedItems.filter((item) => item !== noValue), value];
};

const handleSingleSelect = () => (value === noValue ? [] : [value]);

const updatedItems = isMultipleSelect
? value === '없음'
? [value]
: selectedItems.includes(value)
? selectedItems.filter((item) => item !== value)
: [...selectedItems.filter((item) => item !== '없음'), value]
: value === '없음'
? []
: [value];
? handleMultipleSelect()
: handleSingleSelect();

setSelectedItems(updatedItems);
onToggle(updatedItems);
setSelectedItem((prev) =>
prev === value || selectedItems.find((item) => item === value)
? null
: value
);
};

return { handleToggle, selectedItems, setSelectedItems };
return { selectedItem, handleToggle, selectedItems, setSelectedItems };
};
11 changes: 8 additions & 3 deletions src/consts/positions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
export const POSITIONS_BUTTON = {
import { PositionInfo } from '@type/models/Position';

export const POSITIONS_BUTTON: Record<
PositionInfo['acronym'],
PositionInfo['acronym']
> = {
C: 'C',
PF: 'PF',
SF: 'SF',
PG: 'PG',
SG: 'SG',
없음: '',
} as const;
없음: '없음',
};
44 changes: 44 additions & 0 deletions src/hooks/usePositionToast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import toast from 'react-hot-toast';

import { Flex } from '@components/shared/Flex';
import { Text } from '@components/shared/Text';

import { usePositionsQuery } from '@hooks/queries/usePositionsQuery';

import { Position } from '@type/models/Position';

export const usePositionToast = () => {
const { data: positions } = usePositionsQuery();

const getClickedPosition = (myPosition: Position) => {
const positionInfo = positions.find(
(position) => position.acronym === myPosition
);

return positionInfo;
};

const handleClickPosition = (myPosition: Position) => {
const positionInfo = getClickedPosition(myPosition);

if (!positionInfo) {
return;
}

toast(
() => (
<Flex align="center">
<Flex direction="column" align="center">
<Text size={18} weight={700}>
{positionInfo.name}
</Text>
<Text>{positionInfo.description}</Text>
</Flex>
</Flex>
),
{ position: 'bottom-center' }
);
};

return { getClickedPosition, handleClickPosition };
};
40 changes: 6 additions & 34 deletions src/pages/ProfilePage/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,29 @@ import toast from 'react-hot-toast';
import { useNavigate } from 'react-router-dom';

import { Avatar } from '@components/Avatar';
import { Modal } from '@components/Modal';
import { Button } from '@components/shared/Button';
import { Flex } from '@components/shared/Flex';
import { Image } from '@components/shared/Image';
import { Text } from '@components/shared/Text';

import { useMemberProfileQuery } from '@hooks/queries/useMemberProfileQuery';
import { usePositionsQuery } from '@hooks/queries/usePositionsQuery';
import { useChatOnButtonClick } from '@hooks/useChatOnButtonClick';
import { usePositionToast } from '@hooks/usePositionToast';

import { theme } from '@styles/theme';

import { useLoginInfoStore } from '@stores/loginInfo.store';

import { Member } from '@type/models';
import { Position, PositionInfo } from '@type/models/Position';
import { PositionInfo } from '@type/models/Position';

import { PATH_NAME } from '@consts/pathName';

import Social from '@assets/follow.svg?react';
import HandHeart from '@assets/handHeart.svg?react';
import Heart from '@assets/heart.svg?react';

import { ModalItem, PointerFlex } from './ProfilePage.style';
import { PointerFlex } from './ProfilePage.style';
import {
ColoredSvgWrapper,
CrewGroup,
Expand Down Expand Up @@ -62,12 +61,9 @@ export const Profile = ({ memberId }: { memberId: Member['id'] }) => {
const navigate = useNavigate();

const { data: profile } = useMemberProfileQuery({ memberId });
const { data: positions } = usePositionsQuery();

const [isHeartClicked, setIsHeartClicked] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [clickedPositionInfo, setClickedPositionInfo] =
useState<PositionInfo | null>(null);
useState<PositionInfo | null>(null);

const handleClickHeart = () => {
setIsHeartClicked((prev: boolean) => !prev);
Expand All @@ -84,24 +80,12 @@ export const Profile = ({ memberId }: { memberId: Member['id'] }) => {
myId,
});

const handleClickPosition = (myPosition: Position) => {
const positionInfo = positions.find(
(position) => position.acronym === myPosition
);

if (!positionInfo) {
return;
}

setClickedPositionInfo(positionInfo);

setIsModalOpen(true);
};

const handleClickCrew = (id: Member['id']) => {
moveToPage(PATH_NAME.GET_CREWS_PATH(String(id)));
};

const { handleClickPosition } = usePositionToast();

return (
<Main>
<FlexItem>
Expand Down Expand Up @@ -190,18 +174,6 @@ export const Profile = ({ memberId }: { memberId: Member['id'] }) => {
<Introduce>{profile.introduction}</Introduce>
</ProfileField>
</FlexItem>
<Modal isOpen={isModalOpen} close={() => setIsModalOpen(false)}>
{clickedPositionInfo && (
<Modal.Content>
<ModalItem direction="column" align="center" gap={8}>
<Text size={24} weight={700}>
{clickedPositionInfo.name}
</Text>
<Text>{clickedPositionInfo.description}</Text>
</ModalItem>
</Modal.Content>
)}
</Modal>
</Main>
);
};
Expand Down
32 changes: 26 additions & 6 deletions src/pages/RegisterPage/RegisterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { LogoImage } from '@pages/LoginPage/LoginPage.style';
import { Header } from '@components/Header';
import { SelectBox } from '@components/SelectBox';
import { Button } from '@components/shared/Button';
import { Flex } from '@components/shared/Flex';
import { Text } from '@components/shared/Text';
import {
ToggleButton,
Expand All @@ -15,17 +16,17 @@ import {

import { useRegistrationMutation } from '@hooks/mutations/useRegistrationMutation';
import { useLocationsQuery } from '@hooks/queries/useLocationsQuery';
import { usePositionToast } from '@hooks/usePositionToast';

import { theme } from '@styles/theme';

import { Position } from '@type/models/Position';
import { Position, PositionInfo } from '@type/models/Position';

import { PATH_NAME } from '@consts/pathName';
import { POSITIONS_BUTTON } from '@consts/positions';

import LOGO_SRC from '@assets/logoSvg.svg';

// 1번 라인
import {
FieldContainer,
Main,
Expand All @@ -34,6 +35,8 @@ import {
ScrollBox,
} from './RegisterPage.style';

type Acronym = PositionInfo['acronym'];

export const RegisterPage = () => {
const navigate = useNavigate();

Expand All @@ -45,7 +48,7 @@ export const RegisterPage = () => {
}

const [selectedLocation, setSelectedLocation] = useState<string[]>();
const [selectedPosition, setSelectedPosition] = useState<string[]>();
const [selectedPosition, setSelectedPosition] = useState<Acronym[]>();

const {
handleToggle: handleToggleLocation,
Expand All @@ -58,11 +61,15 @@ export const RegisterPage = () => {
const {
handleToggle: handleTogglePosition,
selectedItems: selectedPositions,
selectedItem: selectedPositionItem,
} = useToggleButtons({
onToggle: setSelectedPosition,
isMultipleSelect: true,
noValue: POSITIONS_BUTTON['없음'],
});

const { getClickedPosition } = usePositionToast();

const { mutate } = useRegistrationMutation();
const { data: resLocations } = useLocationsQuery();
const locations = resLocations.addressDepth2List;
Expand All @@ -88,6 +95,10 @@ export const RegisterPage = () => {

navigate(PATH_NAME.MAIN);
};

const positionInfo =
selectedPositionItem && getClickedPosition(selectedPositionItem);

return (
<RegisterContainer>
<Header isLogo={false} title="정보 입력" isRightContainer={false} />
Expand Down Expand Up @@ -116,16 +127,25 @@ export const RegisterPage = () => {
주 포지션
</Text>
<PositionButtonGroup>
{Object.entries(POSITIONS_BUTTON).map(([position, value]) => (
{Object.values(POSITIONS_BUTTON).map((position) => (
<ToggleButton
key={position}
value={value}
value={position}
label={position}
isActive={selectedPositions.includes(position)}
onToggle={handleTogglePosition}
onToggle={() => handleTogglePosition(position)}
/>
))}
</PositionButtonGroup>
{positionInfo && (
<Flex>
<Text>{positionInfo.name}</Text>
<Text weight={300}>
{' : '}
{positionInfo.description}
</Text>
</Flex>
)}
</FieldContainer>
<FieldContainer>
<Button
Expand Down

0 comments on commit 58ded94

Please sign in to comment.