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(toks-components, quiz): Image Preview 기능 구현 #403

Merged
merged 10 commits into from
Feb 18, 2024
5 changes: 3 additions & 2 deletions src/app/my-page/components/LogoutBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ export const LogoutBar = () => {
로그아웃
</Text>
<Image
className="h-auto w-24px"
src={ICON_URL.CHEVRON_RIGHT}
alt="로그아웃 버튼"
width={24}
height={24}
width="0"
height="0"
Comment on lines +26 to +30
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 무슨 차이인가요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next Image를 사용할 때 콘솔에 src has either width or height modified, but not the other. If you use CSS to change the size of your image, also include the styles 'width: "auto"' or 'height: "auto"' to maintain the aspect ratio. warning이 여러번 떴었는데요, 해당 warning을 해결하기 위해서는 width나 height 둘 중 하나를 auto로 설정해서 ratio를 맞춰야하는데 next Image를 사용할 때에는 width와 height 두 속성 모두 지정을 해줘야만했기 때문에 위와 같은 방식으로 작성하게 되었습니다!
next/image

/>
</button>
<LogoutBottomSheet onClose={() => setIsShow(false)} isShow={isShow} />
Expand Down
5 changes: 3 additions & 2 deletions src/app/my-page/components/LogoutBottonSheet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ export const LogoutBottomSheet = ({ onClose, isShow }: BottomSheetProps) => {
로그아웃 하시겠어요?
</Text>
<Image
className="h-auto w-14px"
onClick={() => onClose()}
src={ICON_URL.SMALL_X}
alt="바텀시트 닫기버튼"
width={14}
height={14}
width="0"
height="0"
/>
</div>
<div className="h-40px" />
Expand Down
2 changes: 1 addition & 1 deletion src/app/my-page/components/UserInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const UserInfo = () => {
{user?.nickname}
</Text>
<Image
className="ml-4px"
className="ml-4px h-auto w-24px"
src={ICON_URL.CHEVRON_RIGHT}
alt="닉네임 수정 버튼"
width={24}
Expand Down
6 changes: 3 additions & 3 deletions src/app/my-page/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ const MyPage = () => {
똑스에서 풀고 싶은 퀴즈가 있다면?
</Text>
<Image
className="mx-auto my-20px"
className="mx-auto my-20px h-auto w-160px"
src={ICON_URL.EMOJI_ROCKET}
width={160}
height={160}
width="0"
height="0"
alt="로켓 이미지"
/>
<Button
Expand Down
5 changes: 3 additions & 2 deletions src/app/nickname/components/NicknameBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ export const NicknameBox = ({
)}
>
<Image
className="h-auto w-52px"
src={ICON_URL.EMOJI_DROOLING}
alt="똑스 아이콘"
width={52.5}
height={52.5}
width="0"
height="0"
/>
<div className="mt-16px flex w-full flex-col items-center">
<Text typo="headingM" color="white">
Expand Down
46 changes: 36 additions & 10 deletions src/app/quiz/components/QuizButton/Thumbnail.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
'use client';

import Image from 'next/image';
import { useState } from 'react';

import { ICON_URL, bgColor, cn } from '@/common';
import { Modal } from '@/common/components/Modal';

import { QuizButtonProps } from './type';

Expand All @@ -14,9 +18,13 @@ export function Thumbnail({
imageUrl,
name = '퀴즈',
className,
...rest
}: ThumbnailProps) {
const [isShow, setIsShow] = useState(false);

return (
<div
{...rest}
className={cn(
'relative flex aspect-square w-140px items-center justify-center overflow-hidden rounded-8px',
OXType &&
Expand All @@ -25,16 +33,34 @@ export function Thumbnail({
)}
>
{imageUrl && (
<img
src={imageUrl}
alt={`${name}사진`}
style={{
width: '100%',
height: '100%',
objectFit: 'cover',
objectPosition: 'center',
}}
/>
<>
<img
onClick={() => setIsShow(true)}
src={imageUrl}
alt={`${name}사진`}
style={{
width: '100%',
height: '100%',
objectFit: 'cover',
objectPosition: 'center',
}}
/>
<Modal isShow={isShow} onClose={() => setIsShow(false)}>
<img
onClick={(e) => {
e.stopPropagation();
}}
className="rounded-8px"
src={imageUrl}
alt={`${name}사진`}
style={{
width: '100%',
objectFit: 'cover',
objectPosition: 'center',
}}
/>
</Modal>
</>
)}
{OXType && (
<Image
Expand Down
16 changes: 8 additions & 8 deletions src/app/quiz/components/QuizButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ export function QuizButton({
...rest
}: QuizButtonProps) {
return (
<button
className={clsx(className, 'flex flex-1 flex-col items-center')}
disabled={isSubmitted}
{...rest}
>
<div className={clsx(className, 'flex flex-1 flex-col items-center')}>
{(OXType || imageUrl) && (
<Thumbnail
className="mb-24px w-full"
Expand All @@ -43,11 +39,15 @@ export function QuizButton({
{isSubmitted && (
<ProgressBar percentage={percentage} isSelected={isSelected} />
)}
<div className="absolute z-10 flex h-full w-full items-center justify-center">
<button
className="absolute z-10 flex h-full w-full items-center justify-center"
disabled={isSubmitted}
{...rest}
>
<Text typo="bodyBold" color="gray10">
{name}
</Text>
</div>
</button>
</div>
{isSubmitted && participationLabel && (
<Text
Expand All @@ -58,6 +58,6 @@ export function QuizButton({
{participationLabel}
</Text>
)}
</button>
</div>
);
}
5 changes: 3 additions & 2 deletions src/app/quiz/components/ScrollToTopButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ export function ScrollToTopButton() {
}}
>
<Image
className="h-auto w-16px"
src={ICON_URL.CHEVRON_UP}
width={16}
height={9}
width="0"
height="0"
alt="맨 위로가기 아이콘"
/>
</button>
Expand Down
6 changes: 3 additions & 3 deletions src/common/components/Appbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ export const Appbar = () => {
<div className="flex w-full items-center justify-between pb-[20px] pt-[16px]">
<div className="flex items-center gap-4px" role="button">
<Image
layout="fixed"
width={60}
height={20}
width="0"
height="0"
src={ICON_URL.TOKS_LOGO}
alt="toks 로고"
className="h-auto w-60px"
/>
</div>
<button className="flex items-center gap-[12px]">
Expand Down
5 changes: 3 additions & 2 deletions src/common/components/BackHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ export const BackHeader = () => {
<div className="flex h-full w-full items-center justify-between">
<button type="button" onClick={() => router.back()}>
<Image
className="h-auto w-24px"
src={ICON_URL.CHEVRON_LEFT_BIG}
alt="뒤로가기 버튼"
width={24}
height={24}
width="0"
height="0"
/>
</button>
</div>
Expand Down
67 changes: 67 additions & 0 deletions src/common/components/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use client';

import { AnimatePresence, motion } from 'framer-motion';
import Image from 'next/image';
import { PropsWithChildren, ReactNode } from 'react';

import { ICON_URL } from '@/common';

import { GlobalPortal } from '../GlobalPortal';

type ModalProp = {
isShow: boolean;
onClose: VoidFunction;
};

export const Modal = ({
isShow,
onClose,
children,
}: PropsWithChildren<ModalProp>) => {
return (
<GlobalPortal.Consumer>
<Dimmer isShow={isShow} onClose={onClose} children={children} />
</GlobalPortal.Consumer>
);
};

const backdropVariants = {
hidden: { opacity: 0 },
visible: { opacity: 1 },
};

const Dimmer = ({
isShow,
onClose,
children,
}: {
isShow: boolean;
onClose: VoidFunction;
children: ReactNode;
}) => {
return (
<AnimatePresence>
{isShow && (
<motion.div
initial="hidden"
animate="visible"
exit="hidden"
variants={backdropVariants}
transition={{ duration: 0.3 }}
onClick={() => onClose()}
className="fixed left-0 top-0 z-50 flex h-full w-full items-center justify-center bg-gray-120/80 p-20px"
>
<div className="flex flex-col">
<button
className="flex justify-end pb-16px"
onClick={() => onClose()}
>
<Image src={ICON_URL.CLOSE} alt="close" width={24} height={24} />
</button>
{children}
</div>
</motion.div>
)}
</AnimatePresence>
);
};
Loading