diff --git a/src/components/Atoms/Button.tsx b/src/components/Atoms/Button.tsx index 949786b5..52607ae3 100644 --- a/src/components/Atoms/Button.tsx +++ b/src/components/Atoms/Button.tsx @@ -1,4 +1,3 @@ -import { ButtonUnstyled, buttonUnstyledClasses, ButtonUnstyledProps } from '@mui/base'; import { CircularProgress, styled } from '@mui/material'; const CustomButtonRoot = styled('button')` @@ -8,7 +7,7 @@ const CustomButtonRoot = styled('button')` background-color: #312ed7; font-size: 18px; line-height: 21px; - color: ${(props: Props) => props.color || 'white'}; + color: ${(props: ButtonProps) => props.color || 'white'}; transition: all 150ms ease; cursor: pointer; border: none; @@ -17,34 +16,38 @@ const CustomButtonRoot = styled('button')` opacity: 0.9; } - &.${buttonUnstyledClasses.active} { + &:active { opacity: 0.8; } - &.${buttonUnstyledClasses.focusVisible} { + &:focus-visible { box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 5px rgba(0, 127, 255, 0.5); outline: none; } - &.${buttonUnstyledClasses.disabled} { + &:disabled { opacity: 0.5; cursor: not-allowed; background-color: #dadada; } `; -interface Props extends ButtonUnstyledProps { +interface ButtonProps { children?: React.ReactNode; className?: string; $loading?: boolean; disabled?: boolean; + onClick?: (e: React.MouseEvent) => void; + color?: string; + type?: 'button' | 'submit' | 'reset' | undefined; } -export const Button: React.FC = ({ children, ...props }) => ( - + +export const Button: React.FC = ({ children, ...props }) => ( + {props.$loading ? : children} - + ); export const NavButton = styled(Button)` @@ -70,7 +73,7 @@ const ClearButtonNative = styled('button')` } `; -export const ClearButton: React.FC = ({ children, ...props }) => ( +export const ClearButton: React.FC = ({ children, ...props }) => ( {props.disabled ? : children} diff --git a/src/pages/auth/signIn/SignInPage.tsx b/src/pages/auth/signIn/SignInPage.tsx index d97d51e0..959f6682 100644 --- a/src/pages/auth/signIn/SignInPage.tsx +++ b/src/pages/auth/signIn/SignInPage.tsx @@ -1,5 +1,4 @@ import PermIdentityOutlinedIcon from '@mui/icons-material/PermIdentityOutlined'; -import { Checkbox } from '@mui/material'; import { observer } from 'mobx-react-lite'; import { useEffect } from 'react'; import { Controller, useForm } from 'react-hook-form'; @@ -7,16 +6,7 @@ import { useHistory, useLocation } from 'react-router-dom'; import { PasswordInput } from './components'; import { PageUiStoreImpl } from './SignInPageUiStore'; -import { - CheckboxLabel, - Form, - Input, - Link, - LoginButton, - LogoImage, - PageWrapper, - SubLink, -} from './styled'; +import { Form, Input, Link, LoginButton, LogoImage, PageWrapper, SubLink } from './styled'; import { PageStoreHOC } from '@/components'; import { PAGE_URL } from '@/configs/path'; diff --git a/src/pages/board/postDetail/components/ReplyComment/ReplyCommentContainer.tsx b/src/pages/board/postDetail/components/ReplyComment/ReplyCommentContainer.tsx index cfdc2551..037145c1 100644 --- a/src/pages/board/postDetail/components/ReplyComment/ReplyCommentContainer.tsx +++ b/src/pages/board/postDetail/components/ReplyComment/ReplyCommentContainer.tsx @@ -19,15 +19,15 @@ export const ReplyCommentContainer: React.FC<{ model: Model.Comment }> = observe commentInput.target?.id === model.id ? commentInput.state : InputState.WRITE, ).get(); - const handeLongPress = useCallback(model => () => open(model), [open]); - const bind = useLongPress(handeLongPress(model), { + const handleLongPress = useCallback(model => () => open(model), [open]); + const bind = useLongPress(handleLongPress(model), { cancelOnMovement: true, captureEvent: true, onFinish: ev => ev?.preventDefault(), }); return ( -
  • +
  • ); diff --git a/src/pages/circle/home/CircleHomePage.tsx b/src/pages/circle/home/CircleHomePage.tsx index 9a0c75ef..5b5284d0 100644 --- a/src/pages/circle/home/CircleHomePage.tsx +++ b/src/pages/circle/home/CircleHomePage.tsx @@ -1,5 +1,5 @@ import { observer } from 'mobx-react-lite'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { PageUiStoreImpl } from './CircleHomePageUiStore'; import * as Circle from './components'; @@ -8,13 +8,29 @@ import { H2 } from './styled'; import { BodyScreen, GNB, Header, PageBody, PageStoreHOC } from '@/components'; import { usePageUiStore } from '@/hooks'; +const WEB_WIDTH_CONDITION = 550; +const RESIZE_DELAY = 300; +let timer: string | number | NodeJS.Timeout | undefined; + const CircleHomePage: React.FC = observer(() => { const { fetch, circles, joinedCircles } = usePageUiStore(); + const [screenWidth, setScreenWidth] = useState(window.innerWidth); useEffect(() => { fetch(); }, [fetch]); + useEffect(() => { + const handleWindowResize = () => { + clearTimeout(timer); + timer = setTimeout(function () { + setScreenWidth(window.innerWidth); + }, RESIZE_DELAY); + }; + window.addEventListener('resize', handleWindowResize); + return () => window.removeEventListener('resize', handleWindowResize); + }); + return ( <>
    @@ -25,7 +41,7 @@ const CircleHomePage: React.FC = observer(() => { WEB_WIDTH_CONDITION ? Circle.WebSlider : Circle.Slider} />

    내 동아리

    = memo( + ({ model: { id: circleId, mainImage, name, newLineDescription } }) => { + const { push } = useHistory(); + const [isFlipped, setFlip] = useState(false); + const handleClick = () => { + if (isFlipped) setFlip(c => !c); + else push(generatePath(PAGE_URL.CircleJoin, { circleId })); + }; + const handleFlip = (e: React.MouseEvent) => { + e.stopPropagation(); + setFlip(c => !c); + }; + + return ( + + + + + + {name} +

    + + +

    + {name} + + + +
    +
    +
    + ); + }, +); + +const Card = styled.article` + box-sizing: border-box; + width: 90%; + min-width: 360px; + min-height: 500px; + background: #fff; + border: 1px solid #dadada; + box-shadow: 1px 2px 5px rgb(0 0 0 / 15%); + border-radius: 5px; + overflow: hidden; + text-align: left; +`; + +const Body = styled.div` + position: absolute; + width: 100%; + height: calc(100% - 40px); + transition: transform 0.65s; + transform-style: preserve-3d; + + > div { + position: absolute; + backface-visibility: hidden; + } +`; + +const Cover = styled.div<{ mainImage: string | null }>` + top: 6px; + left: 6px; + width: calc(100% - 12px); + height: calc(100% - 6px); + border-radius: 5px; + + ${({ mainImage }) => + mainImage + ? css` + background: center / contain no-repeat url(${mainImage}); + ` + : css` + background: center / contain no-repeat url('/images/empty.png'); + background-size: 65%; + `} + background-color: #efefef; +`; + +const Name = styled.h3` + margin: 0 35px 0 13px; + line-height: 36px; + font-size: 12px; + font-weight: bold; + backface-visibility: hidden; +`; + +const Inner = styled.div<{ isFlipped: boolean }>` + position: relative; + width: 100%; + padding-bottom: 140%; // 5:7 비율 + + ${Body}, ${Name} { + transform: ${({ isFlipped }) => (isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)')}; + } +`; + +const Content = styled.div` + padding: 13px 9px; + width: 100%; + height: 100%; + background-color: #f8f8f8; + border-radius: 5px; + transform: rotateY(180deg); + overflow: hidden; +`; + +const ContentName = styled.div` + margin-bottom: 9px; + line-height: 18px; + font-size: 15px; + font-weight: bold; +`; + +const Footer = styled.div` + position: absolute; + bottom: 0; + width: 100%; + height: 40px; +`; + +const Icon = styled(Article)` + position: absolute; + top: 9px; + right: 5px; +`; diff --git a/src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx b/src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx new file mode 100644 index 00000000..577e4ed5 --- /dev/null +++ b/src/pages/circle/home/components/WebSlider/CircleWebSlider.tsx @@ -0,0 +1,23 @@ +import styled from '@emotion/styled'; +import { observer } from 'mobx-react-lite'; + +import { CircleWebSlideCard } from './CircleWebSlideCard'; +import { ListComponent } from '../CircleListFrame'; + +export const CircleWebSlider: ListComponent = observer(({ items }) => { + return ( + + {items.map(item => ( + + ))} + + ); +}); + +const WebScrollWrapper = styled.div` + display: flex; + align-items: center; + gap: 20px; + overflow-x: auto; + padding: 10px 0px; +`; diff --git a/src/pages/circle/home/components/WebSlider/index.ts b/src/pages/circle/home/components/WebSlider/index.ts new file mode 100644 index 00000000..b519abc6 --- /dev/null +++ b/src/pages/circle/home/components/WebSlider/index.ts @@ -0,0 +1 @@ +export { CircleWebSlider as WebSlider } from './CircleWebSlider'; diff --git a/src/pages/circle/home/components/index.ts b/src/pages/circle/home/components/index.ts index 30471392..1104a3a0 100644 --- a/src/pages/circle/home/components/index.ts +++ b/src/pages/circle/home/components/index.ts @@ -1,4 +1,5 @@ export * from './List'; export * from './Slider'; +export * from './WebSlider'; export { CircleListFrame as ListFrame } from './CircleListFrame';