Skip to content

Commit

Permalink
[Design] 창 팝업/전환 시 애니메이션 효과 일부 추가
Browse files Browse the repository at this point in the history
- 로그인/프로필 창 팝업 및 좌측 창 전환 시 애니메이션 효과 적용

Issues #122
  • Loading branch information
novice1993 committed Oct 2, 2023
1 parent b292191 commit f1608c3
Show file tree
Hide file tree
Showing 15 changed files with 488 additions and 478 deletions.
59 changes: 23 additions & 36 deletions client/src/components/EntireList/EntireList.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { motion } from "framer-motion";
import Header from "./Header";
import StockItem from "./StockItem";
import useCompanyData from "../../hooks/useCompanyData";
import { useSelector } from "react-redux"; // 👈 추가
import { StateProps } from "../../models/stateProps"; // 👈 추가
import useGetCash from "../../hooks/useGetCash";

/*
🔴 수정사항
1) 불필요한 컴포넌트 사용 : Divider 컴포넌트
-> 구분선 (border) 설정위해 생성한 것으로 보이나, 상위 컴포넌트 너비 설정으로 해결 가능 (불필요하여 주석처리)
-> 삭제하는 게 좋을 것 같음
2) 현금 보유량 컴포넌트 조건부 렌더링 변경 (로그인 필요한 서비스 X -> 로그인 해야 화면에 나타나도록)
3) header 컨테이너 부분 height 43px로 고정
4) 금액에 회계 단위 (toLocaleString) 적용 -> 이를 위해 useEffect, useState 활용
*/

const holdingAmountText = "보유 현금";
const amountUnit = "원";

Expand Down Expand Up @@ -51,29 +39,28 @@ const EntireList: React.FC<EntireListProps> = ({ currentListType, onChangeListTy
// 🔴

return (
<WatchListContainer>
<Header1Container>
<Header currentListType={currentListType} onChangeListType={onChangeListType} isMenuOpen={isMenuOpen} setMenuOpen={setMenuOpen} />
</Header1Container>
{/* <Divider /> */}
<Header2Container isLogin={isLogin}>
{/* {isLogin == 0 ? (<HoldingsAmount>로그인이 필요한 서비스 입니다.</HoldingsAmount>) : (<HoldingsAmount>현금 보유량: {holdingsAmount}원</HoldingsAmount>)} */}
<HoldingsAmount isLogin={isLogin}>
{isLogin === 1 && (
<>
<div className="amountText">{holdingAmountText}</div>
<div className="amount">
{holdingCash} {amountUnit}
</div>
</>
)}
</HoldingsAmount>
</Header2Container>
{/* <Divider /> */}
<StockList>
{isLoading ? <div></div> : isError ? <div>Error fetching data</div> : companiesList.map((company) => <StockItem key={company.companyId} company={company} setShowChangePrice={setShowChangePrice} showChangePrice={showChangePrice} />)}
</StockList>
</WatchListContainer>
<motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }}>
<WatchListContainer>
<Header1Container>
<Header currentListType={currentListType} onChangeListType={onChangeListType} isMenuOpen={isMenuOpen} setMenuOpen={setMenuOpen} />
</Header1Container>
<Header2Container isLogin={isLogin}>
<HoldingsAmount isLogin={isLogin}>
{isLogin === 1 && (
<>
<div className="amountText">{holdingAmountText}</div>
<div className="amount">
{holdingCash} {amountUnit}
</div>
</>
)}
</HoldingsAmount>
</Header2Container>
<StockList>
{isLoading ? <div></div> : isError ? <div>Error fetching data</div> : companiesList.map((company) => <StockItem key={company.companyId} company={company} setShowChangePrice={setShowChangePrice} showChangePrice={showChangePrice} />)}
</StockList>
</WatchListContainer>
</motion.div>
);
};

Expand Down
67 changes: 35 additions & 32 deletions client/src/components/HoldingList/HoldingList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import styled from "styled-components";
import { motion } from "framer-motion";
import Header from "./Header";
import StockItem from "./StockItem";
import useGetStockHolds from "../../hooks/useGetStockholds";
Expand Down Expand Up @@ -38,38 +39,40 @@ const HoldingList: React.FC<WatchListProps> = ({ currentListType, onChangeListTy
};

return (
<WatchListContainer>
<Header1Container>
<Header currentListType={currentListType} onChangeListType={onChangeListType} isMenuOpen={isMenuOpen} setMenuOpen={setMenuOpen} />
</Header1Container>
{/* <Divider /> */}
<Header2Container>
<EvaluationProfit profit={totalEvaluationProfit}>
<div className="profitText">{evalutationProfitText}</div>
<div className="profit">
{totalEvaluationProfit.toLocaleString()} {profitUnit}
</div>
</EvaluationProfit>
</Header2Container>
{/* <Divider /> */}
<StockList>
{isLogin === 0 ? (
<LoginRequestIndicator openOAuthModal={openOAuthModal} />
) : isLoading || isCompanyDataLoading ? (
<div></div>
) : isError || isCompanyDataError ? (
<div>Error fetching data</div>
) : (
Array.isArray(stockHolds) &&
stockHolds.length > 0 && // 여기에 조건을 추가합니다
stockHolds.map((stockHold: StockItemProps["stockData"]) => {
const matchedCompany = companyData ? companyData.find((company) => company.companyId === stockHold.companyId) : undefined;

return matchedCompany ? <StockItem key={stockHold.companyId} stockData={stockHold} companyData={matchedCompany} setShowChangePrice={setShowChangePrice} showChangePrice={showChangePrice} /> : null;
})
)}
</StockList>
</WatchListContainer>
<motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }}>
<WatchListContainer>
<Header1Container>
<Header currentListType={currentListType} onChangeListType={onChangeListType} isMenuOpen={isMenuOpen} setMenuOpen={setMenuOpen} />
</Header1Container>
{/* <Divider /> */}
<Header2Container>
<EvaluationProfit profit={totalEvaluationProfit}>
<div className="profitText">{evalutationProfitText}</div>
<div className="profit">
{totalEvaluationProfit.toLocaleString()} {profitUnit}
</div>
</EvaluationProfit>
</Header2Container>
{/* <Divider /> */}
<StockList>
{isLogin === 0 ? (
<LoginRequestIndicator openOAuthModal={openOAuthModal} />
) : isLoading || isCompanyDataLoading ? (
<div></div>
) : isError || isCompanyDataError ? (
<div>Error fetching data</div>
) : (
Array.isArray(stockHolds) &&
stockHolds.length > 0 && // 여기에 조건을 추가합니다
stockHolds.map((stockHold: StockItemProps["stockData"]) => {
const matchedCompany = companyData ? companyData.find((company) => company.companyId === stockHold.companyId) : undefined;

return matchedCompany ? <StockItem key={stockHold.companyId} stockData={stockHold} companyData={matchedCompany} setShowChangePrice={setShowChangePrice} showChangePrice={showChangePrice} /> : null;
})
)}
</StockList>
</WatchListContainer>
</motion.div>
);
};

Expand Down
31 changes: 17 additions & 14 deletions client/src/components/Logins/EmailLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import axios from "axios";
import styled from "styled-components";
import React, { useState } from "react";
import { motion } from "framer-motion";
import { setLoginState } from "../../reducer/member/loginSlice";
import { useDispatch } from "react-redux";
import setAutoLogoutAlarm from "../../utils/setAutoLogoutAlarm";
Expand Down Expand Up @@ -72,20 +73,22 @@ const EmailLoginModal: React.FC<EmailLoginModalProps> = ({ onClose, onSignup })

return (
<ModalBackground>
<ModalContainer>
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>{titleText}</Title>
<Label>{emailLabelText}</Label>
<Input type="email" placeholder="이메일을 입력하세요" value={email} onChange={handleEmailChange} onKeyDown={(event) => handleEnterPress(event, "password")} />
<Label>{passwordLabelText}</Label>
<Input type="password" placeholder="비밀번호를 입력하세요" value={password} onChange={handlePasswordChange} onKeyDown={(event) => handleEnterPress(event, "loginButton")} />
{generalError && <ErrorMessage>{generalError}</ErrorMessage>}
<RightAlignedButton onClick={handleFindPasswordClick}>{findPasswordText}</RightAlignedButton>
<LoginButton onClick={handleLoginClick}>{loginButtonText}</LoginButton>
<BottomText>
{noAccountText} <RegisterButton onClick={onSignup}>{registerButtonText}</RegisterButton>
</BottomText>
</ModalContainer>
<motion.div initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }}>
<ModalContainer>
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>{titleText}</Title>
<Label>{emailLabelText}</Label>
<Input type="email" placeholder="이메일을 입력하세요" value={email} onChange={handleEmailChange} onKeyDown={(event) => handleEnterPress(event, "password")} />
<Label>{passwordLabelText}</Label>
<Input type="password" placeholder="비밀번호를 입력하세요" value={password} onChange={handlePasswordChange} onKeyDown={(event) => handleEnterPress(event, "loginButton")} />
{generalError && <ErrorMessage>{generalError}</ErrorMessage>}
<RightAlignedButton onClick={handleFindPasswordClick}>{findPasswordText}</RightAlignedButton>
<LoginButton onClick={handleLoginClick}>{loginButtonText}</LoginButton>
<BottomText>
{noAccountText} <RegisterButton onClick={onSignup}>{registerButtonText}</RegisterButton>
</BottomText>
</ModalContainer>
</motion.div>
</ModalBackground>
);
};
Expand Down
31 changes: 16 additions & 15 deletions client/src/components/Logins/OAuthLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

import React from "react";
import styled from "styled-components";
import GoogleLoginButton from "./GoogleLoginButton";
import KakaoLoginButton from "./KakaoLoginButton";
import { motion } from "framer-motion";

const OAuthLoginModal: React.FC<LoginModalProps> = ({ onClose, onEmailLoginClick, onEmailSignupClick }) => {
const titleText = "로그인";
Expand All @@ -16,17 +16,19 @@ const OAuthLoginModal: React.FC<LoginModalProps> = ({ onClose, onEmailLoginClick

return (
<ModalBackground>
<ModalContainer>
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>{titleText}</Title>
<GoogleLoginButton backendURL={GOOGLE_BACKEND_URL} />
<KakaoLoginButton backendURL={KAKAO_BACKEND_URL} />
<OrText>{orText}</OrText>
<EmailButtonsContainer>
<EmailButton onClick={onEmailLoginClick}>{emailLoginText}</EmailButton>
<EmailButton onClick={onEmailSignupClick}>{emailSignupText}</EmailButton>
</EmailButtonsContainer>
</ModalContainer>
<motion.div initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }}>
<ModalContainer>
<CloseButton onClick={onClose}>&times;</CloseButton>
<Title>{titleText}</Title>
<GoogleLoginButton backendURL={GOOGLE_BACKEND_URL} />
<KakaoLoginButton backendURL={KAKAO_BACKEND_URL} />
<OrText>{orText}</OrText>
<EmailButtonsContainer>
<EmailButton onClick={onEmailLoginClick}>{emailLoginText}</EmailButton>
<EmailButton onClick={onEmailSignupClick}>{emailSignupText}</EmailButton>
</EmailButtonsContainer>
</ModalContainer>
</motion.div>
</ModalBackground>
);
};
Expand All @@ -35,12 +37,11 @@ export default OAuthLoginModal;

//변수 타입
interface LoginModalProps {

onClose: () => void;
onEmailLoginClick: () => void;
onEmailSignupClick: () => void;
onWatchListClick?: () => void; // '?'를 사용하여 선택적으로 만듭니다.
onHoldingsClick?: () => void; // '?'를 사용하여 선택적으로 만듭니다.
onWatchListClick?: () => void; // '?'를 사용하여 선택적으로 만듭니다.
onHoldingsClick?: () => void; // '?'를 사용하여 선택적으로 만듭니다.
}

// 모달창 띄웠을 때 배경 스타일
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/MarketComponents/MarketKospiChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import axios from "axios";
const MarketkospiChart = () => {
const [kospiData, setKospiData] = useState([]);

const { data, isLoading, error } = useQuery("kospi", getKospiData, {});
const { data, isLoading, error } = useQuery("kospi", getKospiData, {
staleTime: Infinity,
});

useEffect(() => {
if (data) {
Expand Down
Loading

0 comments on commit f1608c3

Please sign in to comment.