diff --git a/FE/src/components/FallbackUI.tsx b/FE/src/components/FallbackUI.tsx deleted file mode 100644 index 72031aa8..00000000 --- a/FE/src/components/FallbackUI.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { FallbackProps } from 'react-error-boundary'; - -export default function FallbackUI({ - error, - resetErrorBoundary, -}: FallbackProps) { - return ( -
-

Something went wrong:

-
{error.message}
- -
- ); -} diff --git a/FE/src/components/Header.tsx b/FE/src/components/Header.tsx index b9589508..eaf4dd8e 100644 --- a/FE/src/components/Header.tsx +++ b/FE/src/components/Header.tsx @@ -19,9 +19,12 @@ export default function Header() { useEffect(() => { const check = async () => { - const res = await checkAuth(); - if (res.ok) setIsLogin(true); - else setIsLogin(false); + try { + const res = await checkAuth(); + setIsLogin(res.isLogin); + } catch (error) { + console.log(error); + } }; check(); @@ -42,7 +45,7 @@ export default function Header() { }; return ( -
+
diff --git a/FE/src/components/Mypage/BookMark.tsx b/FE/src/components/Mypage/BookMark.tsx index 25218a9e..8439eb7f 100644 --- a/FE/src/components/Mypage/BookMark.tsx +++ b/FE/src/components/Mypage/BookMark.tsx @@ -1,6 +1,6 @@ -import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; -import { getBookmarkedStocks } from 'service/bookmark'; +import { HeartIcon } from '@heroicons/react/16/solid'; +import useBookmark from 'hooks/useBookmark'; export default function BookMark() { const navigation = useNavigate(); @@ -9,24 +9,20 @@ export default function BookMark() { navigation(`/stocks/${code}`); }; - const { data } = useQuery( - ['bookmark', 'stock'], - () => getBookmarkedStocks(), - { - staleTime: 1000, - suspense: true, - }, - ); + const { bookmarkQuery, unlike } = useBookmark(); + + const { data } = bookmarkQuery; return (
-
-

종목

+
+

종목

현재가

등락률

+

-
    +
      {data?.map((stock) => { const { code, name, stck_prpr, prdy_ctrt, prdy_vrss_sign } = stock; @@ -34,13 +30,16 @@ export default function BookMark() {
    • handleClick(code)} + onClick={(e) => { + if ((e.target as HTMLElement).closest('button')) return; + handleClick(code); + }} > -
      +

      {name}

      {code}

      -

      +

      {(+stck_prpr).toLocaleString()}원

      +

      + +

    • ); })} diff --git a/FE/src/components/Mypage/MyStocksList.tsx b/FE/src/components/Mypage/MyStocksList.tsx index 8b83dc94..1061edfa 100644 --- a/FE/src/components/Mypage/MyStocksList.tsx +++ b/FE/src/components/Mypage/MyStocksList.tsx @@ -44,7 +44,7 @@ export default function MyStocksList({ stocks }: MyStocksListProps) { {(+stck_prpr).toLocaleString()}원

      - {avg_price.toLocaleString()}원 + {Math.floor(avg_price).toLocaleString()}원

      { + navigation(`/stocks/${code}`); + }; + return (

      -
      -

      종목

      +
      +

      종목

      요청 유형

      수량

      요청 가격

      @@ -20,7 +27,7 @@ export default function Order() {

      -
        +
          {data?.map((order) => { const { id, @@ -33,8 +40,12 @@ export default function Order() { } = order; return ( -
        • -
          +
        • handleClick(stock_code)} + > +

          {stock_name}

          {stock_code}

          @@ -47,15 +58,15 @@ export default function Order() { > {trade_type === 'BUY' ? '매수' : '매도'}

          -

          {amount}

          +

          {amount}

          {price.toLocaleString()}원

          -

          +

          {formatTimestamp(created_at)}

          diff --git a/FE/src/components/StocksDetail/TradeSection/BuySection.tsx b/FE/src/components/StocksDetail/TradeSection/BuySection.tsx index ba17325d..78193072 100644 --- a/FE/src/components/StocksDetail/TradeSection/BuySection.tsx +++ b/FE/src/components/StocksDetail/TradeSection/BuySection.tsx @@ -38,7 +38,7 @@ export default function BuySection({ code, detailInfo }: BuySectionProps) { const { isOpen, toggleModal } = useTradeAlertModalStore(); - const [count, setCount] = useState(0); + const [count, setCount] = useState(1); const [upperLimitFlag, setUpperLimitFlag] = useState(false); const [lowerLimitFlag, setLowerLimitFlag] = useState(false); @@ -110,14 +110,14 @@ export default function BuySection({ code, detailInfo }: BuySectionProps) { <>

          -
          +

          매수 가격

          {lowerLimitFlag && ( @@ -130,13 +130,13 @@ export default function BuySection({ code, detailInfo }: BuySectionProps) { 이 주식의 최대 가격은 {(+stck_mxpr).toLocaleString()}입니다.
          )} -
          +

          수량

          @@ -155,7 +155,7 @@ export default function BuySection({ code, detailInfo }: BuySectionProps) {
          -
          +
          {lackAssetFlag && (

          잔액이 부족해요!

          )} @@ -164,7 +164,7 @@ export default function BuySection({ code, detailInfo }: BuySectionProps) { className={ 'rounded-lg bg-juga-red-60 py-2 text-white disabled:bg-juga-grayscale-100' } - disabled={!isLogin} + disabled={!isLogin || count === 0} > 매수하기 diff --git a/FE/src/components/StocksDetail/TradeSection/SellSection.tsx b/FE/src/components/StocksDetail/TradeSection/SellSection.tsx index aa1f674f..b44c30d1 100644 --- a/FE/src/components/StocksDetail/TradeSection/SellSection.tsx +++ b/FE/src/components/StocksDetail/TradeSection/SellSection.tsx @@ -63,7 +63,7 @@ export default function SellSection({ code, detailInfo }: SellSectionProps) { if (isError) return
          error
          ; const quantity = data.quantity; - const avg_price = data.avg_price; + const avg_price = Math.floor(data.avg_price); const pl = (+currPrice - avg_price) * count; const totalPrice = +currPrice * count; @@ -204,7 +204,7 @@ export default function SellSection({ code, detailInfo }: SellSectionProps) { className={ 'rounded-lg bg-juga-blue-50 py-2 text-white disabled:bg-juga-grayscale-100' } - disabled={!isLogin} + disabled={!isLogin || count === 0} > 매도하기 diff --git a/FE/src/hooks/useBookmark.ts b/FE/src/hooks/useBookmark.ts new file mode 100644 index 00000000..745451e5 --- /dev/null +++ b/FE/src/hooks/useBookmark.ts @@ -0,0 +1,25 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { bookmark, getBookmarkedStocks, unbookmark } from 'service/bookmark'; + +export default function useBookmark() { + const queryClient = useQueryClient(); + + const bookmarkQuery = useQuery( + ['bookmark', 'stock'], + () => getBookmarkedStocks(), + { + staleTime: 1000, + suspense: true, + }, + ); + + const like = useMutation((code: string) => bookmark(code), { + onSuccess: () => queryClient.invalidateQueries(['bookmark', 'stock']), + }); + + const unlike = useMutation((code: string) => unbookmark(code), { + onSuccess: () => queryClient.invalidateQueries(['bookmark', 'stock']), + }); + + return { bookmarkQuery, like, unlike }; +} diff --git a/FE/src/service/auth.ts b/FE/src/service/auth.ts index fc0badef..fc8ad4cd 100644 --- a/FE/src/service/auth.ts +++ b/FE/src/service/auth.ts @@ -14,7 +14,7 @@ export async function login( }).then((res) => res.json()); } -export async function checkAuth() { +export async function checkAuth(): Promise<{ isLogin: boolean }> { const url = import.meta.env.PROD ? `${import.meta.env.VITE_API_URL}/auth/check` : '/api/auth/check'; @@ -22,7 +22,7 @@ export async function checkAuth() { return fetch(url, { credentials: 'include', headers: { 'Content-Type': 'application/json' }, - }); + }).then((res) => res.json()); } export async function logout() {