This commit is contained in:
고동영
2024-01-24 13:52:43 +09:00
parent 75e00c4485
commit 32c446f1ae
43 changed files with 935 additions and 32 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#606060" d="M5.501 5.882c-.832 0-1.508.68-1.508 1.52s.676 1.52 1.508 1.52h2.663a1.51 1.51 0 0 1 1.476 1.216l4.544 22.494c.429 2.124 2.281 3.651 4.431 3.651h.292a3.041 3.041 0 0 0-1.347 2.532c0 1.679 1.348 3.04 3.014 3.04 1.666 0 3.015-1.361 3.015-3.04a3.042 3.042 0 0 0-1.348-2.532h10.734a3.044 3.044 0 0 0-1.347 2.532c0 1.679 1.349 3.04 3.014 3.04 1.665 0 3.015-1.361 3.015-3.04a3.042 3.042 0 0 0-1.348-2.532h1.348c.832 0 1.507-.681 1.507-1.521 0-.84-.675-1.52-1.507-1.52H18.615a1.508 1.508 0 0 1-1.476-1.217l-.573-2.837h22.136a3.022 3.022 0 0 0 2.957-2.443l2.09-10.545c.235-1.181-.599-2.307-1.788-2.415l-29.045-2.663-.322-1.59c-.429-2.124-2.281-3.65-4.43-3.65H5.501z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 838 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#EEE" d="M5.501 5.838A1.5 1.5 0 0 0 3.993 7.33a1.5 1.5 0 0 0 1.508 1.491h2.662c.717 0 1.334.5 1.478 1.194l4.543 22.073c.429 2.084 2.281 3.582 4.431 3.582h.292a2.973 2.973 0 0 0-1.347 2.486c0 1.647 1.348 2.983 3.014 2.983 1.666 0 3.015-1.336 3.015-2.983a2.974 2.974 0 0 0-1.348-2.486h10.734a2.975 2.975 0 0 0-1.347 2.486c0 1.647 1.349 2.983 3.015 2.983 1.664 0 3.014-1.336 3.014-2.983a2.972 2.972 0 0 0-1.349-2.486h1.349a1.5 1.5 0 0 0 1.507-1.492 1.5 1.5 0 0 0-1.507-1.492H18.615a1.5 1.5 0 0 1-1.476-1.194l-.573-2.783h22.136a3.01 3.01 0 0 0 2.957-2.398l2.09-10.348c.235-1.159-.598-2.263-1.788-2.37L12.916 10.98l-.322-1.561c-.429-2.084-2.281-3.581-4.431-3.581H5.501z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 834 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#606060" d="M11 7.1c-1.657 0-3.9 2.243-3.9 3.9v8.1c0 2.556 2.243 3 3.9 3h8.1c2.557 0 3.9-.444 3.9-3V11c0-1.657-1.343-3.9-3.9-3.9H11zm0 18.899c-1.657 0-3.9 1.344-3.9 3.001v8.1c0 2.556 2.243 3 3.9 3h8.1c2.557 0 3.9-.444 3.9-3V29c0-1.657-1.343-3.001-3.9-3.001H11zM25.999 29A3.002 3.002 0 0 1 29 25.999h8.1c2.557 0 3 1.344 3 3.001v8.1c0 2.556-.443 3-3 3H29c-1.657 0-3.001-.444-3.001-3V29zm7.501-6.9c-.829 0-1.501.172-1.501-.727v-3.374c0-.551-.447-1.899-1.899-1.899h-2.474c-.899 0-1.627.228-1.627-.6s.728-1.501 1.627-1.501H30.1c1.452 0 1.899-.447 1.899-1.899V9.626c0-.898.672-2.526 1.501-2.526.829 0 1.501 1.628 1.501 2.526V12.1c0 1.452.447 1.899.099 1.899h4.274c.898 0 .726.673.726 1.501 0 .828.172.6-.726.6H35.1c.348 0-.099 1.348-.099 1.899v3.374c0 .899-.672.727-1.501.727z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 940 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#EEE" d="M10.1 7.916c-.757 0-3 1.319-3 2.944v8.832c0 1.625 2.243 2.944 3 2.944h9c2.557 0 3.9-1.319 3.9-2.944V10.86c0-1.625-1.343-2.944-3.9-2.944h-9zm0 17.663c-.757 0-3 1.319-3 2.945v8.831c0 1.626 2.243 2.944 3 2.944h9c2.557 0 3.9-1.318 3.9-2.944v-8.831c0-1.626-1.343-2.945-3.9-2.945h-9zm15.899 2.945c0-1.626 1.344-2.945 3.001-2.945h8.1c2.557 0 3.899 1.319 3.899 2.945v8.831c0 1.626-1.342 2.944-3.899 2.944H29c-1.657 0-3.001-1.318-3.001-2.944v-8.831zm7.501-5.888c-.829 0-1.5-.714-1.5-1.597v-3.31c0-.542-.448-.981-1.9-.981h-2.474c-.898 0-1.627-.659-1.627-1.472 0-.812.729-1.473 1.627-1.473H30.1c1.452 0 1.9-.438 1.9-.98v-3.31c0-.882.671-1.597 1.5-1.597s1.501.715 1.501 1.597v3.31c0 .542.447.98.099.98h4.274c.898 0 1.625.661 1.625 1.473 0 .813-.727 1.472-1.625 1.472H35.1c.348 0-.099.439-.099.981v3.31c0 .883-.672 1.597-1.501 1.597z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 999 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
<path fill-rule="evenodd" fill="#606060" d="M8.827 16.606a4.039 4.039 0 0 0-1.828 3.383V36.95c0 2.226 1.792 4.029 4.002 4.029H37c2.21 0 4-1.803 4-4.029V19.989c0-1.367-.687-2.64-1.827-3.383L25.087 7.425a1.988 1.988 0 0 0-2.173 0L8.827 16.606zM29.001 40.1v-9.23A2.007 2.007 0 0 0 27 28.856h-6.9c-.204 0-1.1.901-1.1 2.014v9.23"/>
</svg>

After

Width:  |  Height:  |  Size: 461 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill="none" d="M0 0h48v48H0V0z"/>
<path fill-rule="evenodd" fill="#EEE" d="M8.827 16.381A3.94 3.94 0 0 0 7.001 19.7v16.644c0 2.184 1.79 3.954 3.099 3.954H37c2.21 0 4-1.77 4-3.954V19.7a3.937 3.937 0 0 0-1.828-3.319l-14.085-9.01a2.02 2.02 0 0 0-2.173 0l-14.087 9.01zm20.174 23.937v-9.941c0-1.092-.897-1.976-2-1.976H20.1c-.206 0-2 .884-2 1.976v9.941"/>
</svg>

After

Width:  |  Height:  |  Size: 435 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#606060" d="M22.723 42.112a2.016 2.016 0 0 1-2.852 0L5.614 27.856a2.018 2.018 0 0 1 0-2.852l19.962-19.96 15.695 1.44 1.413 15.669-19.961 19.959zm10.762-27.866a3.78 3.78 0 0 0-5.344 5.345 3.78 3.78 0 0 0 5.344-5.345z"/>
<path opacity=".302" fill="none" d="M0 0h48v47.1H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 387 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#EEE" d="M22.723 41.41a2.042 2.042 0 0 1-2.851 0L5.614 27.42a1.953 1.953 0 0 1 0-2.798L25.576 5.034l15.695 1.413 1.413 15.376L22.723 41.41zm10.762-27.346a3.833 3.833 0 0 0-5.345 0 3.662 3.662 0 0 0 0 5.245 3.831 3.831 0 0 0 5.345 0 3.66 3.66 0 0 0 0-5.245z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#606060" d="M24 22c4.419 0 7.1-3.582 7.1-8.9 0-3.519-2.681-8-7.1-8-4.418 0-7.999 4.481-7.999 8 0 5.318 3.581 8.9 7.999 8.9zm-6.001 3.999C11.373 25.999 5.1 30.373 5.1 37v1.1c0 2.557 2.243 3 3.9 3h29.1c2.556 0 3-.443 3-3V37c0-6.627-4.473-11.001-11.1-11.001H17.999z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 432 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#EEE" d="M24 21.673c4.419 0 8-3.514 8-7.85s-3.581-7.851-8-7.851c-4.418 0-7.999 3.515-7.999 7.851s3.581 7.85 7.999 7.85zm-6.9 3.925c-5.727 0-12 4.292-12 10.795v1.962c0 1.626 2.243 2.944 3 2.944H39c1.657 0 2.1-1.318 2.1-2.944v-1.962c0-6.503-4.472-10.795-12-10.795h-12z"/>
<path opacity=".302" fill="none" d="M0 0h47.1v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 438 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#606060" d="M42.1 17.999c0 2.762-2.672 5.166-5.434 5.166s-5.833-2.238-5.833-4.999c0 2.761-4.071 4.999-6.833 4.999-2.761 0-6.833-2.238-6.833-4.999 0 2.761-3.072 4.999-5.834 4.999-2.761 0-7.233-2.404-7.233-5.166 0-.284.854-.727 0-1.899l3.772-8.406C7.944 6.831 9.133 5.1 10.001 5.1h27.998c.869 0 2.057 1.731 2.129 2.594L42.1 16.1c.945 1.172 0 1.615 0 1.899zm-24.933 5.759c1.327 1.187 4.912 1.91 6.833 1.91 1.922 0 5.506-.723 6.833-1.91 1.327 1.187 3.912 1.91 5.833 1.91a7.473 7.473 0 0 0 3.334-.78v13.445c0 1.841-1.158 2.767-3.9 2.767H29v-9c0-.021-1.079-2-2.9-2h-5.101c-.919 0-1.999 1.979-1.999 2v9h-8c-1.841 0-3.001-.926-3.001-2.767V24.888a7.476 7.476 0 0 0 3.334.78c1.922 0 4.506-.723 5.834-1.91z"/>
<path opacity=".302" fill="none" d="M0 0h48v47.1H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 867 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#EEE" d="M42.1 17.747c0 2.71-2.672 5.07-5.434 5.07s-5.833-2.197-5.833-4.906c0 2.709-4.071 4.906-7.733 4.906-1.861 0-5.933-2.197-5.933-4.906 0 2.709-3.072 4.906-5.834 4.906-2.762 0-7.233-2.36-7.233-5.07 0-.279.854-.713 0-.981l3.772-9.131C7.944 6.788 9.134 5.972 10 5.972h27.999c.868 0 2.057.816 2.128 1.663l1.973 9.131c.946.268 0 .702 0 .981zm-24.933 5.651c1.327 1.165 4.912 1.875 5.933 1.875 2.822 0 6.406-.71 7.733-1.875 1.327 1.165 3.912 1.875 5.833 1.875 1.199 0 2.329-.276 2.434-.766v13.194c0 1.806-.258 3.598-2.101 3.598H29v-8.832c0-.903-1.079-1.962-2.9-1.962h-6c-.02 0-1.1 1.059-1.1 1.962v8.832h-8.9c-.941 0-2.101-1.792-2.101-3.598V24.507a7.592 7.592 0 0 0 3.334.766c1.922 0 4.506-.71 5.834-1.875z"/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
</svg>

After

Width:  |  Height:  |  Size: 873 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
<path fill-rule="evenodd" fill="#606060" d="M24 42.999c10.493 0 19.001-8.506 19.001-19.899C43.001 13.506 34.493 5 24 5 13.507 5 5 13.506 5 23.1c0 11.393 8.507 19.899 19 19.899zm-6.147-22.351a2.795 2.795 0 1 0 0-5.588 2.795 2.795 0 0 0 0 5.588zm14.038-2.168a1.676 1.676 0 1 0-2.37-2.371L16.109 29.52a1.676 1.676 0 1 0 2.37 2.371L31.891 18.48zm1.051 11.667a2.794 2.794 0 1 1-5.589-.003 2.794 2.794 0 0 1 5.589.003z"/>
</svg>

After

Width:  |  Height:  |  Size: 550 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
<path fill-rule="evenodd" fill="#EEE" d="M24 41.999c10.493 0 19.001-8.284 19.001-18.504S34.493 4.992 24 4.992c-10.493 0-19 8.283-19 18.503s8.507 18.504 19 18.504zM17.853 20.23c1.544 0 2.794-1.218 2.794-2.721 0-1.503-1.25-2.721-2.794-2.721-1.543 0-2.794 1.218-2.794 2.721 0 1.503 1.251 2.721 2.794 2.721zm14.038-2.111a1.602 1.602 0 0 0 0-2.309 1.707 1.707 0 0 0-2.37 0L16.109 28.872a1.601 1.601 0 0 0 0 2.308 1.707 1.707 0 0 0 2.37 0l13.412-13.061zm1.05 11.363c0 1.503-1.25 2.72-2.795 2.72-1.542 0-2.793-1.217-2.793-2.72 0-1.503 1.251-2.721 2.793-2.721 1.545 0 2.795 1.218 2.795 2.721z"/>
</svg>

After

Width:  |  Height:  |  Size: 722 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v47.1H0V0z"/>
<path fill-rule="evenodd" fill="#606060" d="M20.424 5.985c7.973 0 14.438 6.515 14.438 14.552 0 8.036-6.465 14.55-14.438 14.55-7.974 0-14.439-6.514-14.439-14.55 0-8.037 6.465-14.552 14.439-14.552zM35.082 32.209l6.32 6.369a2.012 2.012 0 0 1 0 2.831 1.974 1.974 0 0 1-2.808 0l-6.321-6.369a2.014 2.014 0 0 1 0-2.831 1.975 1.975 0 0 1 2.809 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 478 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z"/>
<path fill-rule="evenodd" fill="#EEE" d="M20.424 5.958c7.973 0 14.438 6.393 14.438 14.279s-6.465 14.279-14.438 14.279c-7.974 0-14.439-6.393-14.439-14.279S12.45 5.958 20.424 5.958zM35.083 31.691l6.319 6.251c.776.767.776 2.01 0 2.778a2.002 2.002 0 0 1-2.809 0l-6.32-6.251a1.95 1.95 0 0 1 0-2.778 2.003 2.003 0 0 1 2.81 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#606060" d="m40.657 39.908-5.195-.883a1.091 1.091 0 0 0-1.207.685l-1.82 4.87c-.319.852-1.504.952-1.965.166l-7.221-12.308c.234.009.468.014.703.014 4.536 0 8.641-1.821 11.601-4.76l6.232 10.625c.46.786-.219 1.746-1.128 1.591zM23.951 29.241c-7.215 0-13.065-5.757-13.065-12.858 0-7.102 5.85-12.858 13.065-12.858s13.066 5.756 13.066 12.858c0 7.101-5.851 12.858-13.066 12.858zm4.836-15.436-1.989-.424a1.206 1.206 0 0 1-.785-.56L24.99 11.09c-.463-.782-1.611-.782-2.075 0l-1.024 1.731c-.169.286-.453.49-.783.56l-1.989.424c-.899.191-1.254 1.266-.641 1.941l1.357 1.494c.224.247.332.576.299.905l-.205 1.994c-.093.901.837 1.564 1.677 1.199l1.863-.807c.309-.133.66-.133.968 0l1.863.807c.84.365 1.771-.298 1.677-1.199l-.205-1.994a1.173 1.173 0 0 1 .299-.905l1.357-1.494c.612-.675.258-1.75-.641-1.941zM19.06 31.719l3.006 5.126-4.633 7.898c-.461.787-1.647.687-1.964-.165l-1.819-4.87a1.093 1.093 0 0 0-1.208-.686l-5.195.883c-.91.156-1.59-.804-1.128-1.591l6.231-10.622a16.372 16.372 0 0 0 6.71 4.027z"/>
<path opacity=".302" fill="none" d="M-.015.012h48v48h-48v-48z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path fill-rule="evenodd" fill="#EEE" d="m40.657 39.228-5.195-.867a1.094 1.094 0 0 0-1.207.673l-1.821 4.778c-.318.837-1.503.935-1.964.163l-7.221-12.078c.233.009.468.014.703.014 4.536 0 8.641-1.786 11.6-4.671l6.233 10.427c.461.771-.22 1.713-1.128 1.561zM23.951 28.76c-7.215 0-13.065-5.649-13.065-12.617 0-6.969 5.85-12.618 13.065-12.618s13.065 5.649 13.065 12.618c0 6.968-5.85 12.617-13.065 12.617zm4.836-15.148-1.989-.415a1.2 1.2 0 0 1-.784-.55l-1.025-1.698c-.462-.768-1.61-.768-2.074 0l-1.024 1.698a1.197 1.197 0 0 1-.784.55l-1.988.415c-.898.188-1.254 1.243-.641 1.905l1.357 1.467c.224.242.332.564.299.888l-.205 1.956c-.093.884.837 1.535 1.678 1.177l1.862-.792c.309-.131.661-.131.968 0l1.863.792c.841.358 1.771-.293 1.678-1.177l-.206-1.956a1.136 1.136 0 0 1 .299-.888l1.357-1.467c.611-.662.258-1.717-.641-1.905zm-9.727 17.58 3.006 5.03-4.633 7.751c-.461.772-1.647.674-1.963-.163l-1.82-4.778a1.096 1.096 0 0 0-1.208-.674l-5.195.867c-.91.153-1.59-.789-1.128-1.562L12.35 27.24a16.429 16.429 0 0 0 6.71 3.952z"/>
<path opacity=".302" fill="none" d="M-.015.012h48v48h-48v-48z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,17 +1,19 @@
import React, { useEffect } from "react";
import ThemeDecorator from "@enact/sandstone/ThemeDecorator"; import ThemeDecorator from "@enact/sandstone/ThemeDecorator";
import React, { useEffect } from "react";
import css from "./App.module.less"; import css from "./App.module.less";
import MainView from "../views/MainView/MainView"; import MainView from "../views/MainView/MainView";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch } from "react-redux";
import { fetchAuthenticationCode } from "../features/auth/authThunks"; import { fetchAuthenticationCode } from "../features/auth/authThunks";
import { fetchHomeMenu } from "../features/menu/menuThunks";
function AppBase(props) { function AppBase(props) {
const dispatch = useDispatch(); const dispatch = useDispatch();
useEffect(() => { useEffect(() => {
dispatch(fetchAuthenticationCode()); dispatch(fetchAuthenticationCode());
dispatch(fetchHomeMenu());
}, [dispatch]); }, [dispatch]);
return <MainView />; return <MainView />;

View File

@@ -12,6 +12,7 @@ export const URLS = {
//home controller //home controller
GET_HOME_TERMS: "/lgsp/v1/home/terms.lge", GET_HOME_TERMS: "/lgsp/v1/home/terms.lge",
GET_HOME_MENU: "/lgsp/v1/home/menu.lge",
//on-sale controller //on-sale controller
GET_ON_SALE_INFO: "/lgsp/v1/onsale/onsale.lge", GET_ON_SALE_INFO: "/lgsp/v1/onsale/onsale.lge",

View File

@@ -17,7 +17,20 @@ export async function getHomeMainContents() {}
export async function getHomeLayout() {} export async function getHomeLayout() {}
// 메뉴 목록 조회 IF-LGSP-044 // 메뉴 목록 조회 IF-LGSP-044
export async function getHomeMenu() {} export async function getHomeMenu() {
try {
const response = await api.get(URLS.GET_HOME_MENU, {
headers: {
lgsp_auth:
"idAfo9EFgAKcoblkOVTBL1o3rnFjw/8n8Wqd6ToStVBXJE7NE4G2L9y2rHH2z1GeufkrdBN5K14kFCxYhDBFewoj7m02hDe5vlLFzfbDAs8gZlyZUMu5bD79Dn2d5+Bb1Nd1Cg==",
},
});
return response.data;
} catch (error) {
console.log("Error", error);
throw error;
}
}
// 약관 정보 조회 IF-LGSP-005 // 약관 정보 조회 IF-LGSP-005
export async function getHomeTerms(props) { export async function getHomeTerms(props) {

View File

@@ -0,0 +1,81 @@
import { Marquee, MarqueeController } from "@enact/sandstone/Marquee";
import Spottable from "@enact/spotlight/Spottable";
import { getTargetByDirectionFromElement } from "@enact/spotlight/src/target";
import classNames from "classnames";
import compose from "ramda/src/compose";
import { useCallback, useMemo, useRef, useState } from "react";
import css from "./TabItem.module.less";
const SpottableComponent = Spottable("div");
const TabItemBase = ({
icons,
title,
expanded = false,
selected = false,
index = 0,
deActivateTab,
className,
...rest
}) => {
const [focused, setFocused] = useState(false);
const itemRef = useRef();
const _onFocus = useCallback(() => {
setFocused(true);
}, [index]);
const _onBlur = useCallback(() => {
setFocused(false);
}, []);
const isDivider = useMemo(() => {
return !title;
}, []);
const onKeyDown = useCallback(
(event) => {
if (event.key === "ArrowRight") {
const next = getTargetByDirectionFromElement(
"right",
itemRef.current.node
);
if (!next && deActivateTab) {
deActivateTab();
}
}
},
[deActivateTab]
);
const renderIcon = useCallback(() => {
if (icons) {
const Component = icons;
return <Component iconType={focused ? "expanded" : "normal"} />;
} else {
return null;
}
}, [focused, selected, expanded]);
return (
<SpottableComponent
ref={itemRef}
className={classNames(
css.tabItem,
focused && css.focused
//!isDivider && selected && css.selected
)}
onKeyDown={onKeyDown}
onFocus={_onFocus}
onBlur={_onBlur}
spotlightDisabled={isDivider}
>
{icons && <div className={css.icon}>{renderIcon()}</div>}
{expanded && title && (
<Marquee marqueeOn={"focus"} className={classNames(css.text)}>
{title}
</Marquee>
)}
</SpottableComponent>
);
};
const ItemDecorator = compose(MarqueeController({ marqueeOnFocus: true }));
const TabItem = ItemDecorator(TabItemBase);
export default TabItem;

View File

@@ -0,0 +1,55 @@
@ICON_SIZE: 48px;
.tabItem{
padding: 18px 12px 18px 42px;
font-size: 36px;
display: flex;
color: #606060;
align-items: center;
&.focused {
color: #ffffff;
background: linear-gradient(#cb1253, #e15ba1);
border-radius: 42px;
width: 402px;
}
.icon {
position: relative;
min-width: @ICON_SIZE;
height: @ICON_SIZE;
> img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
> svg {
position: absolute;
width: @ICON_SIZE;
height: @ICON_SIZE;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
.text {
width: 100%;
line-height: 36px;
padding-left: 18px;
padding-top: 6px;
flex-grow: 1;
flex-shrink: 1;
overflow: hidden;
}
.marqueeWrap {
width: 100%;
}
}

View File

@@ -1,45 +1,457 @@
import { useMemo } from "react"; import Spotlight from "@enact/spotlight";
import { useDispatch } from "react-redux"; import classNames from "classnames";
import { addPanels } from "../../features/panels/panelsSlice"; import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { useDispatch, useSelector } from "react-redux";
import TabItem from "./TabItem";
import css from "./TabLayout.module.less";
//enact
import Skinnable from "@enact/sandstone/Skinnable";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import { Cancelable } from "@enact/ui/Cancelable";
//아이콘
import { Job } from "@enact/core/util";
import CartIcon from "./iconComponents/CartIcon";
import CategoryIcon from "./iconComponents/CategoryIcon";
import FeaturedBrandIcon from "./iconComponents/FeaturedBrandIcon";
import HomeIcon from "./iconComponents/HomeIcon";
import HotPicksIcon from "./iconComponents/HotPicksIcon";
import MyPageIcon from "./iconComponents/MyPageIcon";
import OnSaleIcon from "./iconComponents/OnSaleIcon";
import SearchIcon from "./iconComponents/SearchIcon";
import TrendingNowIcon from "./iconComponents/TrendingNowIcon";
//이미지
import shoptimeFullIcon from "../../../assets/icons/ic-lnb-logo-shoptime@3x.png";
import shopTimeIcon from "../../../assets/icons/ic-lnb-shoptime-symbol@3x.png";
import * as Config from "../../utils/Config"; const Container = SpotlightContainerDecorator(
import { $L } from "../../utils/helperMethods"; { enterTo: "default-element" },
"div"
);
export default function TabLayout(props) { const MainContainer = SpotlightContainerDecorator(
{ enterTo: "last-focused", continue5WayHold: true },
"div"
);
const CancelableDiv = Cancelable(
{ modal: true, onCancel: "handleCancel" },
Skinnable(Container)
);
class TabMenuItem {
constructor(icons = "", title = "", target, children = []) {
this.icons = icons;
this.title = title;
this.target = target;
this.children = []; //TabMenuItem
if (children && children.length > 0) {
for (let i = 0; i < children.length; i++) {
const tabmenu = new TabMenuItem(
children[i].icons,
children[i].title,
children[i].target,
children[i].children
);
this.children.push(tabmenu);
}
}
}
hasChildren = () => {
return this.children.length > 0;
};
getChildren = () => {
return this.children;
};
}
const deActivateTabJabFunc = (func) => {
func();
};
let deActivateTabJob = new Job(deActivateTabJabFunc, 2000);
const COLLABSED_MAIN = 0;
const ACTIVATED_MAIN = 1;
const ACTIVATED_SUB = 2;
const EXTRA_AREA = 3;
export default function TabLayout({ topPanelName, onTabActivated }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [mainExpanded, setMainExpanded] = useState(false);
const [mainSelectedIndex, setMainSelectedIndex] = useState(-1);
const [tabs, setTabs] = useState([]);
const [tabFocused, setTabFocused] = useState([false, false, false]); //COLLABSED_MAIN, ACTIVATED_MAIN, ACTIVATED_SUB
const panelSwitching = useRef(null);
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const titles = useSelector((state) => state.menu.title);
// const items = useSelector((state) => state.menu.items);
const menuItems = useMemo( const menuItems = useMemo(
() => [ () => [
{ label: $L("MY PAGE"), panel: Config.panel_names.MY_PAGE_PANEL },
{ label: $L("CATEGORY"), panel: Config.panel_names.CATEGORY_PANEL },
{ label: $L("SEARCH"), panel: Config.panel_names.SEARCH_PANEL },
{ label: $L("HOME"), panel: Config.panel_names.HOME_PANEL },
{ label: $L("ON SALE"), panel: Config.panel_names.ON_SALE_PANEL },
{ {
label: $L("TRENDING NOW"), title: titles[1],
panel: Config.panel_names.TRENDING_NOW_PANEL, icons: CategoryIcon,
children: [
{
title: "123123",
target: [],
},
],
}, },
{ label: $L("HOT PICKS"), panel: Config.panel_names.HOT_PICKS_PANEL },
{ label: $L("CART"), panel: Config.panel_names.CART_PANEL },
{ {
label: $L("FEATURED BRANDS"), title: titles[0],
panel: Config.panel_names.FEATURED_BRANDS_PANEL, icons: MyPageIcon,
children: [
{
title: "123123",
target: [],
},
],
}, },
{
title: titles[2],
icons: SearchIcon,
children: [
{
title: "12323232",
target: [],
},
],
},
{
title: titles[3],
icons: HomeIcon,
children: [
{
title: "43534543",
target: [],
},
],
},
{
title: titles[8],
icons: FeaturedBrandIcon,
children: [
{
title: "dsadasd",
target: [],
},
],
},
{
title: titles[4],
icons: OnSaleIcon,
children: [
{
title: "",
target: [],
},
],
},
{
title: titles[5],
icons: TrendingNowIcon,
},
{
title: titles[6],
icons: HotPicksIcon,
},
{
title: titles[7],
icons: CartIcon,
},
// 메뉴 추가 필요 20240112 chw
], ],
[] [mainExpanded]
); );
const handleNavigation = (panel) => { const makeTabmenu = useCallback(() => {
dispatch(addPanels({ name: panel, panelInfo: {} })); const t = [];
};
for (let i = 0; i < menuItems.length; i++) {
const tabmenu = new TabMenuItem(
menuItems[i].icons,
menuItems[i].title,
menuItems[i].target,
menuItems[i].children
);
t.push(tabmenu);
}
return t;
}, []);
useEffect(() => {
setTabs(makeTabmenu());
}, []);
const deActivateTab = useCallback(() => {
setTabFocused([false, false, false, false]);
setMainSelectedIndex(-1);
setMainExpanded(false);
}, []);
const onTabHasFocus = useCallback(
(type) => (event) => {
switch (type) {
case COLLABSED_MAIN:
case ACTIVATED_MAIN: {
console.log("#tabs[mainSelectedIndex]", tabs[mainSelectedIndex]);
if (!cursorVisible) {
const parent = event.target.parentNode;
const children = parent.childNodes;
const index = Array.prototype.indexOf.call(children, event.target);
setMainExpanded(true);
setMainSelectedIndex(index);
} else {
if (!panelSwitching.current) {
setMainExpanded(true);
}
}
break;
}
case ACTIVATED_SUB: {
setMainExpanded(false);
break;
}
case EXTRA_AREA: {
if (cursorVisible) {
deActivateTabJob.start(deActivateTab);
return;
}
}
}
setTabFocused((prevState) => {
const prev = [...prevState];
prev[type] = true;
return prev;
});
},
[cursorVisible, deActivateTab]
);
const onTabBlur = useCallback(
(type) => (event) => {
switch (type) {
case ACTIVATED_MAIN: {
if (!cursorVisible) {
setMainExpanded(false);
}
break;
}
case ACTIVATED_SUB: {
if (!cursorVisible) {
}
break;
}
case EXTRA_AREA: {
if (cursorVisible) {
deActivateTabJob.stop();
return;
}
}
}
setTabFocused((prevState) => {
const prev = [...prevState];
prev[type] = true;
return prev;
});
},
[cursorVisible]
);
const handleNavigation = useCallback(
({ index, target }) => {
setMainSelectedIndex(index);
if (target) {
// dispatch(resetPanels(target));
deActivateTab();
} else if (cursorVisible) {
setMainExpanded(true);
}
},
[cursorVisible, deActivateTab, dispatch]
);
const onClickSubItem = useCallback(
({ index, target }) => {
if (target) {
// dispatch(resetPanels(target));
deActivateTab();
panelSwitching.current = true;
// panelSwitchingJob.start(panelSwitching);
}
},
[dispatch, deActivateTab]
);
const onClickExtraArea = useCallback(
({ index, target }) => {
deActivateTabJob.startAfter(100, deActivateTab);
},
[dispatch, deActivateTab]
);
const tabActivated = useMemo(() => {
return mainExpanded || mainSelectedIndex >= 0;
}, [mainExpanded, mainSelectedIndex]);
const showTab = useMemo(() => {
if (!topPanelName) {
return true;
}
return false;
}, [topPanelName]);
const showSubTab = useMemo(() => {
if (
tabActivated &&
tabs[mainSelectedIndex] &&
tabs[mainSelectedIndex].hasChildren()
) {
return true;
}
return false;
}, [tabActivated, tabs, mainSelectedIndex]);
const backKeyHandler = useCallback(
(ev) => {
if (tabActivated) {
deActivateTab();
ev.stopPropagation();
ev.preventDefault();
return true;
}
},
[tabActivated, deActivateTab]
);
useEffect(() => {
if (tabActivated) {
setTimeout(() => {
Spotlight.focus("activatedMain");
}, 0);
}
if (onTabActivated) {
onTabActivated(tabActivated && showTab);
}
}, [tabActivated, showTab]);
useEffect(() => {}, [showSubTab, mainSelectedIndex]);
if (!showTab) {
return null;
}
return ( return (
<div> <>
{menuItems.map((item, index) => ( {/* collabsed Main */}
<button key={index} onClick={() => handleNavigation(item.panel)}> <Container
{item.label} className={css.tabWrap}
</button> onFocus={onTabHasFocus(COLLABSED_MAIN)}
))} onMouseOver={onTabHasFocus(COLLABSED_MAIN)}
</div> onBlur={onTabBlur(COLLABSED_MAIN)}
onMouseLeave={onTabBlur(COLLABSED_MAIN)}
>
<img className={css.logo} src={shopTimeIcon} alt="" />
{tabs.map((item, index) => (
<TabItem
key={"tabitem" + index}
expanded={false}
selected={mainSelectedIndex === index}
index={index}
onClick={handleNavigation}
icons={item.icons}
/>
))}
</Container>
{
<CancelableDiv
spotlightRestrict="self-only"
spotlightId="activatedMain"
className={classNames(
css.expandedRootContainer,
!tabActivated && css.hide
)}
handleCancel={backKeyHandler}
>
{/* expanded Main */}
<MainContainer
className={classNames(css.tabWrap, mainExpanded && css.expanded)}
onFocus={onTabHasFocus(ACTIVATED_MAIN)}
onMouseOver={onTabHasFocus(COLLABSED_MAIN)}
onBlur={onTabBlur(ACTIVATED_MAIN)}
onMouseLeave={onTabBlur(ACTIVATED_MAIN)}
>
<img
className={classNames(css.logo, mainExpanded && css.expanded)}
src={mainExpanded ? shoptimeFullIcon : shopTimeIcon}
alt=""
/>
{tabActivated &&
tabs.map((item, index) => (
<TabItem
key={"tabitemExpanded" + index}
onClick={handleNavigation}
deActivateTab={deActivateTab}
icons={item.icons}
expanded={mainExpanded}
selected={mainSelectedIndex === index}
title={item.title}
index={index}
/>
))}
</MainContainer>
{/* Sub */}
{
<Container
spotlightId="activatedSub"
className={classNames(
css.tabWrap,
css.secondDepthLayout,
!showSubTab && css.hide
)}
onFocus={onTabHasFocus(ACTIVATED_SUB)}
onMouseOver={onTabHasFocus(ACTIVATED_SUB)}
onBlur={onTabBlur(ACTIVATED_SUB)}
onMouseLeave={onTabBlur(ACTIVATED_SUB)}
>
{showSubTab &&
tabs[mainSelectedIndex].children.map((item, index) => {
return (
<TabItem
key={"tabitemSubmenu" + index}
onClick={onClickSubItem}
{...item}
expanded={true}
index={index}
isSubItem={true}
mainExpanded={mainExpanded}
deActivateTab={deActivateTab}
title={item.title}
/>
);
})}
</Container>
}
{/* Extra Area*/}
{tabActivated && (
<Container
className={classNames(css.tabWrap, css.extraArea)}
onClick={onClickExtraArea}
onFocus={onTabHasFocus(EXTRA_AREA)}
onMouseOver={onTabHasFocus(EXTRA_AREA)}
onBlur={onTabBlur(EXTRA_AREA)}
onMouseLeave={onTabBlur(EXTRA_AREA)}
/>
)}
</CancelableDiv>
}
</>
); );
} }

View File

@@ -0,0 +1,62 @@
.expandedRootContainer {
position: absolute;
display: flex;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
&.hide {
width: auto;
z-index: 0;
}
}
.tabWrap {
background-color: #222222;
width: 120px;
display: flex;
flex-direction: column;
justify-content: center;
// padding-top: 104px;
// padding-bottom: 104px;
z-index: 1;
flex-grow: 0;
transition: width 0.5s ease;
&.expanded {
width: 402px;
}
&.secondDepthLayout {
width: 386px;
height: calc(100%);
opacity: 0.95;
box-shadow: 8px 0 36px rgba(33, 33, 32, 0.08);
padding-bottom: unset;
justify-content: flex-start;
}
&.extraArea {
flex-grow: 1;
background-color: rgba(0, 0, 0, 0);
transition: initial;
}
&.hide {
width: 0;
}
}
.logo {
width: 54px;
height: 54px;
margin-left: 42px;
margin-bottom: 84px;
&.expanded {
width: 234px;
height: 54px;
}
}

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const CartIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M5.501 5.882c-.832 0-1.508.68-1.508 1.52s.676 1.52 1.508 1.52h2.663a1.51 1.51 0 0 1 1.476 1.216l4.544 22.494c.429 2.124 2.281 3.651 4.431 3.651h.292a3.041 3.041 0 0 0-1.347 2.532c0 1.679 1.348 3.04 3.014 3.04 1.666 0 3.015-1.361 3.015-3.04a3.042 3.042 0 0 0-1.348-2.532h10.734a3.044 3.044 0 0 0-1.347 2.532c0 1.679 1.349 3.04 3.014 3.04 1.665 0 3.015-1.361 3.015-3.04a3.042 3.042 0 0 0-1.348-2.532h1.348c.832 0 1.507-.681 1.507-1.521 0-.84-.675-1.52-1.507-1.52H18.615a1.508 1.508 0 0 1-1.476-1.217l-.573-2.837h22.136a3.022 3.022 0 0 0 2.957-2.443l2.09-10.545c.235-1.181-.599-2.307-1.788-2.415l-29.045-2.663-.322-1.59c-.429-2.124-2.281-3.65-4.43-3.65H5.501z"
/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z" />
</svg>
);
};
export default CartIcon;

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const CategoryIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M11 7.1c-1.657 0-3.9 2.243-3.9 3.9v8.1c0 2.556 2.243 3 3.9 3h8.1c2.557 0 3.9-.444 3.9-3V11c0-1.657-1.343-3.9-3.9-3.9H11zm0 18.899c-1.657 0-3.9 1.344-3.9 3.001v8.1c0 2.556 2.243 3 3.9 3h8.1c2.557 0 3.9-.444 3.9-3V29c0-1.657-1.343-3.001-3.9-3.001H11zM25.999 29A3.002 3.002 0 0 1 29 25.999h8.1c2.557 0 3 1.344 3 3.001v8.1c0 2.556-.443 3-3 3H29c-1.657 0-3.001-.444-3.001-3V29zm7.501-6.9c-.829 0-1.501.172-1.501-.727v-3.374c0-.551-.447-1.899-1.899-1.899h-2.474c-.899 0-1.627.228-1.627-.6s.728-1.501 1.627-1.501H30.1c1.452 0 1.899-.447 1.899-1.899V9.626c0-.898.672-2.526 1.501-2.526.829 0 1.501 1.628 1.501 2.526V12.1c0 1.452.447 1.899.099 1.899h4.274c.898 0 .726.673.726 1.501 0 .828.172.6-.726.6H35.1c.348 0-.099 1.348-.099 1.899v3.374c0 .899-.672.727-1.501.727z"
/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z" />
</svg>
);
};
export default CategoryIcon;

View File

@@ -0,0 +1,15 @@
import { convertThemeColor } from "./convertThemeColor";
const FeaturedBrandIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M42.1 17.999c0 2.762-2.672 5.166-5.434 5.166s-5.833-2.238-5.833-4.999c0 2.761-4.071 4.999-6.833 4.999-2.761 0-6.833-2.238-6.833-4.999 0 2.761-3.072 4.999-5.834 4.999-2.761 0-7.233-2.404-7.233-5.166 0-.284.854-.727 0-1.899l3.772-8.406C7.944 6.831 9.133 5.1 10.001 5.1h27.998c.869 0 2.057 1.731 2.129 2.594L42.1 16.1c.945 1.172 0 1.615 0 1.899zm-24.933 5.759c1.327 1.187 4.912 1.91 6.833 1.91 1.922 0 5.506-.723 6.833-1.91 1.327 1.187 3.912 1.91 5.833 1.91a7.473 7.473 0 0 0 3.334-.78v13.445c0 1.841-1.158 2.767-3.9 2.767H29v-9c0-.021-1.079-2-2.9-2h-5.101c-.919 0-1.999 1.979-1.999 2v9h-8c-1.841 0-3.001-.926-3.001-2.767V24.888a7.476 7.476 0 0 0 3.334.78c1.922 0 4.506-.723 5.834-1.91z"
/>
<path opacity=".302" fill="none" d="M0 0h48v47.1H0V0z" />
</svg>
);
};
export default FeaturedBrandIcon;

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const HomeIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z" />
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M8.827 16.606a4.039 4.039 0 0 0-1.828 3.383V36.95c0 2.226 1.792 4.029 4.002 4.029H37c2.21 0 4-1.803 4-4.029V19.989c0-1.367-.687-2.64-1.827-3.383L25.087 7.425a1.988 1.988 0 0 0-2.173 0L8.827 16.606zM29.001 40.1v-9.23A2.007 2.007 0 0 0 27 28.856h-6.9c-.204 0-1.1.901-1.1 2.014v9.23"
/>
</svg>
);
};
export default HomeIcon;

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const HotPicksIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M22.723 42.112a2.016 2.016 0 0 1-2.852 0L5.614 27.856a2.018 2.018 0 0 1 0-2.852l19.962-19.96 15.695 1.44 1.413 15.669-19.961 19.959zm10.762-27.866a3.78 3.78 0 0 0-5.344 5.345 3.78 3.78 0 0 0 5.344-5.345z"
/>
<path opacity=".302" fill="none" d="M0 0h48v47.1H0V0z" />
</svg>
);
};
export default HotPicksIcon;

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const MyPageIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M24 22c4.419 0 7.1-3.582 7.1-8.9 0-3.519-2.681-8-7.1-8-4.418 0-7.999 4.481-7.999 8 0 5.318 3.581 8.9 7.999 8.9zm-6.001 3.999C11.373 25.999 5.1 30.373 5.1 37v1.1c0 2.557 2.243 3 3.9 3h29.1c2.556 0 3-.443 3-3V37c0-6.627-4.473-11.001-11.1-11.001H17.999z"
/>
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z" />
</svg>
);
};
export default MyPageIcon;

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const OnSaleIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v48H0V0z" />
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M24 42.999c10.493 0 19.001-8.506 19.001-19.899C43.001 13.506 34.493 5 24 5 13.507 5 5 13.506 5 23.1c0 11.393 8.507 19.899 19 19.899zm-6.147-22.351a2.795 2.795 0 1 0 0-5.588 2.795 2.795 0 0 0 0 5.588zm14.038-2.168a1.676 1.676 0 1 0-2.37-2.371L16.109 29.52a1.676 1.676 0 1 0 2.37 2.371L31.891 18.48zm1.051 11.667a2.794 2.794 0 1 1-5.589-.003 2.794 2.794 0 0 1 5.589.003z"
/>
</svg>
);
};
export default OnSaleIcon;

View File

@@ -0,0 +1,16 @@
import { convertThemeColor } from "./convertThemeColor";
const SearchIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path opacity=".302" fill="none" d="M0 0h48v47.1H0V0z" />
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="M20.424 5.985c7.973 0 14.438 6.515 14.438 14.552 0 8.036-6.465 14.55-14.438 14.55-7.974 0-14.439-6.514-14.439-14.55 0-8.037 6.465-14.552 14.439-14.552zM35.082 32.209l6.32 6.369a2.012 2.012 0 0 1 0 2.831 1.974 1.974 0 0 1-2.808 0l-6.321-6.369a2.014 2.014 0 0 1 0-2.831 1.975 1.975 0 0 1 2.809 0z"
/>
</svg>
);
};
export default SearchIcon;

View File

@@ -0,0 +1,15 @@
import { convertThemeColor } from "./convertThemeColor";
const TrendingNowIcon = ({ iconType = "normal" }) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
fill-rule="evenodd"
fill={convertThemeColor(iconType)}
d="m40.657 39.908-5.195-.883a1.091 1.091 0 0 0-1.207.685l-1.82 4.87c-.319.852-1.504.952-1.965.166l-7.221-12.308c.234.009.468.014.703.014 4.536 0 8.641-1.821 11.601-4.76l6.232 10.625c.46.786-.219 1.746-1.128 1.591zM23.951 29.241c-7.215 0-13.065-5.757-13.065-12.858 0-7.102 5.85-12.858 13.065-12.858s13.066 5.756 13.066 12.858c0 7.101-5.851 12.858-13.066 12.858zm4.836-15.436-1.989-.424a1.206 1.206 0 0 1-.785-.56L24.99 11.09c-.463-.782-1.611-.782-2.075 0l-1.024 1.731c-.169.286-.453.49-.783.56l-1.989.424c-.899.191-1.254 1.266-.641 1.941l1.357 1.494c.224.247.332.576.299.905l-.205 1.994c-.093.901.837 1.564 1.677 1.199l1.863-.807c.309-.133.66-.133.968 0l1.863.807c.84.365 1.771-.298 1.677-1.199l-.205-1.994a1.173 1.173 0 0 1 .299-.905l1.357-1.494c.612-.675.258-1.75-.641-1.941zM19.06 31.719l3.006 5.126-4.633 7.898c-.461.787-1.647.687-1.964-.165l-1.819-4.87a1.093 1.093 0 0 0-1.208-.686l-5.195.883c-.91.156-1.59-.804-1.128-1.591l6.231-10.622a16.372 16.372 0 0 0 6.71 4.027z"
/>
<path opacity=".302" fill="none" d="M-.015.012h48v48h-48v-48z" />
</svg>
);
};
export default TrendingNowIcon;

View File

@@ -0,0 +1,11 @@
export const convertThemeColor = (iconType) => {
const themeMode = "light";
const theme = {
light: {
normal: "#353535",
expanded: "#FEFEFE",
},
};
return theme[themeMode][iconType];
};

View File

@@ -5,6 +5,7 @@ const initialState = {
appStatus: { appStatus: {
showLoadingPanel: { show: true, type: "launching" }, showLoadingPanel: { show: true, type: "launching" },
isLoading: true, isLoading: true,
cursorVisible: false,
}, },
}; };

View File

@@ -0,0 +1,33 @@
import { createSlice } from "@reduxjs/toolkit";
import { fetchHomeMenu } from "./menuThunks";
const initialState = {
title: "",
items: {},
};
export const menuSlice = createSlice({
name: "menu",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchHomeMenu.pending, (state, action) => {})
.addCase(fetchHomeMenu.fulfilled, (state, action) => {
state.title = action.payload.gnb.map((titles) => {
return titles.menuNm;
});
state.items = action.payload.gnb.map((items) => {
return items;
});
})
.addCase(fetchHomeMenu.rejected, (state, action) => {});
},
});
export const selectorMenuId = (state) => state.menu.menuId;
export const selectorMenuTitle = (state) => state.menu.title;
export const selectorMenuItem = (state) => state.menu.items;
export default menuSlice.reducer;

View File

@@ -0,0 +1,15 @@
import { createAsyncThunk } from "@reduxjs/toolkit";
import { getHomeMenu } from "../../api/homeApi";
export const fetchHomeMenu = createAsyncThunk(
"menu/fetchHomeMenu",
async (_, { rejectWithValue }) => {
try {
const response = await getHomeMenu();
return response.data;
} catch (error) {
return rejectWithValue("unkown Error");
}
}
);

View File

@@ -2,8 +2,9 @@ import { configureStore } from "@reduxjs/toolkit";
import appDataReducer from "../features/appData/appDataSlice"; import appDataReducer from "../features/appData/appDataSlice";
import authReducer from "../features/auth/authSlice"; import authReducer from "../features/auth/authSlice";
import panelsReducer from "../features/panels/panelsSlice";
import commonReducer from "../features/common/commonSlice"; import commonReducer from "../features/common/commonSlice";
import menuReducer from "../features/menu/menuSlice";
import panelsReducer from "../features/panels/panelsSlice";
export const store = configureStore({ export const store = configureStore({
reducer: { reducer: {
@@ -11,5 +12,6 @@ export const store = configureStore({
auth: authReducer, auth: authReducer,
appData: appDataReducer, appData: appDataReducer,
common: commonReducer, common: commonReducer,
menu: menuReducer,
}, },
}); });

View File

@@ -55,3 +55,4 @@
/* Text Button */ /* Text Button */
@LargeTextBtnHeight: 78px; @LargeTextBtnHeight: 78px;
@SmallTextBtnHeight: 60px; @SmallTextBtnHeight: 60px;
@cateTabTwoFixWidth: 240px;