-
Notifications
You must be signed in to change notification settings - Fork 2
[feat] 마이페이지 좋아요 기능 연결 및 /mycd 라우팅 처리 #119
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
Changes from 5 commits
d412ce6
58a6eaa
f05d028
b6c6a98
e11ad5b
0fcd366
9f014ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import { useState } from 'react' | ||
| import { useNavigate } from 'react-router-dom' | ||
|
|
||
| import styled from 'styled-components' | ||
|
|
@@ -7,16 +8,49 @@ import { useMyLikedCdList } from '@/entities/playlist/model/useMyCd' | |
| import { CdNameInfo } from '@/pages/mypage/ui/main/components' | ||
| import { useSingleSelect } from '@/shared/lib/useSingleSelect' | ||
| import { flexColCenter } from '@/shared/styles/mixins' | ||
| import { Loading, Error, ContentHeader, Cd } from '@/shared/ui' | ||
| import { Loading, Error, ContentHeader, Modal } from '@/shared/ui' | ||
| import type { SortType } from '@/shared/ui/ContentHeader' | ||
| import type { ModalProps } from '@/shared/ui/Modal' | ||
| import { Playlist } from '@/widgets/playlist' | ||
|
|
||
| const MyLikedCdList = () => { | ||
| const navigate = useNavigate() | ||
|
|
||
| const { selected: currentSort, onSelect: setCurrentSort } = useSingleSelect<SortType>('POPULAR') | ||
| const [modal, setModal] = useState<ModalProps>({ | ||
| isOpen: false, | ||
| title: '', | ||
| description: '', | ||
| ctaType: 'single', | ||
| confirmText: '', | ||
| cancelText: '', | ||
| onClose: () => { | ||
| setModal((prev) => ({ ...prev, isOpen: false })) | ||
| }, | ||
| onConfirm: () => {}, | ||
| onCancel: () => { | ||
| setModal((prev) => ({ ...prev, isOpen: false })) | ||
| }, | ||
| }) | ||
|
|
||
| const { selected: currentSort, onSelect: setCurrentSort } = useSingleSelect<SortType>('POPULAR') | ||
| const { data: myLikedCdList, isLoading, isError, isSuccess } = useMyLikedCdList(currentSort) | ||
|
|
||
| const onLikedCdClick = (cdId: number, isPublic: boolean) => { | ||
| if (!cdId) return | ||
| if (!isPublic) { | ||
| setModal({ | ||
| isOpen: true, | ||
| title: '비공개된 CD는 재생할 수 없어요.', | ||
| ctaType: 'single', | ||
| confirmText: '확인', | ||
| onClose: () => setModal((p) => ({ ...p, isOpen: false })), | ||
| onConfirm: () => setModal((p) => ({ ...p, isOpen: false })), | ||
| }) | ||
| return | ||
| } | ||
| navigate(`/mypage/${cdId}/tracklist`) | ||
| } | ||
hansololiviakim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (isLoading) return <Loading isLoading={isLoading} /> | ||
| if (isError || !isSuccess) return <Error /> | ||
|
|
||
|
|
@@ -40,20 +74,37 @@ const MyLikedCdList = () => { | |
| ) : ( | ||
| myLikedCdList?.map((item) => ( | ||
| <li key={item.playlistId}> | ||
| {/* TODO: 나의CD 이동 후 좋아요한 CD 재생은 각 브랜치 병합 이후 작업 */} | ||
| <CdButton type="button" onClick={() => navigate('/mycd')}> | ||
| {/* TODO: CD 컴포넌트 좋아요는 각 브랜치 병합 이후 작업 (10/20~) */} | ||
| <Cd | ||
| variant="responsive" | ||
| <CdButton | ||
| type="button" | ||
| onClick={() => onLikedCdClick(item?.playlistId, item?.isPublic)} | ||
| > | ||
| <Playlist | ||
| id={item.playlistId} | ||
| key={item.playlistId} | ||
| title={item.playlistName} | ||
| username={item.playlistName} | ||
hansololiviakim marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| stickers={item?.cdResponse?.cdItems} | ||
| isPublic={item?.isPublic} | ||
| cdVariant="responsive" | ||
| isPublic={item.isPublic} | ||
| /> | ||
hansololiviakim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| </CdButton> | ||
| <CdNameInfo title={item?.playlistName || ''} creator={item?.creatorNickname || ''} /> | ||
| </li> | ||
| )) | ||
| )} | ||
| </CdListWrap> | ||
|
|
||
| <Modal | ||
| isOpen={modal.isOpen} | ||
| title={modal.title} | ||
| description={modal.description} | ||
| ctaType={modal.ctaType} | ||
| confirmText={modal.confirmText} | ||
| cancelText={modal.cancelText} | ||
| onClose={modal.onClose} | ||
| onConfirm={modal.onConfirm} | ||
| onCancel={modal.onCancel} | ||
| /> | ||
| </> | ||
| ) | ||
| } | ||
|
|
@@ -80,6 +131,9 @@ const CdButton = styled.button` | |
| width: 100%; | ||
| aspect-ratio: 1 / 1; | ||
| border-radius: 10px; | ||
|
|
||
| & > { | ||
| } | ||
|
||
| ` | ||
|
|
||
| const NoLikedWrapper = styled.div` | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,50 +5,66 @@ import styled from 'styled-components' | |||||
| import type { CdCustomData } from '@/entities/playlist' | ||||||
| import { LikeButton } from '@/features/like' | ||||||
| import Cd from '@/shared/ui/Cd' | ||||||
| import type { CdProps } from '@/shared/ui/Cd' | ||||||
|
|
||||||
| interface PlaylistProps { | ||||||
| title: string | ||||||
| username: string | ||||||
| id: number | ||||||
| stickers?: CdCustomData[] | ||||||
| cdVariant?: CdProps['variant'] | ||||||
| isPublic?: boolean | ||||||
| } | ||||||
|
|
||||||
| const Playlist = ({ id, title, username, stickers }: PlaylistProps) => { | ||||||
| const Playlist = ({ | ||||||
| id, | ||||||
| title, | ||||||
| username, | ||||||
| stickers, | ||||||
| cdVariant = 'xl', | ||||||
| isPublic = true, | ||||||
| }: PlaylistProps) => { | ||||||
| const navigate = useNavigate() | ||||||
|
|
||||||
| // 마이페이지에서만 아래 옵션을 사용하고 있어 구분하기 위함 | ||||||
| const isFromMypage = cdVariant === 'responsive' | ||||||
hansololiviakim marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| const handleClick = () => { | ||||||
| if (isFromMypage) return | ||||||
| navigate(`/discover/${id}`) | ||||||
| } | ||||||
|
|
||||||
| return ( | ||||||
| <Wrapper onClick={handleClick}> | ||||||
| <CdBox> | ||||||
| <Cd variant="xl" stickers={stickers} /> | ||||||
| <Wrapper onClick={handleClick} $cdVariant={cdVariant}> | ||||||
| <CdBox $cdVariant={cdVariant}> | ||||||
| <Cd variant={cdVariant} stickers={stickers} isPublic={isPublic} /> | ||||||
| <ButtonContainer> | ||||||
| <LikeButton playlistId={id} type="HOME" /> | ||||||
| </ButtonContainer> | ||||||
| </CdBox> | ||||||
| <InfoBox> | ||||||
| <Title>{title}</Title> | ||||||
| <UserName>{username}</UserName> | ||||||
| </InfoBox> | ||||||
| {!isFromMypage && ( | ||||||
| <InfoBox> | ||||||
| <Title>{title}</Title> | ||||||
| <UserName>{username}</UserName> | ||||||
| </InfoBox> | ||||||
| )} | ||||||
| </Wrapper> | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| export default Playlist | ||||||
|
|
||||||
| const Wrapper = styled.div` | ||||||
| const Wrapper = styled.div<{ $cdVariant: string }>` | ||||||
| display: flex; | ||||||
| flex-direction: column; | ||||||
| gap: 12px; | ||||||
| width: 140px; | ||||||
| width: ${({ $cdVariant }) => ($cdVariant === 'responsive' ? '100%' : '140px')}; | ||||||
| ` | ||||||
|
|
||||||
| const CdBox = styled.div` | ||||||
| const CdBox = styled.div<{ $cdVariant: string }>` | ||||||
| position: relative; | ||||||
| width: 140px; | ||||||
| height: 140px; | ||||||
| width: ${({ $cdVariant }) => ($cdVariant === 'responsive' ? '100%' : '140px')}; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| aspect-ratio: 1 / 1; | ||||||
| border-radius: 16px; | ||||||
|
|
||||||
| display: flex; | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.