2 Incheckningar aa86f0802e ... 848bd06ff2

Upphovsman SHA1 Meddelande Datum
  tuyetnhi 848bd06ff2 auto complete search 1 år sedan
  tuyetnhi 01b58dd576 table-ranking-100 1 år sedan

+ 2 - 1
package.json

@@ -90,6 +90,7 @@
     "yarn": "^1.22.17"
   },
   "dependencies": {
-    "currency.js": "^2.0.4"
+    "currency.js": "^2.0.4",
+    "usehooks-ts": "^2.9.1"
   }
 }

BIN
public/favicon.png


+ 1 - 1
public/index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-
+    <link rel="icon" href="./favicon.png" />
     <title>Metarare</title>
     <!-- Google tag (gtag.js) -->
     <script

+ 1 - 0
src/@types/index.d.ts

@@ -311,6 +311,7 @@ declare module 'metarare' {
 
     export interface ISalesRanking {
         id: number;
+        rank: number;
         name: string;
         thumbnail_image: string;
         total_revenue: number;

+ 47 - 0
src/components/common/AutoCompleteSearch.scss

@@ -0,0 +1,47 @@
+@import "assets/css/_lib";
+
+.complete_box {
+    position: absolute;
+    visibility: inherit;
+    border: 1px solid #eee;
+    border-top: none;
+    box-shadow: 1px 0px 5px 0 rgba(0, 0, 0, 0.16);
+    top: 90%;
+    left: 50%;
+    width: 92%;
+    z-index: 10;
+    background-color: #fff;
+    border-bottom-left-radius: 12px;
+    border-bottom-right-radius: 12px;
+    max-height: 200px;
+    overflow-y: auto;
+    transform: translateX(-50%);
+
+    @include pc {
+        top: 66%;
+        width: 97%;
+    }
+
+    .complete_list {
+        position: relative;
+        z-index: 1;
+
+        .complete_item {
+            cursor: pointer;
+            display: block;
+            padding: 10px 16px;
+            font-size: 14px;
+            line-height: 18px;
+            color: #888;
+
+            &:hover {
+                background-color: #f5f5f5;
+            }
+        }
+    }
+}
+
+.hidden {
+    visibility: hidden;
+    z-index: -1;
+}

+ 31 - 0
src/components/common/AutoCompleteSearch.tsx

@@ -0,0 +1,31 @@
+import * as React from "react";
+import styles from "./AutoCompleteSearch.scss";
+import classNames from "classnames/bind";
+
+const cx = classNames.bind(styles);
+
+export interface IAutoCompleteSearchProps {
+  onClick: (value: string) => void;
+  show: boolean;
+  data: string[];
+}
+
+export default function AutoCompleteSearch({
+  onClick,
+  show,
+  data,
+}: IAutoCompleteSearchProps) {
+  return (
+    <div className={cx("complete_box", !show ? "hidden" : "")}>
+      <div className={cx("complete_list")}>
+        {data.map((item, index) => {
+          return (
+            <div className={cx("complete_item")} key={index} onClick={() => onClick(item)}>
+              <span className={cx("complete_text")}>{item}</span>
+            </div>
+          );
+        })}
+      </div>
+    </div>
+  );
+}

+ 96 - 0
src/components/common/RankingTable.scss

@@ -0,0 +1,96 @@
+@import "assets/css/_lib";
+
+.table_wrapper {
+    margin-top: 20px;
+    font-size: 12px;
+    @include pc {
+        font-size: 16px;
+    }
+    &>table {
+        width: 100%;
+        border-collapse: collapse;
+        border-spacing: 0;
+
+        thead {
+            tr {
+                th {
+                    height: 40px;
+                    padding: 0 10px;
+                    font-size: 1em;
+                    font-weight: 400;
+                    color: #888;
+                    text-align: left;
+                    border-bottom: 1px solid #ddd;
+
+                    &:first-child {
+                        padding-left: 0;
+                    }
+
+                    &:last-child {
+                        padding-right: 0;
+                        text-align: center;
+                    }
+                }
+            }
+        }
+
+        tbody {
+            tr {
+                height: 60px;
+
+                td {
+                    padding: 0 10px;
+                    font-size: 1em;
+                    font-weight: 400;
+                    color: #333;
+                    border-bottom: 1px solid #ddd;
+                    padding: 20px 10px;
+
+                    &:first-child {
+                        padding-right: 0;
+                    }
+
+                    &:last-child {
+                        padding-right: 0;
+                    }
+                }
+
+                .rank {
+                    margin-right: 10px;
+                    &>div {
+                        margin: auto;
+                        width: 24px;
+                        height: 24px;
+                        border-radius: 50%;
+                        display: flex;
+                        align-items: center;
+                        justify-content: center;
+                        font-family: 'HelveticaNeue', 'Helvetica', arial, 'sans-serif' !important;
+                        font-size: 0.8em;
+                        color: #fff;
+                        z-index: 1;
+                    }
+                }
+
+                .name{
+                    max-width: 100px;
+                    @include ellipsis;
+                }
+                .thumbnail_image {
+                    width: 64px;
+
+                    &>img {
+                        width: 64px;
+                        height: 64px;
+                        margin-right: 10px;
+                        border-radius: 50%;
+                        vertical-align: middle;
+                    }
+                }
+                .total_revenue{
+                    text-align: center;
+                }
+            }
+        }
+    }
+}

+ 52 - 0
src/components/common/RankingTable.tsx

@@ -0,0 +1,52 @@
+import { ISalesRanking } from "metarare";
+import * as React from "react";
+import styles from "./RankingTable.scss";
+import classNames from "classnames/bind";
+import currency from "currency.js";
+
+const cx = classNames.bind(styles);
+
+export interface IRankingTableProps{
+    data: ISalesRanking[];
+}
+
+export default function RankingTable({data}: IRankingTableProps) {
+  const header = ["", "Store", "", "Total Value"];
+  const renderColor = (rank: number) => {
+    if (rank === 1) return "#ffd700";
+    if (rank === 2) return "#c0c0c0";
+    if (rank === 3) return "#cd7f32";
+    return "#3d3d3d";
+  };
+  return (
+    <div className={cx("table_wrapper")}>
+      <table>
+        <thead>
+          <tr>
+            {header.map((item, index) => (
+              <th key={index}>{item}</th>
+            ))}
+          </tr>
+        </thead>
+        <tbody>
+          {data.map((item, index) => (
+            <tr key={"custom-table-ranking" + index}>
+              <td className={cx("rank")}>
+                <div style={{
+                    background: renderColor(item.rank)
+                }}>{item.rank}</div></td>
+              <td className={cx("thumbnail_image")}>
+                <img src={item.thumbnail_image} alt={item.name} />
+              </td>
+              <td className={cx("name")}>{item.name}</td>
+              <td className={cx("total_revenue")}>{currency(item.total_revenue).format({
+                    symbol: "$",
+                    precision: 0,
+              })}</td>
+            </tr>
+          ))}
+        </tbody>
+      </table>
+    </div>
+  );
+}

+ 1 - 1
src/components/common/SaleRankingCard.tsx

@@ -12,7 +12,7 @@ export interface ISalesRankingCardProps extends ISalesRanking {
 }
 
 export default function SalesRankingCard({
-  id: rank,
+  rank,
   name,
   thumbnail_image,
   className,

+ 59 - 20
src/components/mobile/Search.tsx

@@ -1,47 +1,86 @@
-import React from 'react';
-import classNames from 'classnames/bind';
-import styles from './Search.scss';
+import React, { useRef, useState } from "react";
+import classNames from "classnames/bind";
+import styles from "./Search.scss";
 
-import { ReactComponent as IconSearchGray } from '@assets/img/svg/ico_search_gray.svg';
-import { ReactComponent as IconClose } from '@assets/img/svg/ico_close.svg';
-import useSearch from '@src/hooks/useSearch';
-import { useHistory } from 'react-router';
-import URLInfo from '@src/constants/URLInfo';
+import { ReactComponent as IconSearchGray } from "@assets/img/svg/ico_search_gray.svg";
+import { ReactComponent as IconClose } from "@assets/img/svg/ico_close.svg";
+import useSearch from "@src/hooks/useSearch";
+import { useHistory } from "react-router";
+import URLInfo from "@src/constants/URLInfo";
+import { useOnClickOutside } from "usehooks-ts";
+import AutoCompleteSearch from "../common/AutoCompleteSearch";
 
 const cx = classNames.bind(styles);
 
 interface IOwnProps {
   onClose: () => void;
-};
+}
 
 const Search: React.FC<IOwnProps> = ({ onClose }) => {
   const history = useHistory();
-
+  const searchRef = useRef(null);
+  const [showAutoComplete, setShowAutoComplete] = useState<boolean>(false);
   const onSearch = () => {
     history.push(URLInfo.getSearchResultUrl(keyword));
     onClose();
   };
-  const { keyword, setKeyword, onKeyPress, handleSearch } = useSearch({ onSearch });
+  const SelectTextComplete = (text: string) => {
+    history.push(URLInfo.getSearchResultUrl(text));
+    onClose();
+  };
+
+  const { keyword, setKeyword, onKeyPress, handleSearch } = useSearch({
+    onSearch,
+  });
+
+  const fakeComplete = [
+    "test1",
+    "test2",
+    "test3",
+    "test4",
+    "test5",
+    "test6",
+    "test7",
+    "test8",
+    "test9",
+    "test10",
+  ];
+
+  useOnClickOutside(searchRef, () => {
+    setShowAutoComplete(false);
+  });
 
   return (
-    <div className={cx('ly_search')}>
-      <div className={cx('input_box')}>
+    <div className={cx("ly_search")} ref={searchRef}>
+      <div className={cx("input_box")}>
         <input
           type="text"
           placeholder="작가(NFT)이름을 입력해주세요"
-          className={cx('input_search')}
+          className={cx("input_search")}
           value={keyword}
           onKeyPress={onKeyPress}
           onChange={(e) => setKeyword(e.target.value)}
+          onFocus={() => {
+            setShowAutoComplete(true);
+          }}
         />
-        <button className={cx('btn_search')} onClick={handleSearch}>
-          <span className={cx('blind')}>Search</span>
-          <IconSearchGray className={cx('ico_search')} />
+        <button className={cx("btn_search")} onClick={handleSearch}>
+          <span className={cx("blind")}>Search</span>
+          <IconSearchGray className={cx("ico_search")} />
         </button>
+        <AutoCompleteSearch
+          show={showAutoComplete}
+          data={fakeComplete}
+          onClick={(e) => {
+            setShowAutoComplete(false);
+            SelectTextComplete(e);
+            setKeyword(e);
+          }}
+        />
       </div>
-      <button className={cx('btn_close')} onClick={onClose}>
-        <span className={cx('blind')}>Close</span>
-        <IconClose className={cx('ico_close')} />
+      <button className={cx("btn_close")} onClick={onClose}>
+        <span className={cx("blind")}>Close</span>
+        <IconClose className={cx("ico_close")} />
       </button>
     </div>
   );

+ 41 - 8
src/components/pc/Header.scss

@@ -16,13 +16,16 @@
         z-index: 20;
     }
 }
+
 .logo {
     flex: 0 0 auto;
     margin-right: 16px;
+
     .link_logo {
         display: block;
         padding: 17px 0;
     }
+
     .ico_logo {
         overflow: hidden;
         width: 40px;
@@ -31,20 +34,24 @@
         border-radius: 8px;
         vertical-align: top;
     }
+
     .name {
         font-family: 'Retorica', 'Barun';
         font-size: 28px;
         line-height: 40px;
     }
 }
+
 .gnb {
     display: flex;
     flex: 1 1 auto;
 }
+
 .search_area {
     position: relative;
     flex: 1 1 auto;
     margin: 19px 10px 0 0;
+  
     .input_search {
         display: block;
         width: 100%;
@@ -57,38 +64,46 @@
         font-size: 14px;
         line-height: 18px;
         outline: none;
+
         &::placeholder {
             color: #888;
         }
+
         &:focus {
             background-color: #fff;
             border: 1px solid #16dccf;
             color: #000;
         }
     }
+
     .btn_search {
         position: absolute;
-        top: 0; 
+        top: 0;
         right: 0;
         padding: 10px 16px;
     }
+
     .ico_search {
         vertical-align: top;
-    }   
+    }
 }
-.ico_share{
+
+.ico_share {
     width: 24px;
     height: 24px;
     margin-top: 5px;
     vertical-align: top;
 }
+
 .menu_list {
     white-space: nowrap;
     margin-top: 19px;
+
     .menu_item {
         position: relative;
         display: inline-block;
         vertical-align: top;
+
         .menu {
             display: block;
             padding: 0 20px;
@@ -96,6 +111,7 @@
             font-size: 14px;
             line-height: 36px;
         }
+
         .btn_community {
             padding: 0 20px;
             color: #888;
@@ -104,12 +120,14 @@
             vertical-align: top;
             font-family: 'Retorica', 'Barun';
         }
+
         .ico_arr {
             width: 24px;
             height: 24px;
             margin-top: 5px;
             vertical-align: top;
         }
+
         .ly_community {
             position: absolute;
             top: 40px;
@@ -120,6 +138,7 @@
             background-color: #fff;
             box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
             z-index: 10;
+
             .dimmed {
                 position: fixed;
                 top: 0;
@@ -127,41 +146,49 @@
                 width: 100%;
                 height: 100vh;
             }
+
             .community_list {
                 position: relative;
                 z-index: 1;
             }
+
             .link_community {
                 display: block;
                 padding: 0 16px;
                 line-height: 42px;
                 letter-spacing: -0.42px;
             }
+
             .link_community_number {
                 display: block;
                 padding: 0 16px;
                 line-height: 20px;
                 letter-spacing: -0.42px;
             }
+
             .community_sns {
                 margin-top: 8px;
                 text-align: center;
             }
+
             .link_sns {
                 display: inline-block;
                 padding: 8px 10px 16px;
                 vertical-align: top;
             }
+
             .link_sns_u {
                 display: inline-block;
-                padding: 4px 10px ;
+                padding: 4px 10px;
                 vertical-align: top;
             }
+
             .ico_sns {
                 width: 24px;
                 height: 24px;
                 vertical-align: top;
             }
+
             .ico_sns_facebook {
                 width: 21px;
                 height: 21px;
@@ -170,12 +197,14 @@
         }
     }
 }
+
 .btn_area {
     .link_activity {
         display: inline-block;
         padding: 25px 8px;
         vertical-align: top;
     }
+
     .link {
         display: inline-block;
         height: 36px;
@@ -187,27 +216,31 @@
         line-height: 36px;
         vertical-align: top;
     }
+
     .link_make {
         color: #fff;
-        background: rgb(249,72,160);
-        background: linear-gradient(90deg, rgba(249,72,160,1) 0%, rgba(120,156,187,1) 70%, rgba(22,220,207,1) 100%);
-        font-size:12px;
+        background: rgb(249, 72, 160);
+        background: linear-gradient(90deg, rgba(249, 72, 160, 1) 0%, rgba(120, 156, 187, 1) 70%, rgba(22, 220, 207, 1) 100%);
+        font-size: 12px;
         font-family: 'Retorica', 'Barun';
     }
+
     .link_login {
         min-width: 76px;
         border: 1px solid #ddd;
         line-height: 34px;
         box-sizing: border-box;
-        font-size:12px;
+        font-size: 12px;
         font-family: 'Retorica', 'Barun';
     }
+
     .btn_profile {
         width: 40px;
         height: 40px;
         margin: 17px 0 0 8px;
         border-radius: 8px;
         vertical-align: top;
+
         .img_profile {
             border-radius: 8px;
         }

+ 35 - 4
src/components/pc/Header.tsx

@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect, useState, useRef } from "react";
 import classNames from "classnames/bind";
 import styles from "./Header.scss";
 import { Link } from "react-router-dom";
@@ -18,19 +18,25 @@ import useLogin from "@src/hooks/useLogin";
 import { useHistory } from "react-router";
 import { fetchUserInfo } from "@src/store/reducers/UserReducer";
 import { YoutubeIcon } from "../common/icon/youtube";
+import { useOnClickOutside} from "usehooks-ts";
+import AutoCompleteSearch from "../common/AutoCompleteSearch";
 
 const cx = classNames.bind(styles);
 
 const Header: React.FC = () => {
+  const searchRef = useRef(null)
   const history = useHistory();
   const dispatch = useDispatch();
-
+  const [showAutoComplete, setShowAutoComplete] = useState<boolean>(false);
   const { userInfo, isUserInfoLoaded } = useSelector((store) => store.user);
   const onSearch = () => {
     history.push(URLInfo.getSearchResultUrl(keyword));
   };
+  const SelectTextComplete = (text: string) => {
+    history.push(URLInfo.getSearchResultUrl(text));
+  };
   const { keyword, setKeyword, onKeyPress, handleSearch } = useSearch({
-    onSearch
+    onSearch,
   });
   const [showCommunity, setShowCommunity] = useState(false);
   const [showProfile, setShowProfile] = useState<boolean>(false);
@@ -48,6 +54,23 @@ const Header: React.FC = () => {
     }
   };
 
+  const fakeComplete = [
+    "test1",
+    "test2",
+    "test3",
+    "test4",
+    "test5",
+    "test6",
+    "test7",
+    "test8",
+    "test9",
+    "test10",
+  ];
+
+  useOnClickOutside(searchRef, () => {
+    setShowAutoComplete(false);
+  });
+
   return (
     <div className={cx("header_wrap")}>
       <div className={cx("header_group")}>
@@ -58,7 +81,7 @@ const Header: React.FC = () => {
           </Link>
         </h1>
         <div className={cx("gnb")}>
-          <div className={cx("search_area")}>
+          <div className={cx("search_area")} ref={searchRef}>
             <input
               type="text"
               placeholder="작품(NFT)이름을 입력해주세요"
@@ -66,11 +89,19 @@ const Header: React.FC = () => {
               value={keyword}
               onKeyPress={onKeyPress}
               onChange={(e) => setKeyword(e.target.value)}
+              onFocus={() => {
+                setShowAutoComplete(true);
+              }}
             />
             <button className={cx("btn_search")} onClick={handleSearch}>
               <span className={cx("blind")}>Search</span>
               <IconSearchGray className={cx("ico_search")} />
             </button>
+            <AutoCompleteSearch show={showAutoComplete} data={fakeComplete} onClick={(e) => {
+              setShowAutoComplete(false);
+              SelectTextComplete(e);
+              setKeyword(e);
+            }} />
           </div>
           <ul className={cx("menu_list")}>
             <li className={cx("menu_item")}>

+ 10 - 10
src/containers/common/ArtistsScrollList.tsx

@@ -23,51 +23,51 @@ const dataFake: IArtist[] = [
     {
         id: 1,
         name: 'John Doe',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/20/300/300',
     },
     {
         id: 2,
         name: 'Kasper Henderson',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/21/300/300',
     },
     {
         id: 3,
         name: 'Cooper Lynn',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/22/300/300',
     },
     {
         id: 4,
         name: 'Iris Stein',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/23/300/300',
     },
     {
         id: 5,
         name: 'Leland Richards',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/24/300/300',
     },
     {
         id: 6,
         name: 'Octavia Norris',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/25/300/300',
     },
     {
         id: 7,
         name: 'Leland Richards',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/26/300/300',
     },
     {
         id: 8,
         name: 'Octavia Norris',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/27/300/300',
     },
     {
         id: 9,
         name: 'Leland Richards',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/28/300/300',
     },
     {
         id: 10,
         name: 'Octavia Norris',
-        thumbnail_image: 'https://picsum.photos/300/300',
+        thumbnail_image: 'https://picsum.photos/id/29/300/300',
     }
 ]

+ 24 - 14
src/containers/common/SalesRankingscrollList.tsx

@@ -9,74 +9,84 @@ export default function SalesRankingScrollList(props: ISalesRankingScrollListPro
   return (
     <>
       <div className={"mo_wrapper"}>
-        <MobileSalesRankingScrollList list={dataFake} />
+        <MobileSalesRankingScrollList list={dataRankingFake} />
       </div>
       <div className={"pc_wrapper"}>
-        <PCSalesRankingScrollList list={dataFake} />
+        <PCSalesRankingScrollList list={dataRankingFake} />
       </div>
     </>
   );
 }
 
-const dataFake: ISalesRanking[] = [
+export const dataRankingFake: ISalesRanking[] = [
   {
     id: 1,
+    rank: 1,
     name: "John Doe",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/10/300/300",
     total_revenue: 100000,
   },
   {
     id: 2,
-    name: "Kasper Henderson",
-    thumbnail_image: "https://picsum.photos/300/300",
+    rank: 2,
+    name: "Kasper Henderson Kasper Henderson Kasper Henderson",
+    thumbnail_image: "https://picsum.photos/id/11/300/300",
     total_revenue: 90000,
   },
   {
     id: 3,
+    rank: 3,
     name: "Cooper Lynn",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/12/300/300",
     total_revenue: 80000,
   },
   {
     id: 4,
+    rank: 4,
     name: "Iris Stein",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/13/300/300",
     total_revenue: 70000,
   },
   {
     id: 5,
+    rank: 5,
     name: "Leland Richards",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/14/300/300",
     total_revenue: 60000,
   },
   {
     id: 6,
+    rank: 6,
     name: "Octavia Norris",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/15/300/300",
     total_revenue: 50000,
   },
   {
     id: 7,
+    rank: 7,
     name: "Leland Richards",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/16/300/300",
     total_revenue: 40000,
   },
   {
     id: 8,
+    rank: 8,
     name: "Octavia Norris",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/17/300/300",
     total_revenue: 30000,
   },
   {
     id: 9,
+    rank: 9,
     name: "Leland Richards",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/18/300/300",
     total_revenue: 20000,
   },
   {
     id: 10,
+    rank: 10,
     name: "Octavia Norris",
-    thumbnail_image: "https://picsum.photos/300/300",
+    thumbnail_image: "https://picsum.photos/id/19/300/300",
     total_revenue: 10000,
   },
 ];

+ 30 - 0
src/index.scss

@@ -7,4 +7,34 @@ body {
 }
 body::-webkit-scrollbar {
   display: none; /* Chrome, Safari, Opera*/
+}
+
+::-webkit-scrollbar {
+  width: 5px;
+  height: 5px;
+}
+
+@media screen and (max-width: 1024px) {
+  ::-webkit-scrollbar {
+    width: 3px;
+    height: 3px;
+  }
+}
+  
+
+/* Track */
+::-webkit-scrollbar-track {
+  background: #f1f1f1;
+  border-radius: 10px; 
+}
+ 
+/* Handle */
+::-webkit-scrollbar-thumb {
+  background: #888; 
+  border-radius: 10px;
+}
+
+/* Handle on hover */
+::-webkit-scrollbar-thumb:hover {
+  background: #555; 
 }

+ 21 - 15
src/pages/Home.tsx

@@ -13,6 +13,8 @@ import Loading from '@src/components/common/Loading';
 import useMore from '@src/hooks/useMore';
 import ArtistsScrollList from '@src/containers/common/ArtistsScrollList';
 import SalesRankingScrollList from '@src/containers/common/SalesRankingscrollList';
+import { Link } from 'react-router-dom';
+import URLInfo from '@src/constants/URLInfo';
 
 const cx = classNames.bind(styles);
 
@@ -54,37 +56,37 @@ const Home: React.FC = () => {
   }, [location.pathname]);
 
   return (
-    <div className={cx('home')}>
+    <div className={cx("home")}>
       {isLoaded ? (
         <Loading />
       ) : (
         <>
           {!!data?.curating_list.length && (
-            <div className={cx('banner_group')}>
+            <div className={cx("banner_group")}>
               <BannerScrollList list={data.curating_list} />
             </div>
           )}
           {!!data?.special_bids.length && (
-            <div className={cx('home_group')}>
-              <strong className={cx('home_title')}>Special Bids 🌟</strong>
+            <div className={cx("home_group")}>
+              <strong className={cx("home_title")}>Special Bids 🌟</strong>
               <NFTScrollList list={data.special_bids} />
             </div>
           )}
           {!!data?.hot_bids.length && (
-            <div className={cx('home_group')}>
-              <strong className={cx('home_title')}>지금 뜨는 Bids 🚀</strong>
+            <div className={cx("home_group")}>
+              <strong className={cx("home_title")}>지금 뜨는 Bids 🚀</strong>
               <NFTScrollList list={data.hot_bids} />
             </div>
           )}
           {!!data?.time_auctions.length && (
-            <div className={cx('home_group')}>
-              <strong className={cx('home_title')}>타임옥션 🔥</strong>
+            <div className={cx("home_group")}>
+              <strong className={cx("home_title")}>타임옥션 🔥</strong>
               <NFTScrollList list={data.time_auctions} />
             </div>
           )}
           {!!data?.collections.length && (
-            <div className={cx('home_group')}>
-              <strong className={cx('home_title')}>인기 콜렉션 🎉</strong>
+            <div className={cx("home_group")}>
+              <strong className={cx("home_title")}>인기 콜렉션 🎉</strong>
               <CollectionScrollList list={data.collections} />
             </div>
           )}
@@ -92,18 +94,22 @@ const Home: React.FC = () => {
             <strong className={cx('home_title')}>탐색하기 🔍</strong>
             <ExploreContentContainer list={filterProps.exploreList} filterProps={filterProps} handler={filterHandler} onClickMore={onClickMore} showMore={showMore} isLoaded={isExploreListLoaded} />
           </div> */}
-          <div className={cx('home_group')}>
-            <strong className={cx('home_title')}>Registered Artists 🧑‍🎨</strong>
+          <div className={cx("home_group")}>
+            <strong className={cx("home_title")}>Registered Artists 🧑‍🎨</strong>
             <ArtistsScrollList />
           </div>
-          <div className={cx('home_group')}>
-            <strong className={cx('home_title')}>Sales Ranking 🏆 <a className={cx('see_more')}>Sea more</a></strong>
+          <div className={cx("home_group")}>
+            <strong className={cx("home_title")}>
+              Sales Ranking 🏆{" "}
+              <Link to={URLInfo.RANKING} className={cx("see_more")}>
+                See more
+              </Link>
+            </strong>
             <SalesRankingScrollList />
           </div>
         </>
       )}
     </div>
-
   );
 };
 

+ 1 - 1
src/pages/Login.tsx

@@ -82,7 +82,7 @@ const Login: React.FC<IOwnProps> = ({ }) => {
         <br />
         <button type="button" className={cx('btn', 'google')} onClick={() => handleClickLogin(ESNSType.GOOGLE)}>
           <img src="/static/img/png/ico_google.png" alt="" />
-          {selectedTab === ELoginTabType.REGISTER ? 'Login / Sign up with google ID' : 'Login / Sign up'}
+          {selectedTab === ELoginTabType.REGISTER ? 'Sign up with google ID' : 'Login with google ID'}
         </button>
         {/* <button type="button" className={cx('btn', 'kakao')}>
           <img src="/static/img/png/ico_kakao.png" alt="" />

+ 3 - 1
src/pages/Ranking.tsx

@@ -1,6 +1,8 @@
 import * as React from 'react';
 import classNames from 'classnames/bind';
 import styles from './Ranking.scss';
+import RankingTable from '@src/components/common/RankingTable';
+import { dataRankingFake } from '@src/containers/common/SalesRankingscrollList';
 
 const cx = classNames.bind(styles);
 
@@ -11,7 +13,7 @@ export default function Ranking (props: IRankingProps) {
   return (
     <div className={cx('ranking')}>
         <div className={cx('title')}>랭킹</div>
-        
+        <RankingTable data={dataRankingFake} />
     </div>
   );
 }

+ 5 - 0
yarn.lock

@@ -8910,6 +8910,11 @@ use@^3.1.0:
   resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
   integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
 
+usehooks-ts@^2.9.1:
+  version "2.9.1"
+  resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-2.9.1.tgz#953d3284851ffd097432379e271ce046a8180b37"
+  integrity sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA==
+
 util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"