diff --git a/docs/assets/highlight.css b/docs/assets/highlight.css index 964bdd709..0cf783fd9 100644 --- a/docs/assets/highlight.css +++ b/docs/assets/highlight.css @@ -9,6 +9,10 @@ --dark-hl-3: #CE9178; --light-hl-4: #CD3131; --dark-hl-4: #F44747; + --light-hl-5: #001080; + --dark-hl-5: #9CDCFE; + --light-hl-6: #795E26; + --dark-hl-6: #DCDCAA; --light-code-background: #FFFFFF; --dark-code-background: #1E1E1E; } @@ -19,6 +23,8 @@ --hl-2: var(--light-hl-2); --hl-3: var(--light-hl-3); --hl-4: var(--light-hl-4); + --hl-5: var(--light-hl-5); + --hl-6: var(--light-hl-6); --code-background: var(--light-code-background); } } @@ -28,6 +34,8 @@ --hl-2: var(--dark-hl-2); --hl-3: var(--dark-hl-3); --hl-4: var(--dark-hl-4); + --hl-5: var(--dark-hl-5); + --hl-6: var(--dark-hl-6); --code-background: var(--dark-code-background); } } @@ -37,6 +45,8 @@ --hl-2: var(--light-hl-2); --hl-3: var(--light-hl-3); --hl-4: var(--light-hl-4); + --hl-5: var(--light-hl-5); + --hl-6: var(--light-hl-6); --code-background: var(--light-code-background); } @@ -46,6 +56,8 @@ --hl-2: var(--dark-hl-2); --hl-3: var(--dark-hl-3); --hl-4: var(--dark-hl-4); + --hl-5: var(--dark-hl-5); + --hl-6: var(--dark-hl-6); --code-background: var(--dark-code-background); } @@ -54,4 +66,6 @@ .hl-2 { color: var(--hl-2); } .hl-3 { color: var(--hl-3); } .hl-4 { color: var(--hl-4); } +.hl-5 { color: var(--hl-5); } +.hl-6 { color: var(--hl-6); } pre, code { background: var(--code-background); } diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js index e1e8548c8..d4986d084 100644 --- a/docs/assets/navigation.js +++ b/docs/assets/navigation.js @@ -1 +1 @@ -window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAE61WTW/bIBj+L5yTeOvWTcut6mE77FC1x2pCxKYzCgYEuGk79b8Pf8WYDxtXUWTptXl4Pt4A9uM/oPGLBntwIwTYAIF0aW4qXtQUq8w83JW6ombkSFgB9lcbkJeEFhIzsH88Ty7wE6qpHgmeapZrwllH0Q9Pqb59ff/zvjlT5LyqOANhfjMoOMNMqwjgHrMCyzvJhfpNlM6cez9ZJwdHYuhMce+T+hCVHfuxXnjWiNPFhyOmWHOWDUVK8gF7LpKy+gpzIX2NsJib50R0Xt4ihbOxTMp0RltlWq6AzmyyoFJMtM1nJ6w1oSoTSCp8I8iDRrpW0YAtGE7BSaFi/F6woMKcoBeoQiSw6pqnjlN7Ds+Psa19kPyksAxQNpNgP5zUhROXR5vpGUmCDj5Xh5tSfrmapCwRKyiWgb+qoxrGk3z5ZK6zkS7I65gT0njJtVlWfbFbsjsAx2JVgGHWr8UgM0IuSSCiHVLyWuPYotl2yzlbfHH8ZIfMXH5fOnoI/Q1v4M2V1JgJ9bjZlsk9AedgvOuadYtkkVn1mhzWNLtOyhWUTMkXE40aCOduX/JW/YHc7bvWqtfkjr3c14tGDXjn6rbfH1vaYJEg8cw9EjZIaJAfj6ZfxRxvvH2ffnz/fG0f8X+xTmyepzKdOrs8IJScz6yGdjjtU66ZETrHplQtbPYwzpHUmRnALzuK3l6j3hocbHGwwV3EpMu57DbB6IU9rrLHpfkUVint7JCXNuuzxjyb33/oObC0XQ0AAA==" \ No newline at end of file +window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAE7VZbW/bNhD+L0Y/OtXWtR2Wb54RtEWbJouzoUUxEIrExIJlUaCopNnQ/z5K1AtFHslToiFwQFl3z3PP8e1If/t3Jeh3sTpdbcpytV6VsdjLhyNL65xWkfzy5V4cc/nmkBXp6vTVepXsszzltFidfhucU3ob17kYAW7rIhEZKxRE93oK9fb1j79/rAeIhB2PrFjB+PJlyQpaiMphcEWLlPJLzsrqU1aJyHi2lSk6MgITw8V8RuXBSTvmYz6xNxAji7sDzalgRdQ3MMp726GB0moz+ETaHDCZqechE8l+G1c0GpsoTYO11sTpAni8ykAmF2mrT1e4Z+xQRXVFt7KR0StasioTjD86RnpF+X2WuHPQ4hEAj3SeqCTcUaH8PTkIMw0oVg7Wmp4lmConk55r8Vg+JXGNGypryvOibIMfibJCUH4bJ2iuCY7B/ObtRBI8cOYqBL5DCR78ntR5EOvwXWDaKGlRJZ2oa6Z07+BkqEfSGqn/uNVhCmp3LYC7A9BlN2p7H6exoAa0lUgAWXP0DnyZ1R0+G701dgjMCnwAh1msjq5Flrt2/YQV95SLP2rKH6/ZTvCsuHNKbIEI5ILS6eeyNHvYwiEYvVfGvKKbMtuJWNRVQODUGCXNhe8QZTD4CLvenEzcOAOKkuZbI9bJZE8OrjFww9mD3AUAyMaJdK9ReXhg/KAj3cc8i29sLGU3hfzllVHNFlDVqXDal6iILjfvzsj52fXGHZQCGwy9Ue3jIs0pB4aQwurfo2KzwczQRjgQ1wiu5DKWxFnhJzEXL0MCegzSWM+T03i8D0pyEOjOXpHyO/odL6M1n6ej952hxWAxEVC9htc0NP5vWTbR05RxT2XlouTz6qjeDyriwvo0MhsI0DhdkDmrBXXNupPnHcvfFTeR/Nh5U6SE2Mcpad58UGmbQI+7VRjcIjB23HNZl/xei+YgPTbnqBi9tCZKE8SHkQYzusgNvZdq2GxjnkZae45izU1v47Y5iBIj2kXqDADW3V4Zae0n6G5vbrT2HN2uq6L5pM4ArLK6LcajZt9qjHeeY5Rp48+MKvInPtMn9LkSpnVmJ0xsggauI8ECDkOKru62m6trsr24+PjhjHw8+wot+Wg+A8ta9ddT1vPNF2n95+fr55MOUEHOD58X4+yhgrvbSbcjnuTNnIjLzN2nnSVpLIm0nDOFwRsBJ3Dn5LsS0GbyFa3kvNevI5tLojC87mtQ/fTbrz+/0TvojgrkYmSxTV29k4oQzphnVrWvcRftjYdvHCmo1sx/UJNDzFn7yHfhcdOeBNT/pUcOBI0YO/0qFxg4ELrpihg3vYtn0EBMmqd3zJx0y/Zf54EeGOzm7DA6qiPsEdfBYASsjnh5/A9wXNCB1amrsVtkxJuYrqE/M9SFo0QEOIbHeCoPaREiSmW5dLA2ajjm/gAWvchS/5kqCp6euqkeWSuFoX44CJIs9VSLBF46kKuTNTvmsoLscD0+/IppPD83A8OPkMbznIz4fvZcKBpvdFYlP1Q4maBH7041javfyBu3JTetAAti/xorCnSSLZoR47mL9YRo4RXGhe1evOXff8R+2Lq0IQAA" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js index 1dad9bde7..b1b46c3f1 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAAE61ZTW/bOBD9Lzqrskn6M7eih90F9lC0wF6CQFBsJREiS4IkN9sN/N93qA9rRuLQVJtDYtIavpl5j0OK9LtX5m+Vd3f/7r0m2dG7k76XRafYu/M+F4Xne+cyhfYpP57TuFrAd8FLfUrhwSGNqiqGoZ538fvRm9V1+DF+is5pfYV4OmeHOsmzFqR7agDzvSIq46zuIhiwh8gO+emUZwv4KPIMTKvFtzg7xuXXMi+qv5OqHvcnebQI4YAQjkaM+65Zc46H7Oe7vh0K4mw+N24Mf3+N07iG7/qGA6e96bXhyuLEh42+qReLOytT0xwduXlL6sPLl6iKUdOFn6sxajpzNPVkZcnoy+rWzpUxZwtf5zpJqwUgVvHnIvleR/W54jhqbENq68oL42HCjdHHTZdTTox5mXg4Rcm0aPSX1szQ+PzwWi0e9Xodl1Mg/TTsnloR1QD5lpevCOtHVCbR4xStNbOzQaPj43+JsmMal1PpW5f9Y9cMJnDjHAZAHnmSxhWVz6MoIe5DPTSCG5n1dkNjbq79wD9v5WxxNcZwYcOSqomfMj/XEMqn6ZrxR/ao/yYEtSPCcLpqgbX+c619DD4U/G14swtExO2c5jHxtWXyS1QecXsGM2gUbrsyZXLqwhjn1h6CE5McJ7/EbPOmg9rzmW1exVB7JrPM2998t/YQ5jA74cTGbFfrn1LtNyoSlsDOMNSGIRjad7PlfivW0kpW/bOwwc/mY5KJUbbnuHZTbhIQHfnbMU2kCMMyz/kJ3Dx13UK+6UGGfYOCNVZOiXSxWaI/RGW9gEfxv0Ea/feTS0ObhY1ZqM0+KJ8xqnti47AtGd5O7sPz+qWU3LLJSzgcuiTVGn58blNc9xSnwV8efK/penfv3g94CLUM9jJQwR4AnpI4PerrjzY4v3mp15AP3bN/4kOdl9qiNVksPf9+6SsVyJV8ePDv+xHNg+aLxkxAT5jMBDGT0JMmM0nMFPSUyUwRsxX0ViazFTFbQ29tMlsTsw30NiazDTHbQm9rMtsSsx30diazHTEDUe73JrM9pVezLYw6iJEQjRJmKagWQnMujGoIKofQtAujIIIqIjTzwqiJoKIITb4wyiKoLkLzL4zKCCqN0BKIrS/WwVbufLHz5SqA7ZeOoToJrYcwSiCoVGJP0OXSiE51k1ocaVRDUt2koOjShC5H1dSUk/LlNtitBbWkCkrVocNCsBYADeQE+83Gl+uuRUdTVeWK90NVlVo6adRKUlWllk4aC0lSVaUWTFMigs1qRy2pllILJo1aSqql3POYVEGlZVLGylNUQSVYTEV1U1ocZZwVarQQKh6z1ahZ72Ghr+PjX+26Dyt3pK+y372w2wmW/V707i3h3+UyrPu616PSl+hnOOg96/PlgAMFdQWCMnJF6l7+Dvqgg9oYWaIQoYRmIuu3StwmyHJAhvJxRS6bS+NCXxo36KM+8YAcOONX/dVrdb36HRBXA+LKHbG5lTzoC8qhiVE3A+rGjoqu+OBdveouFgckNA12DNL11xA0e5DEzCg4WnAyouhhJWGGj6brHnnkAh1usdBAJIDgFBgOiijKNYpSMQPbe1HkDc99rj5Hl6FoNKaV43V8FYmGKzScjfjmDSACRBQITih+aiHJuGWgc094Xznwzi09iEDJ0c/NSsSebIrf9yQ3YXrajKyh6S246rSsQSgOLv2yPYag4FEZy20X/L79VKL7tKLRFLbjzcHvlnK/W3h9XpvR0R8FiVAlSwxz9EYwaF5JbikwnG8Rw6hKFTdN+DMlAkLzTXEbhmlXQIXF1ZV54UcUcpt2/8MIkhNta8IYJrx5FEkRp0kGRvcPl8v/AH6un1wfAAA="; \ No newline at end of file +window.searchData = "data:application/octet-stream;base64,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"; \ No newline at end of file diff --git a/docs/functions/App.default.html b/docs/functions/App.default.html index 95511263e..8b967a824 100644 --- a/docs/functions/App.default.html +++ b/docs/functions/App.default.html @@ -1 +1 @@ -default | react-shopping-cart
\ No newline at end of file +default | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/common_components_RenderPropsList_RenderPropsList.RenderPropsList.html b/docs/functions/common_components_RenderPropsList_RenderPropsList.RenderPropsList.html index 9398fe0b7..e9da29c32 100644 --- a/docs/functions/common_components_RenderPropsList_RenderPropsList.RenderPropsList.html +++ b/docs/functions/common_components_RenderPropsList_RenderPropsList.RenderPropsList.html @@ -1,2 +1,2 @@ RenderPropsList | react-shopping-cart
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/functions/common_components_Skeleton_Skeleton.Skeleton.html b/docs/functions/common_components_Skeleton_Skeleton.Skeleton.html index 31c1e858b..923d380c0 100644 --- a/docs/functions/common_components_Skeleton_Skeleton.Skeleton.html +++ b/docs/functions/common_components_Skeleton_Skeleton.Skeleton.html @@ -1 +1 @@ -Skeleton | react-shopping-cart
\ No newline at end of file +Skeleton | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/common_components_SwitchCase_SwitchCase.SwitchCase.html b/docs/functions/common_components_SwitchCase_SwitchCase.SwitchCase.html index 626e81fd5..eba9790cf 100644 --- a/docs/functions/common_components_SwitchCase_SwitchCase.SwitchCase.html +++ b/docs/functions/common_components_SwitchCase_SwitchCase.SwitchCase.html @@ -1,3 +1,3 @@ SwitchCase | react-shopping-cart
  • Type Parameters

    • T extends string | number

    Parameters

    • __namedParameters: SwitchCaseProps<T>

    Returns ReactNode

    Summary

    switch문의 컴포넌트 버전

    Detail

    value의 case에 해당하는 컴포넌트 렌더링

    -
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/functions/common_hooks_useCookieRepository_service.getCookie.html b/docs/functions/common_hooks_useCookieRepository_service.getCookie.html new file mode 100644 index 000000000..5d2b4f280 --- /dev/null +++ b/docs/functions/common_hooks_useCookieRepository_service.getCookie.html @@ -0,0 +1,3 @@ +getCookie | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/common_hooks_useCookieRepository_service.setCookie.html b/docs/functions/common_hooks_useCookieRepository_service.setCookie.html new file mode 100644 index 000000000..6994ba1d3 --- /dev/null +++ b/docs/functions/common_hooks_useCookieRepository_service.setCookie.html @@ -0,0 +1,3 @@ +setCookie | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/common_hooks_useCookieRepository_useCookieRepository.useCookie.html b/docs/functions/common_hooks_useCookieRepository_useCookieRepository.useCookie.html new file mode 100644 index 000000000..b9629aa6d --- /dev/null +++ b/docs/functions/common_hooks_useCookieRepository_useCookieRepository.useCookie.html @@ -0,0 +1,2 @@ +useCookie | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/common_module_store_store.createStore.html b/docs/functions/common_module_store_store.createStore.html new file mode 100644 index 000000000..5dd5fb1f4 --- /dev/null +++ b/docs/functions/common_module_store_store.createStore.html @@ -0,0 +1,2 @@ +createStore | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/common_module_store_useStore.useStore.html b/docs/functions/common_module_store_useStore.useStore.html new file mode 100644 index 000000000..5bb9f125c --- /dev/null +++ b/docs/functions/common_module_store_useStore.useStore.html @@ -0,0 +1,2 @@ +useStore | react-shopping-cart
  • Type Parameters

    • T

    Parameters

    Returns readonly [T, ((next) => void)]

    Summary

    스토어를 리액트에서 상태로 사용할 수 있도록 도와주는 hook

    +
\ No newline at end of file diff --git a/docs/functions/common_utils_convertQueryToString.convertQueryToString.html b/docs/functions/common_utils_convertQueryToString.convertQueryToString.html new file mode 100644 index 000000000..da2871db1 --- /dev/null +++ b/docs/functions/common_utils_convertQueryToString.convertQueryToString.html @@ -0,0 +1,2 @@ +convertQueryToString | react-shopping-cart
  • Parameters

    • query: Record<string, string | number | boolean>

    Returns string

    Summary

    object를 key=value 형태의 string으로로 변환한다.

    +
\ No newline at end of file diff --git a/docs/functions/common_utils_parseApiStatus.parseApiStatus.html b/docs/functions/common_utils_parseApiStatus.parseApiStatus.html index 31527bba7..0e7cca843 100644 --- a/docs/functions/common_utils_parseApiStatus.parseApiStatus.html +++ b/docs/functions/common_utils_parseApiStatus.parseApiStatus.html @@ -1 +1 @@ -parseApiStatus | react-shopping-cart
  • Parameters

    • __namedParameters: {
          isError: boolean;
          isLoading: boolean;
      }
      • isError: boolean
      • isLoading: boolean

    Returns "success" | "error" | "loading"

\ No newline at end of file +parseApiStatus | react-shopping-cart
  • Parameters

    • __namedParameters: {
          isError: boolean;
          isLoading: boolean;
      }
      • isError: boolean
      • isLoading: boolean

    Returns "success" | "error" | "loading"

\ No newline at end of file diff --git a/docs/functions/routes__common_components_Gnb_Gnb.Gnb.html b/docs/functions/routes__common_components_Gnb_Gnb.Gnb.html index e51043dc8..8296cf22d 100644 --- a/docs/functions/routes__common_components_Gnb_Gnb.Gnb.html +++ b/docs/functions/routes__common_components_Gnb_Gnb.Gnb.html @@ -1,3 +1,3 @@ Gnb | react-shopping-cart
  • Returns Element

    Summary

    공통으로 사용하는 네비게이션 바

    Detail

    메인페이지, 장바구니, 주문목록 페이지 라우팅

    -
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/functions/routes__common_components_MoreButton_MoreButton.MoreButton.html b/docs/functions/routes__common_components_MoreButton_MoreButton.MoreButton.html new file mode 100644 index 000000000..a062e580d --- /dev/null +++ b/docs/functions/routes__common_components_MoreButton_MoreButton.MoreButton.html @@ -0,0 +1,9 @@ +MoreButton | react-shopping-cart

Properties

$$typeof: symbol
defaultProps?: Partial<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & RefAttributes<HTMLButtonElement>>
displayName?: string

Used in debugging messages. You might want to set it +explicitly if you want to display a different name for +debugging purposes.

+
propTypes?: WeakValidationMap<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & RefAttributes<HTMLButtonElement>>
\ No newline at end of file diff --git a/docs/functions/routes__common_components_ProductCard_ProductCard.ProductCard.html b/docs/functions/routes__common_components_ProductCard_ProductCard.ProductCard.html index c30ca1af2..b9a558b08 100644 --- a/docs/functions/routes__common_components_ProductCard_ProductCard.ProductCard.html +++ b/docs/functions/routes__common_components_ProductCard_ProductCard.ProductCard.html @@ -1 +1 @@ -ProductCard | react-shopping-cart
\ No newline at end of file +ProductCard | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/routes__common_components_ProductList_ProductList.ProductList.html b/docs/functions/routes__common_components_ProductList_ProductList.ProductList.html index 01e33152b..5430e6f4e 100644 --- a/docs/functions/routes__common_components_ProductList_ProductList.ProductList.html +++ b/docs/functions/routes__common_components_ProductList_ProductList.ProductList.html @@ -1,2 +1,2 @@ ProductList | react-shopping-cart
\ No newline at end of file +
\ No newline at end of file diff --git a/docs/functions/routes__common_store_cartListStore_cartListStore.useCartListStore.html b/docs/functions/routes__common_store_cartListStore_cartListStore.useCartListStore.html new file mode 100644 index 000000000..91fc6c138 --- /dev/null +++ b/docs/functions/routes__common_store_cartListStore_cartListStore.useCartListStore.html @@ -0,0 +1 @@ +useCartListStore | react-shopping-cart
  • Returns {
        actions: {
            changeProductCount: ((e, product) => void);
            decreaseCount: ((id) => void);
            deleteAllProducts: (() => void);
            deleteProduct: ((id) => void);
            increaseCount: ((id) => void);
            saveProduct: ((id) => void);
        };
        cartList: CartItem[];
    }

    • actions: {
          changeProductCount: ((e, product) => void);
          decreaseCount: ((id) => void);
          deleteAllProducts: (() => void);
          deleteProduct: ((id) => void);
          increaseCount: ((id) => void);
          saveProduct: ((id) => void);
      }
      • changeProductCount: ((e, product) => void)
          • (e, product): void
          • Parameters

            • e: ChangeEvent<HTMLInputElement>
            • product: CartItem

            Returns void

      • decreaseCount: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • deleteAllProducts: (() => void)
          • (): void
          • Returns void

      • deleteProduct: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • increaseCount: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • saveProduct: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

    • cartList: CartItem[]
\ No newline at end of file diff --git a/docs/functions/routes__product_list_api.getProductList.html b/docs/functions/routes__product_list_api.getProductList.html index db64377e1..695e5620a 100644 --- a/docs/functions/routes__product_list_api.getProductList.html +++ b/docs/functions/routes__product_list_api.getProductList.html @@ -1,2 +1,2 @@ -getProductList | react-shopping-cart
\ No newline at end of file +getProductList | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/routes_cart__cart_list_api.getCartList.html b/docs/functions/routes_cart__cart_list_api.getCartList.html new file mode 100644 index 000000000..d94002571 --- /dev/null +++ b/docs/functions/routes_cart__cart_list_api.getCartList.html @@ -0,0 +1,2 @@ +getCartList | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/routes_cart__useCartVM.useCartVM.html b/docs/functions/routes_cart__useCartVM.useCartVM.html new file mode 100644 index 000000000..1b69986fa --- /dev/null +++ b/docs/functions/routes_cart__useCartVM.useCartVM.html @@ -0,0 +1,2 @@ +useCartVM | react-shopping-cart
  • Returns {
        actions: {
            changeProductCount: ((e, product) => void);
            decreaseCount: ((id) => void);
            deleteAllProducts: (() => void);
            deleteProduct: ((id) => void);
            increaseCount: ((id) => void);
            isCheckedProduct: ((id) => undefined | boolean);
            saveProduct: ((id) => void);
            toggleAll: (() => void);
            toggleProduct: ((id) => void);
        };
        cartsQuery: UseQueryResult<{
            hasProduct: boolean;
            list: {
                count: number;
                id: number;
                imageUrl: string;
                name: string;
                price: number;
                totalPrice: number;
            }[];
        }, Error>;
        computed: {
            isAllProductChecked: boolean;
            paymentTotal: undefined | string;
            totalSelectedCount: number;
        };
    }

    • actions: {
          changeProductCount: ((e, product) => void);
          decreaseCount: ((id) => void);
          deleteAllProducts: (() => void);
          deleteProduct: ((id) => void);
          increaseCount: ((id) => void);
          isCheckedProduct: ((id) => undefined | boolean);
          saveProduct: ((id) => void);
          toggleAll: (() => void);
          toggleProduct: ((id) => void);
      }
      • changeProductCount: ((e, product) => void)
          • (e, product): void
          • Parameters

            • e: ChangeEvent<HTMLInputElement>
            • product: CartItem

            Returns void

      • decreaseCount: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • deleteAllProducts: (() => void)
          • (): void
          • Returns void

      • deleteProduct: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • increaseCount: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • isCheckedProduct: ((id) => undefined | boolean)
          • (id): undefined | boolean
          • Parameters

            • id: number

            Returns undefined | boolean

      • saveProduct: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

      • toggleAll: (() => void)
          • (): void
          • Returns void

      • toggleProduct: ((id) => void)
          • (id): void
          • Parameters

            • id: number

            Returns void

    • cartsQuery: UseQueryResult<{
          hasProduct: boolean;
          list: {
              count: number;
              id: number;
              imageUrl: string;
              name: string;
              price: number;
              totalPrice: number;
          }[];
      }, Error>
    • computed: {
          isAllProductChecked: boolean;
          paymentTotal: undefined | string;
          totalSelectedCount: number;
      }
      • isAllProductChecked: boolean
      • paymentTotal: undefined | string
      • totalSelectedCount: number

    Summary

    카트 페이지의 view model

    +
\ No newline at end of file diff --git a/docs/functions/routes_products__id__common_components_ProductSkeleton_ProductSkeleton.ProductSkeleton.html b/docs/functions/routes_products__id__common_components_ProductSkeleton_ProductSkeleton.ProductSkeleton.html new file mode 100644 index 000000000..a812e310d --- /dev/null +++ b/docs/functions/routes_products__id__common_components_ProductSkeleton_ProductSkeleton.ProductSkeleton.html @@ -0,0 +1 @@ +ProductSkeleton | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/routes_products__id__common_components_Product_Product.Product.html b/docs/functions/routes_products__id__common_components_Product_Product.Product.html new file mode 100644 index 000000000..3045e5cda --- /dev/null +++ b/docs/functions/routes_products__id__common_components_Product_Product.Product.html @@ -0,0 +1 @@ +Product | react-shopping-cart
\ No newline at end of file diff --git a/docs/functions/routes_products__id__product_item_api.getProduct.html b/docs/functions/routes_products__id__product_item_api.getProduct.html new file mode 100644 index 000000000..4060a21cb --- /dev/null +++ b/docs/functions/routes_products__id__product_item_api.getProduct.html @@ -0,0 +1,2 @@ +getProduct | react-shopping-cart
\ No newline at end of file diff --git a/docs/interfaces/common_hooks_useCookieRepository_type.CookieOptions.html b/docs/interfaces/common_hooks_useCookieRepository_type.CookieOptions.html new file mode 100644 index 000000000..45e388a09 --- /dev/null +++ b/docs/interfaces/common_hooks_useCookieRepository_type.CookieOptions.html @@ -0,0 +1,14 @@ +CookieOptions | react-shopping-cart
interface CookieOptions {
    domain?: string;
    expires?: Date;
    path?: string;
    [key: string]: unknown;
}

Indexable

[key: string]: unknown

기타 키 정의

+

Properties

Properties

domain?: string

Default

현재 도메인
+
+

Description

미지정시 하위 도메인 접근 불가

+
expires?: Date

Summary

쿠키의

+

Default

세션 쿠기(브라우저 종료시 자동 삭제)
+
+

Description

지정시 영구 쿠기(지정 날짜까지 유지)

+
path?: string

Default

"/"
+
+
\ No newline at end of file diff --git a/docs/interfaces/common_module_store_store.Store.html b/docs/interfaces/common_module_store_store.Store.html new file mode 100644 index 000000000..33741cfac --- /dev/null +++ b/docs/interfaces/common_module_store_store.Store.html @@ -0,0 +1,4 @@ +Store | react-shopping-cart
interface Store<T> {
    getState: (() => T);
    setState: ((next) => void);
    subscribe: ((callback) => (() => void));
}

Type Parameters

  • T

Properties

getState: (() => T)

Type declaration

    • (): T
    • Returns T

setState: ((next) => void)

Type declaration

    • (next): void
    • Parameters

      • next: T | ((prev) => T)

      Returns void

subscribe: ((callback) => (() => void))

Type declaration

    • (callback): (() => void)
    • Parameters

      • callback: (() => void)
          • (): void
          • Returns void

      Returns (() => void)

        • (): void
        • Returns void

\ No newline at end of file diff --git a/docs/interfaces/routes__product_list_api.Product.html b/docs/interfaces/routes__product_list_api.Product.html new file mode 100644 index 000000000..61760b71f --- /dev/null +++ b/docs/interfaces/routes__product_list_api.Product.html @@ -0,0 +1,5 @@ +Product | react-shopping-cart
interface Product {
    id: number;
    imageUrl: string;
    name: string;
    price: number;
}

Properties

Properties

id: number
imageUrl: string
name: string
price: number
\ No newline at end of file diff --git a/docs/interfaces/routes_cart__cart_list_api.Product.html b/docs/interfaces/routes_cart__cart_list_api.Product.html new file mode 100644 index 000000000..8feb43b29 --- /dev/null +++ b/docs/interfaces/routes_cart__cart_list_api.Product.html @@ -0,0 +1,5 @@ +Product | react-shopping-cart
interface Product {
    id: number;
    imageUrl: string;
    name: string;
    price: number;
}

Properties

Properties

id: number
imageUrl: string
name: string
price: number
\ No newline at end of file diff --git a/docs/interfaces/routes_products__id__product_item_api.Product.html b/docs/interfaces/routes_products__id__product_item_api.Product.html new file mode 100644 index 000000000..beea662e2 --- /dev/null +++ b/docs/interfaces/routes_products__id__product_item_api.Product.html @@ -0,0 +1,5 @@ +Product | react-shopping-cart
interface Product {
    id: number;
    imageUrl: string;
    name: string;
    price: number;
}

Properties

Properties

id: number
imageUrl: string
name: string
price: number
\ No newline at end of file diff --git a/docs/modules/App.html b/docs/modules/App.html index b27da97a3..e7ee6718a 100644 --- a/docs/modules/App.html +++ b/docs/modules/App.html @@ -1,2 +1,2 @@ -App | react-shopping-cart

Index

Functions

default +App | react-shopping-cart

Index

Functions

\ No newline at end of file diff --git a/docs/modules/common_components_RenderPropsList_RenderPropsList.html b/docs/modules/common_components_RenderPropsList_RenderPropsList.html index bebd8335e..0fd289ce3 100644 --- a/docs/modules/common_components_RenderPropsList_RenderPropsList.html +++ b/docs/modules/common_components_RenderPropsList_RenderPropsList.html @@ -1,2 +1,2 @@ -common/components/RenderPropsList/RenderPropsList | react-shopping-cart

Module common/components/RenderPropsList/RenderPropsList

Index

Functions

RenderPropsList +common/components/RenderPropsList/RenderPropsList | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_components_Skeleton_Skeleton.html b/docs/modules/common_components_Skeleton_Skeleton.html index 6bf17ee45..52b238139 100644 --- a/docs/modules/common_components_Skeleton_Skeleton.html +++ b/docs/modules/common_components_Skeleton_Skeleton.html @@ -1,2 +1,2 @@ -common/components/Skeleton/Skeleton | react-shopping-cart

Module common/components/Skeleton/Skeleton

Index

Functions

Skeleton +common/components/Skeleton/Skeleton | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_components_SwitchCase_SwitchCase.html b/docs/modules/common_components_SwitchCase_SwitchCase.html index e946d660a..1040c5efa 100644 --- a/docs/modules/common_components_SwitchCase_SwitchCase.html +++ b/docs/modules/common_components_SwitchCase_SwitchCase.html @@ -1,2 +1,2 @@ -common/components/SwitchCase/SwitchCase | react-shopping-cart

Module common/components/SwitchCase/SwitchCase

Index

Functions

SwitchCase +common/components/SwitchCase/SwitchCase | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_hooks_useCookieRepository_service.html b/docs/modules/common_hooks_useCookieRepository_service.html new file mode 100644 index 000000000..5e9a89745 --- /dev/null +++ b/docs/modules/common_hooks_useCookieRepository_service.html @@ -0,0 +1,3 @@ +common/hooks/useCookieRepository/service | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_hooks_useCookieRepository_type.html b/docs/modules/common_hooks_useCookieRepository_type.html new file mode 100644 index 000000000..27192ad49 --- /dev/null +++ b/docs/modules/common_hooks_useCookieRepository_type.html @@ -0,0 +1,2 @@ +common/hooks/useCookieRepository/type | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_hooks_useCookieRepository_useCookieRepository.html b/docs/modules/common_hooks_useCookieRepository_useCookieRepository.html new file mode 100644 index 000000000..a0da16d2f --- /dev/null +++ b/docs/modules/common_hooks_useCookieRepository_useCookieRepository.html @@ -0,0 +1,2 @@ +common/hooks/useCookieRepository/useCookieRepository | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_module_store_store.html b/docs/modules/common_module_store_store.html new file mode 100644 index 000000000..85eedcd30 --- /dev/null +++ b/docs/modules/common_module_store_store.html @@ -0,0 +1,3 @@ +common/module/store/store | react-shopping-cart

Module common/module/store/store

Index

Interfaces

Functions

\ No newline at end of file diff --git a/docs/modules/common_module_store_useStore.html b/docs/modules/common_module_store_useStore.html new file mode 100644 index 000000000..f76b85e89 --- /dev/null +++ b/docs/modules/common_module_store_useStore.html @@ -0,0 +1,2 @@ +common/module/store/useStore | react-shopping-cart

Module common/module/store/useStore

Index

Functions

\ No newline at end of file diff --git a/docs/modules/common_utils_convertQueryToString.html b/docs/modules/common_utils_convertQueryToString.html new file mode 100644 index 000000000..be7d7c583 --- /dev/null +++ b/docs/modules/common_utils_convertQueryToString.html @@ -0,0 +1,2 @@ +common/utils/convertQueryToString | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/common_utils_parseApiStatus.html b/docs/modules/common_utils_parseApiStatus.html index 808e22da3..64647759b 100644 --- a/docs/modules/common_utils_parseApiStatus.html +++ b/docs/modules/common_utils_parseApiStatus.html @@ -1,2 +1,2 @@ -common/utils/parseApiStatus | react-shopping-cart

Module common/utils/parseApiStatus

Index

Functions

parseApiStatus +common/utils/parseApiStatus | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/main.html b/docs/modules/main.html index 91e1ff148..4197ea19a 100644 --- a/docs/modules/main.html +++ b/docs/modules/main.html @@ -1 +1 @@ -main | react-shopping-cart
\ No newline at end of file +main | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/mocks_browser.html b/docs/modules/mocks_browser.html index 51477f477..3d335e80c 100644 --- a/docs/modules/mocks_browser.html +++ b/docs/modules/mocks_browser.html @@ -1,2 +1,2 @@ -mocks/browser | react-shopping-cart

Index

Variables

worker +mocks/browser | react-shopping-cart

Index

Variables

\ No newline at end of file diff --git a/docs/modules/mocks_const.html b/docs/modules/mocks_const.html new file mode 100644 index 000000000..4e2e57aa1 --- /dev/null +++ b/docs/modules/mocks_const.html @@ -0,0 +1,2 @@ +mocks/const | react-shopping-cart

Index

Variables

\ No newline at end of file diff --git a/docs/modules/mocks_handlers.html b/docs/modules/mocks_handlers.html index 0915aee86..ee9591300 100644 --- a/docs/modules/mocks_handlers.html +++ b/docs/modules/mocks_handlers.html @@ -1,2 +1,2 @@ -mocks/handlers | react-shopping-cart

Index

Variables

handlers +mocks/handlers | react-shopping-cart

Index

Variables

\ No newline at end of file diff --git a/docs/modules/mocks_products_cart_handlers.html b/docs/modules/mocks_products_cart_handlers.html new file mode 100644 index 000000000..813722a70 --- /dev/null +++ b/docs/modules/mocks_products_cart_handlers.html @@ -0,0 +1,2 @@ +mocks/products/cart.handlers | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/mocks_products_index_handlers.html b/docs/modules/mocks_products_index_handlers.html new file mode 100644 index 000000000..445908c35 --- /dev/null +++ b/docs/modules/mocks_products_index_handlers.html @@ -0,0 +1,2 @@ +mocks/products/index.handlers | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/mocks_products_products_handlers.html b/docs/modules/mocks_products_products_handlers.html index 54d04372b..f530cc4a0 100644 --- a/docs/modules/mocks_products_products_handlers.html +++ b/docs/modules/mocks_products_products_handlers.html @@ -1,2 +1,2 @@ -mocks/products/products.handlers | react-shopping-cart

Module mocks/products/products.handlers

Index

Variables

productsHandlers +mocks/products/products.handlers | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/mocks_products_products_repository.html b/docs/modules/mocks_products_products_repository.html new file mode 100644 index 000000000..d2c6b6eb1 --- /dev/null +++ b/docs/modules/mocks_products_products_repository.html @@ -0,0 +1,2 @@ +mocks/products/products.repository | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes___root.html b/docs/modules/routes___root.html index c6ec65d70..6904e457c 100644 --- a/docs/modules/routes___root.html +++ b/docs/modules/routes___root.html @@ -1,2 +1,2 @@ -routes/__root | react-shopping-cart

Index

Variables

Route +routes/__root | react-shopping-cart

Index

Variables

\ No newline at end of file diff --git a/docs/modules/routes__common_components_MoreButton_MoreButton.html b/docs/modules/routes__common_components_MoreButton_MoreButton.html new file mode 100644 index 000000000..61ec7b1e3 --- /dev/null +++ b/docs/modules/routes__common_components_MoreButton_MoreButton.html @@ -0,0 +1,2 @@ +routes/-common/components/MoreButton/MoreButton | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes__common_components_ProductCard_ProductCard.html b/docs/modules/routes__common_components_ProductCard_ProductCard.html index 4b149c1e3..0ea4460d7 100644 --- a/docs/modules/routes__common_components_ProductCard_ProductCard.html +++ b/docs/modules/routes__common_components_ProductCard_ProductCard.html @@ -1,2 +1,2 @@ -routes/-common/components/ProductCard/ProductCard | react-shopping-cart

Module routes/-common/components/ProductCard/ProductCard

Index

Functions

ProductCard +routes/-common/components/ProductCard/ProductCard | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes__common_components_ProductList_ProductList.html b/docs/modules/routes__common_components_ProductList_ProductList.html index 9b0d414b2..63501a0d4 100644 --- a/docs/modules/routes__common_components_ProductList_ProductList.html +++ b/docs/modules/routes__common_components_ProductList_ProductList.html @@ -1,2 +1,2 @@ -routes/-common/components/ProductList/ProductList | react-shopping-cart

Module routes/-common/components/ProductList/ProductList

Index

Functions

ProductList +routes/-common/components/ProductList/ProductList | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes__common_store_cartListStore_cartListStore.html b/docs/modules/routes__common_store_cartListStore_cartListStore.html new file mode 100644 index 000000000..5bfe96644 --- /dev/null +++ b/docs/modules/routes__common_store_cartListStore_cartListStore.html @@ -0,0 +1,2 @@ +routes/-common/store/cartListStore/cartListStore | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes__common_store_cartListStore_const.html b/docs/modules/routes__common_store_cartListStore_const.html new file mode 100644 index 000000000..eb8f93bf2 --- /dev/null +++ b/docs/modules/routes__common_store_cartListStore_const.html @@ -0,0 +1,4 @@ +routes/-common/store/cartListStore/const | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes__product_list_api.html b/docs/modules/routes__product_list_api.html index bc2d43e90..1e248288c 100644 --- a/docs/modules/routes__product_list_api.html +++ b/docs/modules/routes__product_list_api.html @@ -1,3 +1,4 @@ -routes/-product-list.api | react-shopping-cart

Module routes/-product-list.api

Index

Type Aliases

ProductList +routes/-product-list.api | react-shopping-cart

Module routes/-product-list.api

Index

Interfaces

Type Aliases

Functions

\ No newline at end of file diff --git a/docs/modules/routes_cart__cart_list_api.html b/docs/modules/routes_cart__cart_list_api.html new file mode 100644 index 000000000..44b6a01b0 --- /dev/null +++ b/docs/modules/routes_cart__cart_list_api.html @@ -0,0 +1,4 @@ +routes/cart/-cart-list.api | react-shopping-cart

Module routes/cart/-cart-list.api

Index

Interfaces

Type Aliases

Functions

\ No newline at end of file diff --git a/docs/modules/routes_cart__useCartVM.html b/docs/modules/routes_cart__useCartVM.html new file mode 100644 index 000000000..7a1443cae --- /dev/null +++ b/docs/modules/routes_cart__useCartVM.html @@ -0,0 +1,2 @@ +routes/cart/-useCartVM | react-shopping-cart

Module routes/cart/-useCartVM

Index

Functions

\ No newline at end of file diff --git a/docs/modules/routes_cart_index_lazy.html b/docs/modules/routes_cart_index_lazy.html index 737e16cd7..ffa17d4d9 100644 --- a/docs/modules/routes_cart_index_lazy.html +++ b/docs/modules/routes_cart_index_lazy.html @@ -1,2 +1,2 @@ -routes/cart/index.lazy | react-shopping-cart

Module routes/cart/index.lazy

Index

Variables

Route +routes/cart/index.lazy | react-shopping-cart

Module routes/cart/index.lazy

Index

Variables

\ No newline at end of file diff --git a/docs/modules/routes_index_lazy.html b/docs/modules/routes_index_lazy.html index abaeabc48..7b545281f 100644 --- a/docs/modules/routes_index_lazy.html +++ b/docs/modules/routes_index_lazy.html @@ -1,2 +1,2 @@ -routes/index.lazy | react-shopping-cart

Module routes/index.lazy

Index

Variables

Route +routes/index.lazy | react-shopping-cart

Module routes/index.lazy

Index

Variables

\ No newline at end of file diff --git a/docs/modules/routes_orders_index_lazy.html b/docs/modules/routes_orders_index_lazy.html index b3031bdb1..2a19e282a 100644 --- a/docs/modules/routes_orders_index_lazy.html +++ b/docs/modules/routes_orders_index_lazy.html @@ -1,2 +1,2 @@ -routes/orders/index.lazy | react-shopping-cart

Module routes/orders/index.lazy

Index

Variables

Route +routes/orders/index.lazy | react-shopping-cart

Module routes/orders/index.lazy

Index

Variables

\ No newline at end of file diff --git a/docs/modules/routes_products__id__common_components_ProductSkeleton_ProductSkeleton.html b/docs/modules/routes_products__id__common_components_ProductSkeleton_ProductSkeleton.html new file mode 100644 index 000000000..70f1c71c5 --- /dev/null +++ b/docs/modules/routes_products__id__common_components_ProductSkeleton_ProductSkeleton.html @@ -0,0 +1,2 @@ +routes/products/$id/-common/components/ProductSkeleton/ProductSkeleton | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes_products__id__common_components_Product_Product.html b/docs/modules/routes_products__id__common_components_Product_Product.html new file mode 100644 index 000000000..ee90b964d --- /dev/null +++ b/docs/modules/routes_products__id__common_components_Product_Product.html @@ -0,0 +1,2 @@ +routes/products/$id/-common/components/Product/Product | react-shopping-cart
\ No newline at end of file diff --git a/docs/modules/routes_products__id__product_item_api.html b/docs/modules/routes_products__id__product_item_api.html new file mode 100644 index 000000000..b60fb1229 --- /dev/null +++ b/docs/modules/routes_products__id__product_item_api.html @@ -0,0 +1,3 @@ +routes/products/$id/-product-item.api | react-shopping-cart

Module routes/products/$id/-product-item.api

Index

Interfaces

Functions

\ No newline at end of file diff --git a/docs/modules/routes_products__id_index_lazy.html b/docs/modules/routes_products__id_index_lazy.html new file mode 100644 index 000000000..304034c39 --- /dev/null +++ b/docs/modules/routes_products__id_index_lazy.html @@ -0,0 +1,2 @@ +routes/products/$id/index.lazy | react-shopping-cart

Module routes/products/$id/index.lazy

Index

Variables

\ No newline at end of file diff --git a/docs/types/routes__product_list_api.ProductList.html b/docs/types/routes__product_list_api.ProductList.html deleted file mode 100644 index d5d5bb9d5..000000000 --- a/docs/types/routes__product_list_api.ProductList.html +++ /dev/null @@ -1 +0,0 @@ -ProductList | react-shopping-cart
\ No newline at end of file diff --git a/docs/types/routes__product_list_api.ProductListResponse.html b/docs/types/routes__product_list_api.ProductListResponse.html new file mode 100644 index 000000000..ce0dab725 --- /dev/null +++ b/docs/types/routes__product_list_api.ProductListResponse.html @@ -0,0 +1 @@ +ProductListResponse | react-shopping-cart
ProductListResponse: {
    list: Product[];
    meta: Meta;
}

Type declaration

\ No newline at end of file diff --git a/docs/types/routes_cart__cart_list_api.CartListResponse.html b/docs/types/routes_cart__cart_list_api.CartListResponse.html new file mode 100644 index 000000000..38a9a09f0 --- /dev/null +++ b/docs/types/routes_cart__cart_list_api.CartListResponse.html @@ -0,0 +1 @@ +CartListResponse | react-shopping-cart
CartListResponse: {
    list: (Product & {
        count: number;
    })[];
}

Type declaration

  • list: (Product & {
        count: number;
    })[]
\ No newline at end of file diff --git a/docs/variables/mocks_browser.worker.html b/docs/variables/mocks_browser.worker.html index f2d67c4a5..561d5ec84 100644 --- a/docs/variables/mocks_browser.worker.html +++ b/docs/variables/mocks_browser.worker.html @@ -1 +1 @@ -worker | react-shopping-cart
worker: SetupWorker = ...
\ No newline at end of file +worker | react-shopping-cart
worker: SetupWorker = ...
\ No newline at end of file diff --git a/docs/variables/mocks_const.PAGE_META.html b/docs/variables/mocks_const.PAGE_META.html new file mode 100644 index 000000000..5b6250e9b --- /dev/null +++ b/docs/variables/mocks_const.PAGE_META.html @@ -0,0 +1 @@ +PAGE_META | react-shopping-cart
PAGE_META: {
    DEFAULT_PAGE: "0";
    DEFAULT_PER_COUNT: "15";
} = ...

Type declaration

  • Readonly DEFAULT_PAGE: "0"
  • Readonly DEFAULT_PER_COUNT: "15"
\ No newline at end of file diff --git a/docs/variables/mocks_handlers.handlers.html b/docs/variables/mocks_handlers.handlers.html index 6ef53211b..64a5b378c 100644 --- a/docs/variables/mocks_handlers.handlers.html +++ b/docs/variables/mocks_handlers.handlers.html @@ -1 +1 @@ -handlers | react-shopping-cart
handlers: HttpHandler[] = ...
\ No newline at end of file +handlers | react-shopping-cart
handlers: HttpHandler[] = ...
\ No newline at end of file diff --git a/docs/variables/mocks_products_cart_handlers.cartHandlers.html b/docs/variables/mocks_products_cart_handlers.cartHandlers.html new file mode 100644 index 000000000..5086219df --- /dev/null +++ b/docs/variables/mocks_products_cart_handlers.cartHandlers.html @@ -0,0 +1 @@ +cartHandlers | react-shopping-cart
cartHandlers: HttpHandler[] = ...
\ No newline at end of file diff --git a/docs/variables/mocks_products_index_handlers.productsHandlers.html b/docs/variables/mocks_products_index_handlers.productsHandlers.html new file mode 100644 index 000000000..abe302f4a --- /dev/null +++ b/docs/variables/mocks_products_index_handlers.productsHandlers.html @@ -0,0 +1 @@ +productsHandlers | react-shopping-cart
productsHandlers: HttpHandler[] = ...
\ No newline at end of file diff --git a/docs/variables/mocks_products_products_handlers.productsHandlers.html b/docs/variables/mocks_products_products_handlers.productsHandlers.html index f52989d8b..85f004b5e 100644 --- a/docs/variables/mocks_products_products_handlers.productsHandlers.html +++ b/docs/variables/mocks_products_products_handlers.productsHandlers.html @@ -1 +1 @@ -productsHandlers | react-shopping-cart
productsHandlers: HttpHandler[] = ...
\ No newline at end of file +productsHandlers | react-shopping-cart
productsHandlers: HttpHandler[] = ...
\ No newline at end of file diff --git a/docs/variables/mocks_products_products_repository.productsRepository.html b/docs/variables/mocks_products_products_repository.productsRepository.html new file mode 100644 index 000000000..42e047840 --- /dev/null +++ b/docs/variables/mocks_products_products_repository.productsRepository.html @@ -0,0 +1 @@ +productsRepository | react-shopping-cart
productsRepository: Map<number, Product> = ...
\ No newline at end of file diff --git a/docs/variables/routes___root.Route.html b/docs/variables/routes___root.Route.html index 507cf1fc6..3eb2e9b1e 100644 --- a/docs/variables/routes___root.Route.html +++ b/docs/variables/routes___root.Route.html @@ -1 +1 @@ -Route | react-shopping-cart
Route: RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
    queryClient: QueryClient;
}, {}, unknown, unknown> = ...

Type declaration

  • queryClient: QueryClient

Type declaration

    \ No newline at end of file +Route | react-shopping-cart
    Route: RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
        queryClient: QueryClient;
    }, {}, unknown, unknown> = ...

    Type declaration

    • queryClient: QueryClient

    Type declaration

      \ No newline at end of file diff --git a/docs/variables/routes__common_store_cartListStore_const.CART_COOKIE_KEY.html b/docs/variables/routes__common_store_cartListStore_const.CART_COOKIE_KEY.html new file mode 100644 index 000000000..4d2c08716 --- /dev/null +++ b/docs/variables/routes__common_store_cartListStore_const.CART_COOKIE_KEY.html @@ -0,0 +1 @@ +CART_COOKIE_KEY | react-shopping-cart
      \ No newline at end of file diff --git a/docs/variables/routes__common_store_cartListStore_const.CART_MAX_COUNT.html b/docs/variables/routes__common_store_cartListStore_const.CART_MAX_COUNT.html new file mode 100644 index 000000000..a4c121446 --- /dev/null +++ b/docs/variables/routes__common_store_cartListStore_const.CART_MAX_COUNT.html @@ -0,0 +1 @@ +CART_MAX_COUNT | react-shopping-cart
      \ No newline at end of file diff --git a/docs/variables/routes__common_store_cartListStore_const.CART_MIN_COUNT.html b/docs/variables/routes__common_store_cartListStore_const.CART_MIN_COUNT.html new file mode 100644 index 000000000..0b4e4e969 --- /dev/null +++ b/docs/variables/routes__common_store_cartListStore_const.CART_MIN_COUNT.html @@ -0,0 +1 @@ +CART_MIN_COUNT | react-shopping-cart
      \ No newline at end of file diff --git a/docs/variables/routes_cart_index_lazy.Route.html b/docs/variables/routes_cart_index_lazy.Route.html index 08b5fbad5..1575a036c 100644 --- a/docs/variables/routes_cart_index_lazy.Route.html +++ b/docs/variables/routes_cart_index_lazy.Route.html @@ -1 +1 @@ -Route | react-shopping-cart
      Route: LazyRoute<Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, {}, unknown, unknown>, "cart/", "/cart", "/cart/", "/cart/", {}, {}, {}, {}, {}, {}, {}, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, AnyContext, {}, unknown, unknown, unknown, AnyRoute>> = ...
      \ No newline at end of file +Route | react-shopping-cart
      Route: LazyRoute<Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, {}, unknown, unknown>, "cart/", "/cart", "/cart/", "/cart/", {}, {}, {}, {}, {}, Record<never, string>, Record<never, string>, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, AnyContext, {}, unknown, unknown, unknown>> = ...
      \ No newline at end of file diff --git a/docs/variables/routes_index_lazy.Route.html b/docs/variables/routes_index_lazy.Route.html index 7dfa0266d..75cec3a1e 100644 --- a/docs/variables/routes_index_lazy.Route.html +++ b/docs/variables/routes_index_lazy.Route.html @@ -1 +1 @@ -Route | react-shopping-cart
      Route: LazyRoute<Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, {}, unknown, unknown>, "", "/", "/", "/", {}, {}, {}, {}, {}, {}, {}, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, AnyContext, {}, unknown, unknown, unknown, AnyRoute>> = ...
      \ No newline at end of file +Route | react-shopping-cart
      Route: Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, {}, unknown, unknown>, "", "/", "/", "/", AnySearchSchema, {
          page: number;
      }, {
          page: number;
      }, {
          page: number;
      }, {
          page: number;
      }, Record<never, string>, Record<never, string>, RouteContext, RouteContext, {
          queryClient: QueryClient;
      }, AnyContext, {}, unknown, unknown, unknown> = ...

      Type declaration

      • page: number

      Type declaration

      • page: number

      Type declaration

      • page: number

      Type declaration

      • page: number

      Type declaration

      • queryClient: QueryClient

      Type declaration

        \ No newline at end of file diff --git a/docs/variables/routes_orders_index_lazy.Route.html b/docs/variables/routes_orders_index_lazy.Route.html index 947b56f9c..83fc8c4e9 100644 --- a/docs/variables/routes_orders_index_lazy.Route.html +++ b/docs/variables/routes_orders_index_lazy.Route.html @@ -1 +1 @@ -Route | react-shopping-cart
        Route: LazyRoute<Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
            queryClient: QueryClient;
        }, {}, unknown, unknown>, "orders/", "/orders", "/orders/", "/orders/", {}, {}, {}, {}, {}, {}, {}, RouteContext, RouteContext, {
            queryClient: QueryClient;
        }, AnyContext, {}, unknown, unknown, unknown, AnyRoute>> = ...
        \ No newline at end of file +Route | react-shopping-cart
        Route: LazyRoute<Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
            queryClient: QueryClient;
        }, {}, unknown, unknown>, "orders/", "/orders", "/orders/", "/orders/", {}, {}, {}, {}, {}, Record<never, string>, Record<never, string>, RouteContext, RouteContext, {
            queryClient: QueryClient;
        }, AnyContext, {}, unknown, unknown, unknown>> = ...
        \ No newline at end of file diff --git a/docs/variables/routes_products__id_index_lazy.Route.html b/docs/variables/routes_products__id_index_lazy.Route.html new file mode 100644 index 000000000..4f8e8178a --- /dev/null +++ b/docs/variables/routes_products__id_index_lazy.Route.html @@ -0,0 +1 @@ +Route | react-shopping-cart
        Route: Route<RootRoute<RootSearchSchema, RootSearchSchema, RootSearchSchema, RouteContext, RouteContext, {
            queryClient: QueryClient;
        }, {}, unknown, unknown>, "products/$id/", "/products/$id", "/products/$id/", "/products/$id/", {}, {}, {}, {}, {}, {
            id: number;
        }, {
            id: number;
        }, RouteContext, RouteContext, {
            queryClient: QueryClient;
        }, AnyContext, {}, unknown, unknown, unknown> = ...

        Type declaration

          Type declaration

            Type declaration

              Type declaration

                Type declaration

                  Type declaration

                  • id: number

                  Type declaration

                  • id: number

                  Type declaration

                  • queryClient: QueryClient

                  Type declaration

                    \ No newline at end of file diff --git a/package.json b/package.json index d0be7fa67..3208780c4 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,14 @@ "dependencies": { "@tanstack/react-query": "^5.29.0", "@tanstack/react-query-devtools": "^5.29.0", - "@tanstack/react-router": "^1.26.18", + "@tanstack/react-router": "^1.29.2", "@tanstack/router-devtools": "^1.26.18", "@tanstack/router-vite-plugin": "^1.26.16", "react": "^18.2.0", "react-dom": "^18.2.0", - "typescript-eslint": "^7.0.2" + "react-intersection-observer": "^9.8.2", + "typescript-eslint": "^7.0.2", + "zod": "^3.22.5" }, "devDependencies": { "@types/node": "^20.11.20", diff --git a/src/common/hooks/useCookieRepository/useCookieRepository.ts b/src/common/hooks/useCookieRepository/useCookieRepository.ts new file mode 100644 index 000000000..b744bcebf --- /dev/null +++ b/src/common/hooks/useCookieRepository/useCookieRepository.ts @@ -0,0 +1,65 @@ +import { useEffect, useState } from 'react' + +import { getCookie, setCookie } from '../../utils/cookie' +import { CookieOptions } from '../../utils/cookie/type' + +interface CookieRepository { + get(): Value | undefined + set(value: Value): void + remove(key: Key): void + update(key: Key, value: Value): void + clear(): void +} + +/** + * @summary 쿠키 레파지토리 + */ +export const useCookie = ( + key: Key, + option?: CookieOptions +): CookieRepository => { + const [cookie, setStateCookie] = useState() + + useEffect(() => { + const initializeCookie = () => { + // eslint-disable-next-line no-shadow + const cookie = getCookie(key) + + if (cookie) { + setStateCookie(JSON.parse(cookie) as Value) + } + } + + initializeCookie() + }, [key]) + + const get = () => { + return cookie + } + + const set = (value: Value) => { + setStateCookie(value) + + setCookie(key, JSON.stringify(value), option ?? {}) + } + + const remove = () => { + throw new Error('Not Implemented') + } + + const update = () => { + throw new Error('Not Implemented') + } + + const clear = () => { + throw new Error('Not Implemented') + } + + return { + get, + set, + remove, + update, + clear, + } +} diff --git a/src/common/module/store/store.ts b/src/common/module/store/store.ts new file mode 100644 index 000000000..f3b412884 --- /dev/null +++ b/src/common/module/store/store.ts @@ -0,0 +1,35 @@ +export interface Store { + getState: () => T + setState: (next: T | ((prev: T) => T)) => void + subscribe: (callback: () => void) => () => void +} + +/** + * @summary 스토어를 생성한다. + */ +export const createStore = (initialValue: T): Store => { + let state = initialValue + const callbacks = new Set<() => void>() + + const getState = () => { + return state + } + + const setState = (next: T | ((prev: T) => T)) => { + state = typeof next === 'function' ? (next as (prev: T) => T)(state) : next + + callbacks.forEach((callback) => callback()) + } + + const subscribe = (callback: () => void) => { + callbacks.add(callback) + + return () => callbacks.delete(callback) + } + + return { + getState, + setState, + subscribe, + } +} diff --git a/src/common/module/store/useStore.ts b/src/common/module/store/useStore.ts new file mode 100644 index 000000000..c6a0a8021 --- /dev/null +++ b/src/common/module/store/useStore.ts @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react' + +import { Store } from './store' + +/** + * @summary 스토어를 리액트에서 상태로 사용할 수 있도록 도와주는 hook + */ +export const useStore = (store: Store) => { + const [state, setState] = useState(store.getState()) + + useEffect(() => { + const unsubscribe = store.subscribe(() => { + setState(store.getState()) + }) + + return unsubscribe + }, [store]) + + return [state, store.setState] as const +} diff --git a/src/common/utils/cookie/index.ts b/src/common/utils/cookie/index.ts new file mode 100644 index 000000000..08d1e7ff3 --- /dev/null +++ b/src/common/utils/cookie/index.ts @@ -0,0 +1,38 @@ +import { CookieOptions } from './type' + +/** + * @summary name에 해당하는 쿠키 값을 가져온다. + * @reference https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#example_2_get_a_sample_cookie_named_test2 + */ +export function getCookie(name: T) { + const cookie = document.cookie + .split('; ') + .find((row) => row.startsWith(`${name}=`)) + ?.split('=')[1] + + return decodeURIComponent(cookie || '') +} + +/** + * @summary 쿠키를 저장한다. + * @reference https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie + */ +export function setCookie( + name: Key, + value: Value, + options: CookieOptions +) { + const cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(JSON.stringify(value))}` + + // eslint-disable-next-line no-shadow + const cookieOptions = Object.entries(options).reduce((prev, [key, value]) => { + switch (key) { + case 'expires': + return (prev += `; expires=${(value as Date).toUTCString()}`) + default: + return (prev += `; ${key}=${value}`) + } + }, '') + + document.cookie = cookieString + cookieOptions +} diff --git a/src/common/utils/cookie/type.ts b/src/common/utils/cookie/type.ts new file mode 100644 index 000000000..07b51bbda --- /dev/null +++ b/src/common/utils/cookie/type.ts @@ -0,0 +1,21 @@ +export interface CookieOptions { + /** + * @summary 쿠키의 + * @default 세션 쿠기(브라우저 종료시 자동 삭제) + * @description 지정시 영구 쿠기(지정 날짜까지 유지) + */ + expires?: Date + /** + * @default "/" + */ + path?: string + /** + * @default 현재 도메인 + * @description 미지정시 하위 도메인 접근 불가 + */ + domain?: string + /** + * 기타 키 정의 + */ + [key: string]: unknown +} diff --git a/src/css/index.css b/src/css/index.css index 5f55fca84..0b42bb8c1 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -2,7 +2,7 @@ @import "./page/index.css"; body { - width: 1920px; + max-width: 1920px; margin: 0 auto 0; } diff --git a/src/mocks/browser.ts b/src/mocks/browser.ts index d3824e657..93f9e2693 100644 --- a/src/mocks/browser.ts +++ b/src/mocks/browser.ts @@ -1,5 +1,13 @@ +import { http } from 'msw' import { setupWorker } from 'msw/browser' import { handlers } from './handlers' -export const worker = setupWorker(...handlers) +const imageExtensionRegex = /\.(png|jpe?g|gif|svg)$/i +const sourceCodeExtensionRegex = /\.(ts|tsx|js|jsx)$/i + +export const worker = setupWorker( + ...handlers, + http.get(imageExtensionRegex, () => {}), + http.get(sourceCodeExtensionRegex, () => {}) +) diff --git a/src/mocks/const.ts b/src/mocks/const.ts new file mode 100644 index 000000000..bd29c9035 --- /dev/null +++ b/src/mocks/const.ts @@ -0,0 +1,4 @@ +export const PAGE_META = { + DEFAULT_PAGE: '0', + DEFAULT_PER_COUNT: '15', +} as const diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index ebaa4de12..dcb0d20d7 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -1,3 +1,3 @@ -import { productsHandlers } from './products/products.handlers' +import { productsHandlers } from './products/index.handlers' export const handlers = [...productsHandlers] diff --git a/src/mocks/products/cart.handlers.ts b/src/mocks/products/cart.handlers.ts new file mode 100644 index 000000000..cc0e902e6 --- /dev/null +++ b/src/mocks/products/cart.handlers.ts @@ -0,0 +1,31 @@ +import { delay, http, HttpResponse } from 'msw' + +import { Product } from '@/routes/-product-list.api' + +import { productsRepository } from './products.repository' + +export const cartHandlers = [ + http.get('/carts', async ({ cookies }) => { + const cartList = JSON.parse(decodeURIComponent(cookies.CARTS)) as Array<{ + id: number + count: number + }> // TODO: zod로 검증할 것 + + // id에 해당하는 상품 데이터 내려주기 + const res: Array = [] + + cartList.forEach((product) => { + const foundProduct = productsRepository.get(product.id) + + if (foundProduct) { + res.push({ ...foundProduct, count: product.count }) + } + }) + + await delay(300) + + return HttpResponse.json({ + list: res, + }) + }), +] diff --git a/src/mocks/products/index.handlers.ts b/src/mocks/products/index.handlers.ts new file mode 100644 index 000000000..3f6c48b0b --- /dev/null +++ b/src/mocks/products/index.handlers.ts @@ -0,0 +1,4 @@ +import { cartHandlers } from './cart.handlers' +import { productsHandlers as productsListHandlers } from './products.handlers' + +export const productsHandlers = [...cartHandlers, ...productsListHandlers] diff --git a/src/mocks/products/products.json b/src/mocks/products/products.db.json similarity index 100% rename from src/mocks/products/products.json rename to src/mocks/products/products.db.json diff --git a/src/mocks/products/products.handlers.ts b/src/mocks/products/products.handlers.ts index 527e217c0..a63427521 100644 --- a/src/mocks/products/products.handlers.ts +++ b/src/mocks/products/products.handlers.ts @@ -1,17 +1,33 @@ import { delay, http, HttpResponse } from 'msw' -import type { ProductList } from '@/routes/-product-list.api' +import { PAGE_META } from '../const' +import { productsRepository } from './products.repository' -import products from './products.json' +export const productsHandlers = [ + http.get('/products', async ({ request }) => { + await delay(500) -const allProducts = new Map( - products.map((product) => [product.id, product]) -) + const url = new URL(request.url) -export const productsHandlers = [ - http.get('/products', async () => { + const page = parseInt(url.searchParams.get('page') ?? PAGE_META.DEFAULT_PAGE) + const perCount = parseInt(url.searchParams.get('perCount') ?? PAGE_META.DEFAULT_PER_COUNT) + + const start = page * perCount + const end = start + perCount + + const maxPage = Math.ceil(productsRepository.size / perCount) + const nextPage = page < maxPage ? page + 1 : undefined + + return HttpResponse.json({ + list: Array.from(productsRepository.values()).slice(start, end), + meta: { next_page: nextPage }, + }) + }), + http.get('/products/:id', async ({ params }) => { await delay(1000) - return HttpResponse.json(Array.from(allProducts.values())) + const { id } = params + + return HttpResponse.json(productsRepository.get(Number(id))) }), ] diff --git a/src/mocks/products/products.repository.ts b/src/mocks/products/products.repository.ts new file mode 100644 index 000000000..3575e9f80 --- /dev/null +++ b/src/mocks/products/products.repository.ts @@ -0,0 +1,6 @@ +import { ProductListResponse } from '@/routes/-product-list.api' + +import products from './products.db.json' +export const productsRepository = new Map( + products.map((product) => [product.id, product]) +) diff --git a/src/mocks/readme.md b/src/mocks/readme.md index d1481a15c..352e31879 100644 --- a/src/mocks/readme.md +++ b/src/mocks/readme.md @@ -3,15 +3,20 @@ - mocking 관련 폴더 - 핸들러는 도메인 단위로 폴더를 만든다. - 핸들러의 파일명 규칙은 `[domain name].handlers.ts`로 작성한다. -- 작성한 핸들러는 `handlers.ts`에 추가한다. +- 하나의 도메인에 여러개의 핸들러를 가질 수 있다. (1:N 관계이다.) +- index.handlers에 핸들러를 등록하고 해당 핸들러를 `mocks/handlers.ts`에 추가한다. ## 폴더 구조 ``` 📦mocks - ┣ 📂products # 도메인 단위 - ┃ ┗ 📜products.handlers.ts # 핸들러 - ┣ 📜browser.ts # 진입점 - ┣ 📜handlers.ts # 핸들러 등록 + ┣ 📂products # 도메인 + ┣ ┣ 📜products.db.json # DB + ┣ ┣ 📜products.repository.ts # DB의 CRUD를 담당한다. + ┣ ┣ 📜carts.handlers.ts # 도메인과 핸들러는 1:N 관계이다. + ┣ ┣ 📜products.handlers.ts # 핸들러 + ┃ ┗ 📜index.handlers.ts # 도메인에 작성한 모든 핸들러들을 등록한다. + ┣ 📜browser.ts # 진입점 + ┣ 📜handlers.ts # 핸들러 등록 ┗ 📜readme.md ``` diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 62b2616a6..2105c1361 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -19,6 +19,7 @@ import { Route as rootRoute } from './routes/__root' const IndexLazyImport = createFileRoute('/')() const OrdersIndexLazyImport = createFileRoute('/orders/')() const CartIndexLazyImport = createFileRoute('/cart/')() +const ProductsIdIndexLazyImport = createFileRoute('/products/$id/')() // Create/Update Routes @@ -37,6 +38,13 @@ const CartIndexLazyRoute = CartIndexLazyImport.update({ getParentRoute: () => rootRoute, } as any).lazy(() => import('./routes/cart/index.lazy').then((d) => d.Route)) +const ProductsIdIndexLazyRoute = ProductsIdIndexLazyImport.update({ + path: '/products/$id/', + getParentRoute: () => rootRoute, +} as any).lazy(() => + import('./routes/products/$id/index.lazy').then((d) => d.Route), +) + // Populate the FileRoutesByPath interface declare module '@tanstack/react-router' { @@ -53,6 +61,10 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof OrdersIndexLazyImport parentRoute: typeof rootRoute } + '/products/$id/': { + preLoaderRoute: typeof ProductsIdIndexLazyImport + parentRoute: typeof rootRoute + } } } @@ -62,6 +74,7 @@ export const routeTree = rootRoute.addChildren([ IndexLazyRoute, CartIndexLazyRoute, OrdersIndexLazyRoute, + ProductsIdIndexLazyRoute, ]) /* prettier-ignore-end */ diff --git a/src/routes/-common/components/MoreButton/MoreButton.tsx b/src/routes/-common/components/MoreButton/MoreButton.tsx new file mode 100644 index 000000000..f02c0e653 --- /dev/null +++ b/src/routes/-common/components/MoreButton/MoreButton.tsx @@ -0,0 +1,20 @@ +import { ComponentPropsWithoutRef, forwardRef } from 'react' + +export const MoreButton = forwardRef>( + ({ children, ...props }, ref) => { + return ( + + ) + } +) diff --git a/src/routes/-common/components/ProductCard/ProductCard.tsx b/src/routes/-common/components/ProductCard/ProductCard.tsx index 2c9449699..8ded9988d 100644 --- a/src/routes/-common/components/ProductCard/ProductCard.tsx +++ b/src/routes/-common/components/ProductCard/ProductCard.tsx @@ -1,18 +1,36 @@ -import type { ProductList } from '@/routes/-product-list.api' +import { Link } from '@tanstack/react-router' -type ProductCardProps = ProductList[number] +import type { ProductListResponse } from '@/routes/-product-list.api' + +import { useCartListStore } from '../../store/cartListStore/cartListStore' + +type ProductCardProps = ProductListResponse['list'][number] export const ProductCard = (props: ProductCardProps) => { + const cartListStore = useCartListStore() + return ( - <> - {props.name} + + {props.name} +
                    {props.name} {props.price.toLocaleString()}
                    - 장바구니 + +
                    - + ) } diff --git a/src/routes/-common/components/ProductList/ProductList.tsx b/src/routes/-common/components/ProductList/ProductList.tsx index aacca4040..8e4a5186e 100644 --- a/src/routes/-common/components/ProductList/ProductList.tsx +++ b/src/routes/-common/components/ProductList/ProductList.tsx @@ -1,47 +1,81 @@ -import { useQuery } from '@tanstack/react-query' +import './index.css' + +import { useInfiniteQuery } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useInView } from 'react-intersection-observer' import { RenderPropsList } from '@/common/components/RenderPropsList/RenderPropsList' import { Skeleton } from '@/common/components/Skeleton/Skeleton' import { SwitchCase } from '@/common/components/SwitchCase/SwitchCase' -import { parseApiStatus } from '@/common/utils/parseApiStatus' -import type { ProductList as ProductsListType } from '@/routes/-product-list.api' +import type { ProductListResponse } from '@/routes/-product-list.api' import { getProductList } from '@/routes/-product-list.api' +import { MoreButton } from '../MoreButton/MoreButton' import { ProductCard } from '../ProductCard/ProductCard' /** * @summary 상품목록 컴포넌트 */ export const ProductList = () => { - const { data, isLoading, isError } = useQuery({ - queryKey: ['/posts'], - queryFn: getProductList, + const { ref, inView } = useInView() + const { data, status, isFetchingNextPage, hasNextPage, fetchNextPage } = useInfiniteQuery({ + queryKey: ['/products'], + queryFn: ({ pageParam }) => { + return getProductList({ + page: pageParam, + }) + }, + initialPageParam: 0, + getNextPageParam: (res: ProductListResponse) => res.meta.next_page, + staleTime: 1000 * 60 * 3, }) + useEffect(() => { + if (inView) { + fetchNextPage() + } + }, [fetchNextPage, inView]) + + const flattedProductList = data?.pages.flatMap((group) => group.list) + return ( - } - className="product-container" - style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)' }} - /> - ), - loading: ( - ({ - id: i, - }))} - renderItem={() => } - className="product-container" - style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)' }} - /> - ), - error: <>error, - }} - /> + <> + + } + className="product-container2" + /> + + fetchNextPage()} + disabled={!hasNextPage || isFetchingNextPage} + > + {isFetchingNextPage + ? '더보기' + : hasNextPage + ? 'loading..' + : '더이상 상품이 존재하지 않습니다.'} + + + ), + pending: ( + ({ + id: i, + }))} + renderItem={() => } + className=" product-container2" + /> + ), + error: <>error, + }} + /> + ) } diff --git a/src/routes/-common/components/ProductList/index.css b/src/routes/-common/components/ProductList/index.css new file mode 100644 index 000000000..508c863eb --- /dev/null +++ b/src/routes/-common/components/ProductList/index.css @@ -0,0 +1,23 @@ +.product-container2 { + padding: 20px; + + display: grid; + grid-template-columns: 1fr; + gap: 20px; +} + +@media (min-width: 950px) { + .product-container2 { + padding: 50px 200px; + + grid-template-columns: repeat(3, 1fr); + } +} + +@media (min-width: 1200px) { + .product-container2 { + padding: 50px 200px; + + grid-template-columns: repeat(4, 1fr); + } +} diff --git a/src/routes/-common/components/gnb/Gnb.tsx b/src/routes/-common/components/gnb/Gnb.tsx index 393b6c143..cb4bb6fa7 100644 --- a/src/routes/-common/components/gnb/Gnb.tsx +++ b/src/routes/-common/components/gnb/Gnb.tsx @@ -1,26 +1,55 @@ import { Link } from '@tanstack/react-router' +import { useCartListStore } from '../../store/cartListStore/cartListStore' + /** * @summary 공통으로 사용하는 네비게이션 바 * @detail 메인페이지, 장바구니, 주문목록 페이지 라우팅 */ -export const Gnb = () => ( -
                    -
                    + +
                    + ) +} diff --git a/src/routes/-common/store/cartListStore/cartListStore.ts b/src/routes/-common/store/cartListStore/cartListStore.ts new file mode 100644 index 000000000..3fc110ede --- /dev/null +++ b/src/routes/-common/store/cartListStore/cartListStore.ts @@ -0,0 +1,155 @@ +import { ChangeEvent, useEffect } from 'react' + +import { createStore } from '@/common/module/store/store' +import { useStore } from '@/common/module/store/useStore' +import { getCookie, setCookie } from '@/common/utils/cookie' +import type { Product } from '@/routes/-product-list.api' + +import { CART_COOKIE_KEY, CART_MAX_COUNT, CART_MIN_COUNT } from './const' + +const initializeCookie = getCookie(CART_COOKIE_KEY) + +interface CartItem extends Pick { + count: number +} + +const cartListStore = createStore<{ + cartList: Array +}>({ + cartList: initializeCookie ? JSON.parse(initializeCookie) : [], +}) + +/** + * @summary 브라우저의 쿠키 데이터와 장바구니 데이터를 상태로 동기화하는 레파지토리이다. + * @detail 상태 변경시 브라우저의 쿠키 데이터를 업데이트 한다. + */ +export const useCartListStore = () => { + const [value, setValue] = useStore(cartListStore) + + useEffect(() => { + setCookie(CART_COOKIE_KEY, value.cartList, {}) + }, [value]) + + const saveProduct = (id: CartItem['id']) => { + const foundProduct = value.cartList.find((product) => product.id === id) + + if (foundProduct) { + setValue((prev) => ({ + ...prev, + cartList: [ + ...prev.cartList.filter((product) => product.id !== id), + { id, count: foundProduct.count + 1 }, + ], + })) + + return + } + + setValue((prev) => ({ ...prev, cartList: [...prev.cartList, { id, count: 1 }] })) + } + + const increaseCount = (id: CartItem['id']) => { + setValue((prev) => ({ + ...prev, + cartList: prev.cartList.map((product) => { + return product.id === id + ? { + ...product, + // count: product.count < CART_MAX_COUNT ? product.count + 1 : CART_MAX_COUNT, + count: Math.min(product.count + 1, CART_MAX_COUNT), + } + : product + }), + })) + } + + const decreaseCount = (id: CartItem['id']) => { + setValue((prev) => ({ + ...prev, + cartList: prev.cartList + .map((product) => { + return product.id === id + ? { + ...product, + // count: product.count > CART_MIN_COUNT ? product.count - 1 : CART_MIN_COUNT, + count: Math.max(product.count - 1, CART_MIN_COUNT), + } + : product + }) + .filter((product) => product.count > 0), + })) + } + + const deleteProduct = (id: CartItem['id']) => { + setValue((prev) => ({ + ...prev, + cartList: prev.cartList.filter((product) => product.id !== id), + })) + } + + const changeProductCount = (e: ChangeEvent, product: CartItem) => { + if (e.target.valueAsNumber > CART_MAX_COUNT) { + e.target.value = String(CART_MAX_COUNT) + + setValue((prev) => ({ + ...prev, + cartList: prev.cartList.map((item) => { + return item.id === product.id + ? { + ...product, + count: CART_MAX_COUNT, + } + : product + }), + })) + + return + } + + if (e.target.valueAsNumber < CART_MIN_COUNT) { + e.target.value = String(CART_MIN_COUNT) + + setValue((prev) => ({ + ...prev, + cartList: prev.cartList.map((item) => { + return item.id === product.id + ? { + ...product, + count: CART_MIN_COUNT, + } + : product + }), + })) + + return + } + + setValue((prev) => ({ + ...prev, + cartList: prev.cartList.map((item) => { + return item.id === product.id + ? { + ...product, + count: e.target.valueAsNumber, + } + : product + }), + })) + } + + const deleteAllProducts = () => { + setValue((prev) => ({ ...prev, cartList: [] })) + } + + return { + cartList: value.cartList, + actions: { + saveProduct, + increaseCount, + decreaseCount, + deleteProduct, + changeProductCount, + deleteAllProducts, + }, + } +} diff --git a/src/routes/-common/store/cartListStore/const.ts b/src/routes/-common/store/cartListStore/const.ts new file mode 100644 index 000000000..87b7b0c4b --- /dev/null +++ b/src/routes/-common/store/cartListStore/const.ts @@ -0,0 +1,4 @@ +export const CART_MIN_COUNT = 1 +export const CART_MAX_COUNT = 20 + +export const CART_COOKIE_KEY = 'CARTS' diff --git a/src/routes/-product-list.api.ts b/src/routes/-product-list.api.ts index 2d81acfe7..e43f44bb4 100644 --- a/src/routes/-product-list.api.ts +++ b/src/routes/-product-list.api.ts @@ -1,17 +1,39 @@ -interface Product { +export interface Product { id: number name: string price: number imageUrl: string } -export type ProductList = Array +type Meta = { + next_page?: number +} + +type PageQuery = { + page?: number + perCount?: number +} + +export type ProductListResponse = { + list: Array + meta: Meta +} + +type ProductListParams = PageQuery /** * @summary 상목목록 API */ -export const getProductList = async () => { - const response = await fetch('/products') +export const getProductList = async ({ + page = 0, + perCount = 15, +}: ProductListParams): Promise => { + const urlQueryParams = new URLSearchParams({ + page: page.toString(), + perCount: perCount.toString(), + }) + + const response = await fetch(`/products` + `?${urlQueryParams.toString()}`) if (!response.ok) { throw new Error('failed to getProductList') diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index d2e4d9825..bf1e80e06 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,5 +1,5 @@ import { QueryClient } from '@tanstack/react-query' -import { createRootRouteWithContext, Outlet } from '@tanstack/react-router' +import { createRootRouteWithContext, Outlet, ScrollRestoration } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { Gnb } from './-common/components/Gnb/Gnb' @@ -11,6 +11,7 @@ export const Route = createRootRouteWithContext<{ <> + ), diff --git a/src/routes/cart/-cart-list.api.ts b/src/routes/cart/-cart-list.api.ts new file mode 100644 index 000000000..bab91d118 --- /dev/null +++ b/src/routes/cart/-cart-list.api.ts @@ -0,0 +1,23 @@ +export interface Product { + id: number + name: string + price: number + imageUrl: string +} + +export type CartListResponse = { + list: Array +} + +/** + * @summary 카트목록 API + */ +export const getCartList = async (): Promise => { + const response = await fetch('/carts') + + if (!response.ok) { + throw new Error('failed to getProductList') + } + + return response.json() +} diff --git a/src/routes/cart/-useCartVM.ts b/src/routes/cart/-useCartVM.ts new file mode 100644 index 000000000..ba1369b77 --- /dev/null +++ b/src/routes/cart/-useCartVM.ts @@ -0,0 +1,117 @@ +import { useQuery, useQueryClient } from '@tanstack/react-query' +import { useEffect, useState } from 'react' + +import { useCartListStore } from '../-common/store/cartListStore/cartListStore' +import { CartListResponse, getCartList } from './-cart-list.api' + +/** + * @summary 카트 페이지의 view model + */ +export const useCartVM = () => { + const { actions } = useCartListStore() + const queryClient = useQueryClient() + + /** + * @summary cartsQuery를 트리거한다. + */ + const cartQueryTriggerDecorator = (fn: T) => { + queryClient.invalidateQueries({ + queryKey: ['carts'], + }) + + return fn + } + + const cartsQuery = useQuery({ + queryKey: ['carts'], + queryFn: getCartList, + select: (response) => { + const parsed = response.list.map((product) => { + return { + ...product, + totalPrice: product.price * product.count, + } + }) + + return { + list: parsed, + hasProduct: parsed.length > 0, + } + }, + }) + + const [selectedProductList, setSelectedProductList] = useState( + () => new Map(cartsQuery.data?.list.map((product) => [product.id, true])) + ) + + useEffect(() => { + setSelectedProductList(() => { + return new Map(cartsQuery.data?.list.map((product) => [product.id, true])) + }) + }, [cartsQuery.data]) + + const toggleProduct = (id: CartListResponse['list'][number]['id']) => { + setSelectedProductList((prev) => { + const newMap = new Map(prev) + + if (newMap.has(id)) { + newMap.delete(id) + + return newMap + } + + newMap.set(id, true) + + return newMap + }) + } + + const isCheckedProduct = (id: CartListResponse['list'][number]['id']) => { + return selectedProductList.get(id) + } + + const totalSelectedCount = selectedProductList.size + const isAllProductChecked = selectedProductList.size === cartsQuery.data?.list.length + + const toggleAll = () => { + if (isAllProductChecked) { + setSelectedProductList(() => new Map()) + + return + } + + setSelectedProductList(() => { + return new Map(cartsQuery.data?.list.map((product) => [product.id, true])) + }) + } + + const paymentTotal = cartsQuery.data?.list + .filter((product) => selectedProductList.get(product.id)) + .reduce((acc, product) => acc + product.totalPrice, 0) + .toLocaleString() + + const decoratedCartListActions = Object.entries(actions).reduce( + (prev, [key, fn]) => { + return { + ...prev, + [key]: cartQueryTriggerDecorator(fn), + } + }, + {} as typeof actions + ) + + return { + cartsQuery, + computed: { + isAllProductChecked, + totalSelectedCount, + paymentTotal, + }, + actions: { + toggleProduct, + toggleAll, + isCheckedProduct, + ...decoratedCartListActions, + }, + } +} diff --git a/src/routes/cart/index.lazy.tsx b/src/routes/cart/index.lazy.tsx index 41a597e5a..6fee09372 100644 --- a/src/routes/cart/index.lazy.tsx +++ b/src/routes/cart/index.lazy.tsx @@ -1,4 +1,7 @@ import { createLazyFileRoute } from '@tanstack/react-router' +import { Fragment } from 'react' + +import { useCartVM } from './-useCartVM' export const Route = createLazyFileRoute('/cart/')({ component: Cart, @@ -8,5 +11,130 @@ export const Route = createLazyFileRoute('/cart/')({ * @summary 장바구니 페이지 */ function Cart() { - return
                    Hello /cart/!
                    + const { actions, cartsQuery, computed } = useCartVM() + + return ( +
                    +
                    +

                    장바구니

                    +
                    +
                    + +
                    +
                    +
                    +
                    + + +
                    + +
                    + +
                    + {cartsQuery.data?.list.map((product) => ( + +
                    +
                    + { + actions.toggleProduct(product.id) + }} + /> + {product.name} + {product.name} +
                    + +
                    + + +
                    + actions.changeProductCount(e, product)} + /> +
                    + + +
                    +
                    + {product.totalPrice.toLocaleString()}원 +
                    +
                    +
                    +
                    + ))} +
                    + +
                    +
                    +

                    결제예상금액

                    +
                    +
                    +
                    +
                    + 결제예상금액 + {computed.paymentTotal}원 +
                    +
                    + +
                    +
                    +
                    +
                    +
                    + ) } diff --git a/src/routes/index.lazy.tsx b/src/routes/index.lazy.tsx index e74ab26c8..ab2b7e68e 100644 --- a/src/routes/index.lazy.tsx +++ b/src/routes/index.lazy.tsx @@ -1,9 +1,15 @@ -import { createLazyFileRoute } from '@tanstack/react-router' +import { createFileRoute } from '@tanstack/react-router' +import { z } from 'zod' import { ProductList } from './-common/components/ProductList/ProductList' -export const Route = createLazyFileRoute('/')({ +const homeSearchSchema = z.object({ + page: z.number().catch(1), +}) + +export const Route = createFileRoute('/')({ component: Home, + validateSearch: homeSearchSchema.parse, }) function Home() { diff --git a/src/routes/products/$id/-common/components/Product/Product.tsx b/src/routes/products/$id/-common/components/Product/Product.tsx new file mode 100644 index 000000000..5dc8d50a0 --- /dev/null +++ b/src/routes/products/$id/-common/components/Product/Product.tsx @@ -0,0 +1,30 @@ +import type { Product as ProductResponse } from '../../../-product-item.api' + +interface ProductProps extends ProductResponse { + saveProduct: (id: number) => void +} +export const Product = (props: ProductProps) => { + return ( +
                    +
                    + {props.name} + +
                    + {props.name} +
                    +
                    + 금액 + {props.price?.toLocaleString()}원 +
                    +
                    + + +
                    +
                    + ) +} diff --git a/src/routes/products/$id/-common/components/ProductSkeleton/ProductSkeleton.tsx b/src/routes/products/$id/-common/components/ProductSkeleton/ProductSkeleton.tsx new file mode 100644 index 000000000..329dac997 --- /dev/null +++ b/src/routes/products/$id/-common/components/ProductSkeleton/ProductSkeleton.tsx @@ -0,0 +1,15 @@ +import { Skeleton } from '@/common/components/Skeleton/Skeleton' + +export const ProductSkeleton = () => { + return ( +
                    +
                    + +
                    +
                    + ) +} diff --git a/src/routes/products/$id/-product-item.api.ts b/src/routes/products/$id/-product-item.api.ts new file mode 100644 index 000000000..4d9f0364e --- /dev/null +++ b/src/routes/products/$id/-product-item.api.ts @@ -0,0 +1,19 @@ +export interface Product { + id: number + name: string + price: number + imageUrl: string +} + +/** + * @summary 상목목록 API + */ +export const getProduct = async (id: number) => { + const response = await fetch(`/products/${id}`) + + if (!response.ok) { + throw new Error('failed to getProduct') + } + + return response.json() +} diff --git a/src/routes/products/$id/index.lazy.tsx b/src/routes/products/$id/index.lazy.tsx new file mode 100644 index 000000000..39bab7191 --- /dev/null +++ b/src/routes/products/$id/index.lazy.tsx @@ -0,0 +1,37 @@ +import { useQuery } from '@tanstack/react-query' +import { createFileRoute } from '@tanstack/react-router' + +import { SwitchCase } from '@/common/components/SwitchCase/SwitchCase' +import { useCartListStore } from '@/routes/-common/store/cartListStore/cartListStore' + +import { Product } from './-common/components/Product/Product' +import { ProductSkeleton } from './-common/components/ProductSkeleton/ProductSkeleton' +import type { Product as ProductResponse } from './-product-item.api' +import { getProduct } from './-product-item.api' + +export const Route = createFileRoute('/products/$id/')({ + parseParams: (params) => ({ id: Number(params.id) }), + component: ProductDetail, +}) + +function ProductDetail() { + const { id } = Route.useParams() + + const { data, status } = useQuery({ + queryKey: ['product', id], + queryFn: () => getProduct(id), + }) + + const { actions } = useCartListStore() + + return ( + : null, + pending: , + error:
                    error
                    , + }} + /> + ) +} diff --git a/yarn.lock b/yarn.lock index 901d7e0b2..aba36b83c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -818,6 +818,11 @@ resolved "https://registry.yarnpkg.com/@tanstack/history/-/history-1.26.10.tgz#fa67fd8a3e1a93ad626860afc3d6b5073b8be480" integrity sha512-fHx8RQ3liEDhueIemUggBGmqYnK6vOxtxCduolW7r6ExBEQVwKdLEcaUobxp6BxcXLQ7z/qhXAptlOlYi4FFXg== +"@tanstack/history@1.28.9": + version "1.28.9" + resolved "https://registry.yarnpkg.com/@tanstack/history/-/history-1.28.9.tgz#487d4414c242d1fe5eacdff109fa25f08da81e11" + integrity sha512-WgTFJhHaZnGZPyt0H11xFhGGDj1MtA1mrUmdAjB/nhVpmsAYXsSB5O+hkF9N66u7MjbNb405wTb9diBsztvI5w== + "@tanstack/query-core@5.29.0": version "5.29.0" resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.29.0.tgz#d0b3d12c07d5a47f42ab0c1ed4f317106f3d4b20" @@ -842,7 +847,7 @@ dependencies: "@tanstack/query-core" "5.29.0" -"@tanstack/react-router@1.27.0", "@tanstack/react-router@^1.26.18": +"@tanstack/react-router@1.27.0": version "1.27.0" resolved "https://registry.yarnpkg.com/@tanstack/react-router/-/react-router-1.27.0.tgz#8fbfd9ad6d901623f4ed37edd57b930f8a7be64e" integrity sha512-tBFGdB7o2z0BIT9fsmsF0I9SrLya86HV0xVdPSUWcwFOVUYy8UtDmVw9rBb0Rze0oW5keNgvECT+kYhD6e1vCg== @@ -852,6 +857,16 @@ tiny-invariant "^1.3.1" tiny-warning "^1.0.3" +"@tanstack/react-router@^1.29.2": + version "1.29.2" + resolved "https://registry.yarnpkg.com/@tanstack/react-router/-/react-router-1.29.2.tgz#49a3a5cfad3bd43fc62631f89016b931abdcab35" + integrity sha512-rSSLyI+AaVg79qeeH5fH6KA8ZQkckinH9mFdLrGUhA4wX2B7Az7eloepha2TqvsFJon0HgeV7heMqPkq9nyAeg== + dependencies: + "@tanstack/history" "1.28.9" + "@tanstack/react-store" "^0.2.1" + tiny-invariant "^1.3.1" + tiny-warning "^1.0.3" + "@tanstack/react-store@^0.2.1": version "0.2.1" resolved "https://registry.yarnpkg.com/@tanstack/react-store/-/react-store-0.2.1.tgz#c1a04c85d403d842e56c6d0709211f013bdd1021" @@ -2765,6 +2780,11 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" +react-intersection-observer@^9.8.2: + version "9.8.2" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.8.2.tgz#a45db2441909a4d2f310de381686e151f016691d" + integrity sha512-901naEiiZmse3p+AmtbQ3NL9xx+gQ8TXLiGDc+8GiE3JKJkNV3vP737aGuWTAXBA+1QqxPrDDE+fIEgYpGDlrQ== + react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" @@ -3390,3 +3410,8 @@ zod@^3.22.4: version "3.22.4" resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== + +zod@^3.22.5: + version "3.22.5" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.5.tgz#b9b09db03f6700b0d0b75bf0dbf0c5fc46155220" + integrity sha512-HqnGsCdVZ2xc0qWPLdO25WnseXThh0kEYKIdV5F/hTHO75hNZFp8thxSeHhiPrHZKrFTo1SOgkAj9po5bexZlw==