diff --git a/src/App.css b/src/App.css index dcf04ec..c717171 100644 --- a/src/App.css +++ b/src/App.css @@ -1,242 +1,440 @@ -@import url('https://fonts.googleapis.com/css2?family=Italiana&family=Lato:wght@100;300;400;700;900&family=Roboto:wght@100;300;400;500;700;900&display=swap'); -@import url('https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css'); -@import url('https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css'); - - - -*{margin: 0px; padding: 0px; box-sizing: border-box;} -body{font-family: 'Lato', sans-serif; font-size: 22px;} -#root{zoom: 65%;} -.container-fluid{padding: 0px 45px;} - -.no-click{pointer-events: none !important;} - -.transition{transition: all 0.3s ease-in-out;} -.cursor{cursor: pointer;} -.btn{border-radius: 8px !important;} -.btn-border{border: 1px solid rgba(0,0,0,0.1) !important; padding: 10px 25px !important; border-radius: 5px !important; color: #000 !important;} -.btn-border svg{opacity: 0.5;} -.btn-border:hover{border: 1px solid #3bb77e !important; background: #3bb77e !important; color: #fff !important;} -.btn-border:hover svg{opacity: 1 !important;} -.btn-g a{color: #fff !important; text-decoration: none !important;} -.btn-g{background: #3bb77e !important; padding: 10px 25px !important; border-radius: 5px !important; color: #fff !important; text-transform: capitalize !important; font-size: 18px !important;} -.btn-g:hover{background: #FDC040 !important;} -.btn-lg{font-size: 24px !important; padding: 10px 25px !important;} -.bg-g,.bg-success{background: #3bb77e !important;} -.text-g{color: #3bb77e;} -.text-org{color: #FDC040 !important;} -.text-light{color: #8b8b8b !important;} -p{color: #7E7E7E;} - -.hd{font-size: 38px; font-weight: 600; margin-bottom: 25px;} +@import url("https://fonts.googleapis.com/css2?family=Italiana&family=Lato:wght@100;300;400;700;900&family=Roboto:wght@100;300;400;500;700;900&display=swap"); +@import url("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css"); +@import url("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css"); + +* { + margin: 0px; + padding: 0px; + box-sizing: border-box; +} +body { + font-family: "Lato", sans-serif; + font-size: 22px; +} +#root { + zoom: 65%; +} +.container-fluid { + padding: 0px 45px; +} + +.no-click { + pointer-events: none !important; +} + +.transition { + transition: all 0.3s ease-in-out; +} +.cursor { + cursor: pointer; +} +.btn { + border-radius: 8px !important; +} +.btn-border { + border: 1px solid rgba(0, 0, 0, 0.1) !important; + padding: 10px 25px !important; + border-radius: 5px !important; + color: #000 !important; +} + +.btn-borderWishlistAlreadyAdded { + padding: 10px 25px !important; + border-radius: 5px !important; + color: #fff !important; + border: 1px solid #3bb77e !important; + background: #3bb77e !important; +} + +.btn-border svg { + opacity: 0.5; +} +/* .btn-border:hover { + border: 1px solid #3bb77e !important; + background: #3bb77e !important; + color: #fff !important; +} */ +.btn-border:hover svg { + opacity: 1 !important; +} +.btn-g a { + color: #fff !important; + text-decoration: none !important; +} +.btn-g { + background: #3bb77e !important; + padding: 10px 25px !important; + border-radius: 5px !important; + color: #fff !important; + text-transform: capitalize !important; + font-size: 18px !important; +} +.btn-g:hover { + background: #fdc040 !important; +} +.btn-lg { + font-size: 24px !important; + padding: 10px 25px !important; +} +.bg-g, +.bg-success { + background: #3bb77e !important; +} +.text-g { + color: #3bb77e; +} +.text-org { + color: #fdc040 !important; +} +.text-light { + color: #8b8b8b !important; +} +p { + color: #7e7e7e; +} + +.hd { + font-size: 38px; + font-weight: 600; + margin-bottom: 25px; +} /* START TOOLTIP STYLES */ [tooltip] { - position: relative; /* opinion 1 */ - } - - /* Applies to all tooltips */ - [tooltip]::before, - [tooltip]::after { - text-transform: none; /* opinion 2 */ - font-size: 16px; /* opinion 3 */ - line-height: 1; - user-select: none; - pointer-events: none; - position: absolute; - display: none; - opacity: 0; - } - [tooltip]::before { - content: ''; - border: 5px solid transparent; /* opinion 4 */ - z-index: 1001; /* absurdity 1 */ - } - [tooltip]::after { - content: attr(tooltip); /* magic! */ - - /* most of the rest of this is opinion */ - font-family: Helvetica, sans-serif; - text-align: center; - - /* + position: relative; /* opinion 1 */ +} + +/* Applies to all tooltips */ +[tooltip]::before, +[tooltip]::after { + text-transform: none; /* opinion 2 */ + font-size: 16px; /* opinion 3 */ + line-height: 1; + user-select: none; + pointer-events: none; + position: absolute; + display: none; + opacity: 0; +} +[tooltip]::before { + content: ""; + border: 5px solid transparent; /* opinion 4 */ + z-index: 1001; /* absurdity 1 */ +} +[tooltip]::after { + content: attr(tooltip); /* magic! */ + + /* most of the rest of this is opinion */ + font-family: Helvetica, sans-serif; + text-align: center; + + /* Let the content set the size of the tooltips but this will also keep them from being obnoxious */ - min-width: 3em; - max-width: 21em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - padding: 1ch 1.5ch; - border-radius: .3ch; - box-shadow: 0 1em 2em -.5em rgba(0, 0, 0, 0.35); - background: #3bb77e; - color: #fff; - z-index: 1000; /* absurdity 2 */ - } - - /* Make the tooltips respond to hover */ - [tooltip]:hover::before, - [tooltip]:hover::after { - display: block; - } - - /* don't show empty tooltips */ - [tooltip='']::before, - [tooltip='']::after { - display: none !important; - } - - /* FLOW: UP */ - [tooltip]:not([flow])::before, - [tooltip][flow^="up"]::before { - bottom: 100%; - border-bottom-width: 0; - border-top-color: #3bb77e; - } - [tooltip]:not([flow])::after, - [tooltip][flow^="up"]::after { - bottom: calc(100% + 5px); - } - [tooltip]:not([flow])::before, - [tooltip]:not([flow])::after, - [tooltip][flow^="up"]::before, - [tooltip][flow^="up"]::after { - left: 50%; - transform: translate(-50%, -.5em); - } - - /* FLOW: DOWN */ - [tooltip][flow^="down"]::before { - top: 100%; - border-top-width: 0; - border-bottom-color: #333; - } - [tooltip][flow^="down"]::after { - top: calc(100% + 5px); - } - [tooltip][flow^="down"]::before, - [tooltip][flow^="down"]::after { - left: 50%; - transform: translate(-50%, .5em); - } - - /* FLOW: LEFT */ - [tooltip][flow^="left"]::before { - top: 50%; - border-right-width: 0; - border-left-color: #333; - left: calc(0em - 5px); - transform: translate(-.5em, -50%); - } - [tooltip][flow^="left"]::after { - top: 50%; - right: calc(100% + 5px); - transform: translate(-.5em, -50%); - } - - /* FLOW: RIGHT */ - [tooltip][flow^="right"]::before { - top: 50%; - border-left-width: 0; - border-right-color: #3bb77e; - right: calc(0em - 5px); - transform: translate(.5em, -50%); - } - [tooltip][flow^="right"]::after { - top: 50%; - left: calc(100% + 5px); - transform: translate(.5em, -50%); - } - - /* KEYFRAMES */ - @keyframes tooltips-vert { - to { - opacity: .9; - transform: translate(-50%, 0); - } - } - - @keyframes tooltips-horz { - to { - opacity: .9; - transform: translate(0, -50%); - } - } - - /* FX All The Things */ - [tooltip]:not([flow]):hover::before, - [tooltip]:not([flow]):hover::after, - [tooltip][flow^="up"]:hover::before, - [tooltip][flow^="up"]:hover::after, - [tooltip][flow^="down"]:hover::before, - [tooltip][flow^="down"]:hover::after { - animation: tooltips-vert 300ms ease-out forwards; - } - - [tooltip][flow^="left"]:hover::before, - [tooltip][flow^="left"]:hover::after, - [tooltip][flow^="right"]:hover::before, - [tooltip][flow^="right"]:hover::after { - animation: tooltips-horz 300ms ease-out forwards; + min-width: 3em; + max-width: 21em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 1ch 1.5ch; + border-radius: 0.3ch; + box-shadow: 0 1em 2em -0.5em rgba(0, 0, 0, 0.35); + background: #3bb77e; + color: #fff; + z-index: 1000; /* absurdity 2 */ +} + +/* Make the tooltips respond to hover */ +[tooltip]:hover::before, +[tooltip]:hover::after { + display: block; +} + +/* don't show empty tooltips */ +[tooltip=""]::before, +[tooltip=""]::after { + display: none !important; +} + +/* FLOW: UP */ +[tooltip]:not([flow])::before, +[tooltip][flow^="up"]::before { + bottom: 100%; + border-bottom-width: 0; + border-top-color: #3bb77e; +} +[tooltip]:not([flow])::after, +[tooltip][flow^="up"]::after { + bottom: calc(100% + 5px); +} +[tooltip]:not([flow])::before, +[tooltip]:not([flow])::after, +[tooltip][flow^="up"]::before, +[tooltip][flow^="up"]::after { + left: 50%; + transform: translate(-50%, -0.5em); +} + +/* FLOW: DOWN */ +[tooltip][flow^="down"]::before { + top: 100%; + border-top-width: 0; + border-bottom-color: #333; +} +[tooltip][flow^="down"]::after { + top: calc(100% + 5px); +} +[tooltip][flow^="down"]::before, +[tooltip][flow^="down"]::after { + left: 50%; + transform: translate(-50%, 0.5em); +} + +/* FLOW: LEFT */ +[tooltip][flow^="left"]::before { + top: 50%; + border-right-width: 0; + border-left-color: #333; + left: calc(0em - 5px); + transform: translate(-0.5em, -50%); +} +[tooltip][flow^="left"]::after { + top: 50%; + right: calc(100% + 5px); + transform: translate(-0.5em, -50%); +} + +/* FLOW: RIGHT */ +[tooltip][flow^="right"]::before { + top: 50%; + border-left-width: 0; + border-right-color: #3bb77e; + right: calc(0em - 5px); + transform: translate(0.5em, -50%); +} +[tooltip][flow^="right"]::after { + top: 50%; + left: calc(100% + 5px); + transform: translate(0.5em, -50%); +} + +/* KEYFRAMES */ +@keyframes tooltips-vert { + to { + opacity: 0.9; + transform: translate(-50%, 0); } - +} -.price{font-size: 25px; margin-right: 20px;} -.oldPrice{font-size: 20px; opacity: 0.6; color: #000; text-decoration: line-through;} +@keyframes tooltips-horz { + to { + opacity: 0.9; + transform: translate(0, -50%); + } +} +/* FX All The Things */ +[tooltip]:not([flow]):hover::before, +[tooltip]:not([flow]):hover::after, +[tooltip][flow^="up"]:hover::before, +[tooltip][flow^="up"]:hover::after, +[tooltip][flow^="down"]:hover::before, +[tooltip][flow^="down"]:hover::after { + animation: tooltips-vert 300ms ease-out forwards; +} -.listingPage{width: 100%; height: auto; padding: 45px 0px;} +[tooltip][flow^="left"]:hover::before, +[tooltip][flow^="left"]:hover::after, +[tooltip][flow^="right"]:hover::before, +[tooltip][flow^="right"]:hover::after { + animation: tooltips-horz 300ms ease-out forwards; +} -.breadcrumb{width: 100%; height: auto; padding: 45px 45px; background: #d8f1e5; border-radius: 20px; margin-bottom: 30px;} -.breadcrumb h1{color: #000; opacity: 0.8; font-size: 50px; font-weight: bold;} -.breadcrumb ul li{margin-right: 20px !important;} -.breadcrumb ul li a{color: #000; text-decoration: none; font-size: 22px;} +.price { + font-size: 25px; + margin-right: 20px; +} +.oldPrice { + font-size: 20px; + opacity: 0.6; + color: #000; + text-decoration: line-through; +} +.listingPage { + width: 100%; + height: auto; + padding: 45px 0px; +} -.sidebarWrapper{max-width: 20%; flex: 0 0 20%;} -.rightContent{max-width: 80%; flex: 0 0 80%;} -.sidebarWrapper h3{font-size: 30px; font-weight: 600; position: relative; padding-bottom: 20px; margin-bottom: 30px;} -.sidebarWrapper h3:after{content: ''; width: 100%; height: 3px; background: #f0f0f0; position: absolute; bottom: 0px; -left: 0px;} +.breadcrumb { + width: 100%; + height: auto; + padding: 45px 45px; + background: #d8f1e5; + border-radius: 20px; + margin-bottom: 30px; +} +.breadcrumb h1 { + color: #000; + opacity: 0.8; + font-size: 50px; + font-weight: bold; +} +.breadcrumb ul li { + margin-right: 20px !important; +} +.breadcrumb ul li a { + color: #000; + text-decoration: none; + font-size: 22px; +} -.sidebarWrapper h3:before{content: ''; width: 20%; height: 3px; background: #b0e5c2; position: absolute; bottom: 0px; left: 0px; z-index: 10;} +.sidebarWrapper { + max-width: 20%; + flex: 0 0 20%; +} +.rightContent { + max-width: 80%; + flex: 0 0 80%; +} +.sidebarWrapper h3 { + font-size: 30px; + font-weight: 600; + position: relative; + padding-bottom: 20px; + margin-bottom: 30px; +} +.sidebarWrapper h3:after { + content: ""; + width: 100%; + height: 3px; + background: #f0f0f0; + position: absolute; + bottom: 0px; + left: 0px; +} -.sidebarWrapper .sidebar{position: sticky; top: 110px;} +.sidebarWrapper h3:before { + content: ""; + width: 20%; + height: 3px; + background: #b0e5c2; + position: absolute; + bottom: 0px; + left: 0px; + z-index: 10; +} -.sidebarWrapper .sidebar .card{padding: 25px; border-radius: 10px !important; margin-bottom: 40px;} +.sidebarWrapper .sidebar { + position: sticky; + top: 110px; +} -.sidebarWrapper .sidebar .card .catList a{text-decoration: none;} -.sidebarWrapper .sidebar .card .catList .catItem{ padding: 10px; border: 1px solid rgba(0,0,0,0.050); cursor: pointer; margin: 10px 0px; border-radius: 4px; transition:all 0.3s ease-in-out} -.sidebarWrapper .sidebar .card .catList .catItem h4{color: #000 !important; font-size: 18px; } -.sidebarWrapper .sidebar .card .catList .catItem .rounded-circle{background: #BCE3C9; width: 40px; height: 40px;} -.sidebarWrapper .sidebar .card .catList .catItem:hover{border: 1px solid rgba(0,0,0,0.2);} +.sidebarWrapper .sidebar .card { + padding: 25px; + border-radius: 10px !important; + margin-bottom: 40px; +} -.priceRange span{font-size: 20px;} +.sidebarWrapper .sidebar .card .catList a { + text-decoration: none; +} +.sidebarWrapper .sidebar .card .catList .catItem { + padding: 10px; + border: 1px solid rgba(0, 0, 0, 0.05); + cursor: pointer; + margin: 10px 0px; + border-radius: 4px; + transition: all 0.3s ease-in-out; +} +.sidebarWrapper .sidebar .card .catList .catItem h4 { + color: #000 !important; + font-size: 18px; +} +.sidebarWrapper .sidebar .card .catList .catItem .rounded-circle { + background: #bce3c9; + width: 40px; + height: 40px; +} +.sidebarWrapper .sidebar .card .catList .catItem:hover { + border: 1px solid rgba(0, 0, 0, 0.2); +} -.filters{padding: 25px 0px;} -.filters h5{font-weight: 600; margin-bottom: 10px;} -.filters ul{max-height: 200px; overflow-y: scroll; margin-left: -10px;} -.filters ul::-webkit-scrollbar{width: 10px !important;} -.filters ul::-webkit-scrollbar-thumb{ background: #ccc !important;} -.filters ul li{width: 100%; margin-bottom: 0px; list-style: none;} +.priceRange span { + font-size: 20px; +} -.filterWrapper{display: none !important;} -.sidebarWrapper .sidebar .btn{width: 100% !important;} +.filters { + padding: 25px 0px; +} +.filters h5 { + font-weight: 600; + margin-bottom: 10px; +} +.filters ul { + max-height: 200px; + overflow-y: scroll; + margin-left: -10px; +} +.filters ul::-webkit-scrollbar { + width: 10px !important; +} +.filters ul::-webkit-scrollbar-thumb { + background: #ccc !important; +} +.filters ul li { + width: 100%; + margin-bottom: 0px; + list-style: none; +} +.filterWrapper { + display: none !important; +} +.sidebarWrapper .sidebar .btn { + width: 100% !important; +} -.rightContent .topStrip{padding: 0px 25px;} -.rightContent .topStrip p{font-size: 20px;} +.rightContent .topStrip { + padding: 0px 25px; +} +.rightContent .topStrip p { + font-size: 20px; +} -.rightContent .topStrip .tab_{width: 200px;} -.rightContent .topStrip .tab_ .btn_{background: none !important; border: 1px solid rgba(0,0,0,0.1) !important; padding: 10px 20px !important; text-transform: capitalize !important; color: rgba(0,0,0,0.7) !important; border-radius: 10px !important; font-size: 16px !important; width: 100% !important; justify-content: flex-start !important;} -.rightContent .topStrip .tab_ .btn_ svg{opacity: 0.5;} -.rightContent .topStrip .tab_ .dropdownMenu{top: 100% !important;} +.rightContent .topStrip .tab_ { + width: 200px; +} +.rightContent .topStrip .tab_ .btn_ { + background: none !important; + border: 1px solid rgba(0, 0, 0, 0.1) !important; + padding: 10px 20px !important; + text-transform: capitalize !important; + color: rgba(0, 0, 0, 0.7) !important; + border-radius: 10px !important; + font-size: 16px !important; + width: 100% !important; + justify-content: flex-start !important; +} +.rightContent .topStrip .tab_ .btn_ svg { + opacity: 0.5; +} +.rightContent .topStrip .tab_ .dropdownMenu { + top: 100% !important; +} -.breadcrumbWrapper{width: 100%; height: auto; padding: 30px 0px; - border-bottom:1px solid rgba(0,0,0,0.1) !important ;} -.breadcrumb2{background: none !important; padding: 0px !important;} +.breadcrumbWrapper { + width: 100%; + height: auto; + padding: 30px 0px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important ; +} +.breadcrumb2 { + background: none !important; + padding: 0px !important; +} ul.breadcrumb { padding: 10px 16px; list-style: none; @@ -246,7 +444,7 @@ ul.breadcrumb li { display: inline; font-size: 18px; } -ul.breadcrumb li+li:before { +ul.breadcrumb li + li:before { padding: 8px; color: black; content: "/\00a0"; @@ -260,92 +458,246 @@ ul.breadcrumb li a:hover { text-decoration: underline; } +.detailsContainer { + max-width: 85%; + margin: auto; + padding: 30px 0px; +} +.detailsPage .productInfo { + padding-left: 80px; +} +.detailsPage .productInfo h1 { + font-size: 55px; + font-weight: bold; + opacity: 0.8; +} +.detailsPage .productInfo .priceSec .priceLarge { + font-size: 70px; + font-weight: bold; +} +.detailsPage .productInfo .priceSec .text-org { + font-size: 20px; + font-weight: 600; +} +.detailsPage .productInfo .priceSec .text-light.oldPrice { + font-size: 30px; + font-weight: 600; +} - -.detailsContainer{max-width: 85%; margin: auto; padding: 30px 0px;} - -.detailsPage .productInfo{padding-left: 80px;} -.detailsPage .productInfo h1{font-size: 55px; font-weight: bold; opacity: 0.8;} - .detailsPage .productInfo .priceSec .priceLarge{font-size: 70px; font-weight: bold;} - .detailsPage .productInfo .priceSec .text-org{font-size: 20px; font-weight: 600;} - .detailsPage .productInfo .priceSec .text-light.oldPrice{font-size: 30px; font-weight: 600;} - - .productZoom{ width: 100%; height: auto; border: 1px solid rgba(0,0,0,0.1); padding: 0px; overflow: hidden; border-radius: 15px;} - .zoomSliderBig{width: 100% !important;} - - - .zoomSlider{padding-top: 30px;} - .zoomSlider .slick-slide { padding-right: 20px !important;} - .zoomSlider *{outline: none !important;} - .zoomSlider .item{border: 2px solid transparent !important; overflow: hidden; border-radius: 15px; cursor: pointer;} - .zoomSlider .slick-current .item{border: 2px solid #3bb77e !important; } - .zoomSlider .slick-arrow{top: 55% !important; zoom: 80% !important;} - .zoomSlider .slick-arrow.slick-next{right: -2% !important;} - .zoomSlider .slick-arrow.slick-prev{left: -5% !important;} - +.productZoom { + width: 100%; + height: auto; + border: 1px solid rgba(0, 0, 0, 0.1); + padding: 0px; + overflow: hidden; + border-radius: 15px; +} +.zoomSliderBig { + width: 100% !important; +} - .productSize{width: 100%; height: auto; padding: 25px 0px;} - .productSize ul li{margin-right: 10px !important;} - .productSize ul li a{display: flex; align-items: center; justify-content: center; padding:10px 20px !important; border: 1px solid rgba(0,0,0,0.1); border-radius: 5px !important; cursor: pointer; text-decoration: none !important; color: #000; font-size: 16px !important; transition: all 0.1s ease-in-out;} - - .productSize ul li a.active{background: #3bb77e !important; color: #fff !important;} +.zoomSlider { + padding-top: 30px; +} +.zoomSlider .slick-slide { + padding-right: 20px !important; +} +.zoomSlider * { + outline: none !important; +} +.zoomSlider .item { + border: 2px solid transparent !important; + overflow: hidden; + border-radius: 15px; + cursor: pointer; +} +.zoomSlider .slick-current .item { + border: 2px solid #3bb77e !important; +} +.zoomSlider .slick-arrow { + top: 55% !important; + zoom: 80% !important; +} +.zoomSlider .slick-arrow.slick-next { + right: -2% !important; +} +.zoomSlider .slick-arrow.slick-prev { + left: -5% !important; +} - input::-webkit-outer-spin-button, - input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; - } - - /* Firefox */ - input[type=number] { - -moz-appearance: textfield; - } +.productSize { + width: 100%; + height: auto; + padding: 25px 0px; +} +.productSize ul li { + margin-right: 10px !important; +} +.productSize ul li a { + display: flex; + align-items: center; + justify-content: center; + padding: 10px 20px !important; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 5px !important; + cursor: pointer; + text-decoration: none !important; + color: #000; + font-size: 16px !important; + transition: all 0.1s ease-in-out; +} +.productSize ul li a.active { + background: #3bb77e !important; + color: #fff !important; +} - .addCartSection{width: 100%; height: auto;} - .addCartSection .counterSec{width: 100px; height: 60px; border-radius: 10px; border: 1px solid #3bb77e !important; overflow: hidden; padding: 10px;} - .addCartSection .counterSec input{width:60px; height: 40px; padding: 5px; border: 0px; outline: none !important; text-align: center; pointer-events: none;} +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} - .addCartSection .counterSec{position: relative;} - .addCartSection .counterSec .arrow{position: absolute; cursor: pointer; opacity: 0.6;} - .addCartSection .counterSec .arrow.plus{top: -5px; right: 10px;} - .addCartSection .counterSec .arrow.minus{bottom: -5px; right: 10px;} +/* Firefox */ +input[type="number"] { + -moz-appearance: textfield; +} - .addtocartbtn svg{font-size: 28px !important;} +.addCartSection { + width: 100%; + height: auto; +} +.addCartSection .counterSec { + width: 100px; + height: 60px; + border-radius: 10px; + border: 1px solid #3bb77e !important; + overflow: hidden; + padding: 10px; +} +.addCartSection .counterSec input { + width: 60px; + height: 40px; + padding: 5px; + border: 0px; + outline: none !important; + text-align: center; + pointer-events: none; +} - .addCartSection button{height: 60px; min-width: inherit !important;} - .addCartSection button svg{font-size: 30px !important;} - +.addCartSection .counterSec { + position: relative; +} +.addCartSection .counterSec .arrow { + position: absolute; + cursor: pointer; + opacity: 0.6; +} +.addCartSection .counterSec .arrow.plus { + top: -5px; + right: 10px; +} +.addCartSection .counterSec .arrow.minus { + bottom: -5px; + right: 10px; +} -.card{border-radius: 10px !important;} +.addtocartbtn svg { + font-size: 28px !important; +} - .detailsPageTabs{border-radius: 25px !important;} +.addCartSection button { + height: 60px; + min-width: inherit !important; +} +.addCartSection button svg { + font-size: 30px !important; +} - .customTabs ul li{margin-right: 30px !important;} - .customTabs ul li button{padding: 10px 25px !important; border: 1px solid rgba(0,0,0,0.2) !important; font-size: 20px !important; text-transform: capitalize !important; border-radius: 30px !important; color: #000 !important;} +.card { + border-radius: 10px !important; +} - .customTabs ul li button.active{color: #3bb77e !important;} +.detailsPageTabs { + border-radius: 25px !important; +} - .reviewsCard{margin-bottom: 25px !important;} +.customTabs ul li { + margin-right: 30px !important; +} +.customTabs ul li button { + padding: 10px 25px !important; + border: 1px solid rgba(0, 0, 0, 0.2) !important; + font-size: 20px !important; + text-transform: capitalize !important; + border-radius: 30px !important; + color: #000 !important; +} - .reviewsCard .image{width: 100px;} - .reviewsCard .rounded-circle{display: flex; align-items: center; justify-content: center; overflow: hidden; width: 100px; height:100px;} - .reviewsCard .rounded-circle img{width: 100%; height: 100%; object-fit: cover;} - .reviewsCard .info{width: 85%;} +.customTabs ul li button.active { + color: #3bb77e !important; +} +.reviewsCard { + margin-bottom: 25px !important; +} - .reviewForm .form-group{margin-bottom: 25px;} - .reviewForm .form-group .form-control{height: 80px; font-size: 20px; border-radius: 7px !important; padding-left: 20px;} - .reviewForm .form-group textarea.form-control{height: 200px; padding-top: 25px;} +.reviewsCard .image { + width: 100px; +} +.reviewsCard .rounded-circle { + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + width: 100px; + height: 100px; +} +.reviewsCard .rounded-circle img { + width: 100%; + height: 100%; + object-fit: cover; +} +.reviewsCard .info { + width: 85%; +} - .progressBarBox{margin-bottom: 10px;} - .progress-bar{font-size: 16px;} +.reviewForm .form-group { + margin-bottom: 25px; +} +.reviewForm .form-group .form-control { + height: 80px; + font-size: 20px; + border-radius: 7px !important; + padding-left: 20px; +} +.reviewForm .form-group textarea.form-control { + height: 200px; + padding-top: 25px; +} +.progressBarBox { + margin-bottom: 10px; +} +.progress-bar { + font-size: 16px; +} - .relatedProducts .item { - padding: 15px 5px; - padding-right: 25px !important; +.relatedProducts .item { + padding: 15px 5px; + padding-right: 25px !important; } -.loader{position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 10000; background: #fff; display: flex; align-items: center; justify-content: center;} \ No newline at end of file +.loader { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 10000; + background: #fff; + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/App.js b/src/App.js index fb2b2a0..1760c5c 100644 --- a/src/App.js +++ b/src/App.js @@ -21,6 +21,7 @@ import NotFound from "./pages/NotFound"; import DetailsPage from "./pages/Details"; import axios from "axios"; import Cart from "./pages/cart"; +import Wishlist from "./pages/wishList"; import SignIn from "./pages/SignIn"; import SignUp from "./pages/SignUp"; import Loader from "./assets/images/loading.gif"; @@ -38,6 +39,7 @@ function App() { const [productData, setProductData] = useState([]); const [cartItems, setCartItems] = useState([]); + const [wishlistItems, setWishlistItems] = useState([]); const [isLoading, setIsloading] = useState(true); @@ -50,17 +52,18 @@ function App() { const [isLogin, setIsLogin] = useState(); const [isOpenFilters, setIsopenFilters] = useState(false); const [data, setData] = useState([]); - const [cartCount,setCartCount] = useState(0) + const [cartCount, setCartCount] = useState(0); + const [wishlistCount, setWishlistCount] = useState(0); - - useEffect(()=>{ - fetchCartProducts() - },[isLogin]) + useEffect(() => { + fetchCartProducts(); + fetchWishlistProducts(); + }, [isLogin]); const fetchCartProducts = async () => { try { - const cartRef = doc(db, 'carts', localStorage.getItem("uid")); - const productsCollectionRef = collection(cartRef, 'products'); + const cartRef = doc(db, "carts", localStorage.getItem("uid")); + const productsCollectionRef = collection(cartRef, "products"); const querySnapshot = await getDocs(productsCollectionRef); const products = []; querySnapshot.forEach((doc) => { @@ -69,10 +72,28 @@ function App() { setCartItems(products); setCartCount(products.length); // Set the product count } catch (error) { - console.error('Error fetching cart products:', error); + console.error("Error fetching cart products:", error); } }; + const fetchWishlistProducts = async () => { + console.log("fetchWishlistProducts"); + try { + const wishlistRef = doc(db, "wishlists", localStorage.getItem("uid")); + const productsCollectionRef = collection(wishlistRef, "products"); + const querySnapshot = await getDocs(productsCollectionRef); + console.log(querySnapshot); + const products = []; + querySnapshot.forEach((doc) => { + products.push({ id: doc.id, ...doc.data() }); + }); + console.log(products); + setWishlistItems(products); + setWishlistCount(products.length); // Set the product count + } catch (error) { + console.error("Error fetching wishlist products:", error); + } + }; useEffect(() => { const fetchData = async () => { @@ -210,7 +231,10 @@ function App() { setIsopenNavigation, cartCount, setCartCount, - fetchCartProducts + wishlistCount, + setWishlistCount, + fetchCartProducts, + fetchWishlistProducts, }; return data && data.productData ? ( @@ -247,6 +271,7 @@ function App() { element={} /> } /> + } /> {/* sign in , signup Protection */} {isLogin === null && ( diff --git a/src/components/header/header.js b/src/components/header/header.js index 013f005..05e58de 100644 --- a/src/components/header/header.js +++ b/src/components/header/header.js @@ -38,10 +38,12 @@ const Header = (props) => { const [windowWidth, setWindowWidth] = useState(window.innerWidth); const [isopenSearch, setOpenSearch] = useState(false); const [isOpenNav, setIsOpenNav] = useState(false); - const {cartCount, setCartCount} = useContext(MyContext); + const { cartCount, setCartCount } = useContext(MyContext); + const { wishlistCount, setWishlistCount } = useContext(MyContext); + const headerRef = useRef(); const searchInput = useRef(); - const [profile,setProfile] = useState("") + const [profile, setProfile] = useState(""); const context = useContext(MyContext); const history = useNavigate(); @@ -67,9 +69,9 @@ const Header = (props) => { getCountry("https://countriesnow.space/api/v0.1/countries/"); }, []); - useEffect(()=>{ - setProfile(localStorage.getItem("userImage")) - },[context.isLogin]) + useEffect(() => { + setProfile(localStorage.getItem("userImage")); + }, [context.isLogin]); const getCountry = async (url) => { try { await axios.get(url).then((res) => { @@ -101,7 +103,7 @@ const Header = (props) => { const signOut = () => { context.signOut(); - localStorage.setItem("userImage","") + localStorage.setItem("userImage", ""); history("/"); }; @@ -162,7 +164,29 @@ const Header = (props) => {
setisOpenAccDropDown(!isOpenAccDropDown)} > - {profile!=""?:} + {profile != "" ? ( + + ) : ( + + )}
)} @@ -223,39 +247,44 @@ const Header = (props) => {
  • - + {" "} - - - 3 - - Compare - + + + 3 + + Compare +
  • - + {" "} - - - 3 - - Wishlist - + + + {wishlistCount} + + Wishlist +
  • - + {" "} - {cartCount} + {cartCount} Cart -
  • @@ -264,8 +293,29 @@ const Header = (props) => { setisOpenDropDown(!isOpenDropDown)} > - - {profile!=""?:} + {profile != "" ? ( + + ) : ( + + )} {isOpenDropDown !== false && ( diff --git a/src/components/product/index.js b/src/components/product/index.js index 672866b..2b820f6 100644 --- a/src/components/product/index.js +++ b/src/components/product/index.js @@ -1,186 +1,216 @@ -import React, { useEffect, useState, useContext } from 'react'; -import './style.css'; -import Rating from '@mui/material/Rating'; -import { Button } from '@mui/material'; -import { Link } from 'react-router-dom'; -import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined'; -import FavoriteBorderOutlinedIcon from '@mui/icons-material/FavoriteBorderOutlined'; -import CompareArrowsOutlinedIcon from '@mui/icons-material/CompareArrowsOutlined'; -import RemoveRedEyeOutlinedIcon from '@mui/icons-material/RemoveRedEyeOutlined'; -import { getDatabase, ref, onValue, set, push, child, remove } from "firebase/database"; - -import { MyContext } from '../../App'; -import { db } from '../../firebase'; -import { doc, setDoc } from 'firebase/firestore'; - +import React, { useEffect, useState, useContext } from "react"; +import "./style.css"; +import Rating from "@mui/material/Rating"; +import { Button } from "@mui/material"; +import { Link } from "react-router-dom"; +import ShoppingCartOutlinedIcon from "@mui/icons-material/ShoppingCartOutlined"; +import FavoriteBorderOutlinedIcon from "@mui/icons-material/FavoriteBorderOutlined"; +import CompareArrowsOutlinedIcon from "@mui/icons-material/CompareArrowsOutlined"; +import RemoveRedEyeOutlinedIcon from "@mui/icons-material/RemoveRedEyeOutlined"; +import { + getDatabase, + ref, + onValue, + set, + push, + child, + remove, +} from "firebase/database"; + +import { MyContext } from "../../App"; +import { db } from "../../firebase"; +import { doc, setDoc } from "firebase/firestore"; const Product = (props) => { - - const [productData, setProductData] = useState(); - const [isAdded, setIsadded] = useState(false); - const [userLocation, setUserLocation] = useState(null); - const [loading, setLoading] = useState(true); - const [drivingDistance, setDrivingDistance] = useState(null); - const context = useContext(MyContext); - - useEffect(() => { - setProductData(props.item); - }, [props.item]) - - const setProductCat=()=>{ - sessionStorage.setItem('parentCat', productData.parentCatName); - sessionStorage.setItem('subCatName', productData.subCatName); + const [productData, setProductData] = useState(); + const [isAdded, setIsadded] = useState(false); + const [userLocation, setUserLocation] = useState(null); + const [loading, setLoading] = useState(true); + const [drivingDistance, setDrivingDistance] = useState(null); + const context = useContext(MyContext); + + useEffect(() => { + setProductData(props.item); + }, [props.item]); + + const setProductCat = () => { + sessionStorage.setItem("parentCat", productData.parentCatName); + sessionStorage.setItem("subCatName", productData.subCatName); + }; + ////console.log(productData); //printing1000 data + + useEffect(() => { + navigator.geolocation.getCurrentPosition( + (position) => { + // //console.log(position.coords.latitude, position.coords.longitude); + setUserLocation([position.coords.latitude, position.coords.longitude]); + }, + (error) => { + console.error("Error getting user location:", error); + } + ); + }, [context.isLogin]); + + // const getDrivingDistance = async (start, end) => { + // const response = await fetch(`https://router.project-osrm.org/route/v1/driving/${start.longitude},${start.latitude};${end.longitude},${end.latitude}`); + // const data = await response.json(); + // if (data.code === 'Ok') { + // const distance = data.routes[0].distance; // Distance in meters + // //console.log(distance) ; + // return distance; + // } else { + // throw new Error('Unable to calculate driving distance'); + // } + // }; + + const getDistance = (start, end) => { + const toRadians = (degrees) => (degrees * Math.PI) / 180; + + const earthRadiusKm = 6371; // Radius of the Earth in kilometers + const dLat = toRadians(end[0] - start[0]); + const dLon = toRadians(end[1] - start[1]); + + const lat1 = toRadians(start[0]); + const lat2 = toRadians(end[0]); + + const a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + const distance = earthRadiusKm * c; // Distance in kilometers + + return distance; // Convert distance to meters + }; + + const getDisplacement = (start, end) => { + const distance = getDistance(start, end); // Calculate the straight-line distance + return distance; + }; + + useEffect(() => { + if (userLocation && productData?.coordinates) { + const userCoords = userLocation; + const productCoords = productData.coordinates; + // taking the nearest integer value + const distance = Math.round(getDisplacement(userCoords, productCoords)); + setDrivingDistance(distance); + setLoading(false); } - ////console.log(productData); //printing1000 data - - - useEffect(() => { - navigator.geolocation.getCurrentPosition( - (position) => { - // //console.log(position.coords.latitude, position.coords.longitude); - setUserLocation([position.coords.latitude, position.coords.longitude]); - }, - (error) => { - console.error("Error getting user location:", error); - } - ); - }, [context.isLogin]); - - // const getDrivingDistance = async (start, end) => { - // const response = await fetch(`https://router.project-osrm.org/route/v1/driving/${start.longitude},${start.latitude};${end.longitude},${end.latitude}`); - // const data = await response.json(); - // if (data.code === 'Ok') { - // const distance = data.routes[0].distance; // Distance in meters - // //console.log(distance) ; - // return distance; - // } else { - // throw new Error('Unable to calculate driving distance'); - // } - // }; - - const getDistance = (start, end) => { - const toRadians = (degrees) => (degrees * Math.PI) / 180; - - const earthRadiusKm = 6371; // Radius of the Earth in kilometers - const dLat = toRadians(end[0] - start[0]); - const dLon = toRadians(end[1] - start[1]); - - const lat1 = toRadians(start[0]); - const lat2 = toRadians(end[0]); - - const a = - Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); - const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - const distance = earthRadiusKm * c; // Distance in kilometers - - return distance // Convert distance to meters - }; - - const getDisplacement = (start, end) => { - const distance = getDistance(start, end); // Calculate the straight-line distance - return distance; - }; - - useEffect(() => { - if (userLocation && productData?.coordinates) { - const userCoords =userLocation; - const productCoords = productData.coordinates; - // taking the nearest integer value - const distance = Math.round(getDisplacement(userCoords, productCoords)); - setDrivingDistance(distance); - setLoading(false); - } - }, [userLocation, productData]); - - const addToCart = async (item) => { - try { - const user=localStorage.getItem('uid') - const cartRef = doc(db, 'carts', user); - const productRef = doc(cartRef, 'products', `${item.id}`); - await setDoc(productRef, {...item, quantity: 1}) - setIsadded(true) - context.fetchCartProducts(); - } catch (error) { - console.error('Error adding item to cart:', error); - } - }; - if(loading){ - return
    Loading...
    + }, [userLocation, productData]); + + const addToCart = async (item) => { + try { + const user = localStorage.getItem("uid"); + const cartRef = doc(db, "carts", user); + const productRef = doc(cartRef, "products", `${item.id}`); + await setDoc(productRef, { ...item, quantity: 1 }); + setIsadded(true); + context.fetchCartProducts(); + } catch (error) { + console.error("Error adding item to cart:", error); } - - - return ( -
    - { - props.tag !== null && props.tag !== undefined && - {props.tag} - } - - { - productData !== undefined && - <> - -
    -
    - -
    - -
    - -
    -
    - - - -
    - {productData.brand} -

    {productData.productName.substr(0,50)+'...'}

    - - By {productData.brand} - Distance: {drivingDistance} km -
    -
    - - Rs {productData.price} Rs {productData.oldPrice} -
    -
    - - - -
    - - - } - - - - - - -
    - ) -} - -export default Product; \ No newline at end of file + }; + + const addToWishlist = async (item) => { + console.log("addToWishlist"); + try { + const user = localStorage.getItem("uid"); + const wishlistRef = doc(db, "wishlists", user); + const productRef = doc(wishlistRef, "products", `${item.id}`); + await setDoc(productRef, { ...item, quantity: 1 }); + setIsadded(true); + context.fetchWishlistProducts(); + } catch (error) { + console.error("Error adding item to wishlist:", error); + } + }; + + if (loading) { + return
    Loading...
    ; + } + + return ( +
    + {props.tag !== null && props.tag !== undefined && ( + {props.tag} + )} + + {productData !== undefined && ( + <> + +
    +
    + +
    + +
    + +
    +
    + + +
    + {productData.brand} +

    + {productData.productName.substr(0, 50) + "..."} +

    + + + By {productData.brand} + + + Distance: {drivingDistance} km + +
    +
    + + Rs {productData.price} + {" "} + + Rs {productData.oldPrice} + +
    +
    + + +
    + + )} +
    + ); +}; + +export default Product; diff --git a/src/components/quantityBox/index.js b/src/components/quantityBox/index.js index 17beede..7183768 100644 --- a/src/components/quantityBox/index.js +++ b/src/components/quantityBox/index.js @@ -1,96 +1,92 @@ +import React, { useState, useEffect } from "react"; -import React, { useState, useEffect } from 'react'; - -import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; -import { db } from '../../firebase'; -import { doc, updateDoc } from 'firebase/firestore'; - - +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import { db } from "../../firebase"; +import { doc, updateDoc } from "firebase/firestore"; const QuantityBox = (props) => { - const [inputValue, setinputValue] = useState(props.quantity); - const [cartItems, setcartItems] = useState([]); - const uid = localStorage.getItem("uid"); - useEffect(() => { - setcartItems(props.cartItems); - //setinputValue(props.item.quantity) - }, [props.cartItems]) - - - - const updateCart=(items)=>{ - props.updateCart(items) + const [inputValue, setinputValue] = useState(props.quantity); + const [inputItems, setInputItems] = useState([]); + const uid = localStorage.getItem("uid"); + useEffect(() => { + setInputItems(props.inputItems); + //setinputValue(props.item.quantity) + }, [props.inputItems]); + + const updateInfo = (items) => { + props.updateInfo(items); + }; + const updateDb = async (uid, itemId, newData) => { + const itemRef = doc(db, props.name, uid, "products", itemId); + + try { + await updateDoc(itemRef, newData); + console.log("item updated successfully."); + } catch (error) { + console.error("Error updating item:", error); } - const updateDb = async (uid, cartItemId, newData) => { - const cartItemRef = doc(db, 'carts', uid, 'products', cartItemId); - - try { - await updateDoc(cartItemRef, newData); - console.log('Cart item updated successfully.'); - } catch (error) { - console.error('Error updating cart item:', error); - } - }; - - - // const plus = () => { - // setinputValue(inputValue + 1) - // } - - // const minus = () => { - // if (inputValue !== 1) { - // setinputValue(inputValue - 1) - // } - // } - - - - return ( -
    -
    - - { - setinputValue(inputValue + 1); - const _cart = props.cartItems?.map((cartItem, key) => { - return key === parseInt(props.index) ? { ...cartItem, quantity: inputValue+1 } : {...cartItem} - }); - await updateDb(uid,`${props?.item?.id}`,_cart[props?.index]) - updateCart(_cart); - setcartItems(_cart); - - } - } - - > - - - { - if (inputValue !== 1) { - setinputValue(inputValue - 1) - } - - const _cart = props.cartItems?.map((cartItem, key) => { - return key === parseInt(props.index) ? { ...cartItem, quantity: cartItem.quantity !== 1 ? inputValue-1 : cartItem.quantity } : {...cartItem} - }); - await updateDb(uid,`${props?.item?.id}`,_cart[props?.index]) - updateCart(_cart); - setcartItems(_cart); - - - - } - } - > -
    - -
    - ) -} - -export default QuantityBox; \ No newline at end of file + }; + + // const plus = () => { + // setinputValue(inputValue + 1) + // } + + // const minus = () => { + // if (inputValue !== 1) { + // setinputValue(inputValue - 1) + // } + // } + + return ( +
    +
    + + { + setinputValue(inputValue + 1); + const _info = props.inputItems?.map((eachItem, key) => { + return key === parseInt(props.index) + ? { ...eachItem, quantity: inputValue + 1 } + : { ...eachItem }; + }); + await updateDb(uid, `${props?.item?.id}`, _info[props?.index]); + updateInfo(_info); + setInputItems(_info); + }} + > + + + + { + if (inputValue !== 1) { + setinputValue(inputValue - 1); + } + + const _info = props.inputItems?.map((eachItem, key) => { + return key === parseInt(props.index) + ? { + ...eachItem, + quantity: + eachItem.quantity !== 1 + ? inputValue - 1 + : eachItem.quantity, + } + : { ...eachItem }; + }); + await updateDb(uid, `${props?.item?.id}`, _info[props?.index]); + updateInfo(_info); + setInputItems(_info); + }} + > + + +
    +
    + ); +}; + +export default QuantityBox; diff --git a/src/pages/Details/index.js b/src/pages/Details/index.js index f9bfa9d..838981b 100644 --- a/src/pages/Details/index.js +++ b/src/pages/Details/index.js @@ -1,821 +1,945 @@ -import React, { useContext } from 'react'; -import { Link, useParams } from 'react-router-dom'; -import Rating from '@mui/material/Rating'; -import InnerImageZoom from 'react-inner-image-zoom'; -import 'react-inner-image-zoom/lib/InnerImageZoom/styles.css'; +import React, { useContext } from "react"; +import { Link, useParams } from "react-router-dom"; +import Rating from "@mui/material/Rating"; +import InnerImageZoom from "react-inner-image-zoom"; +import "react-inner-image-zoom/lib/InnerImageZoom/styles.css"; import Slider from "react-slick"; -import { useRef } from 'react'; -import { useState } from 'react'; -import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; -import { useEffect } from 'react'; -import { Button } from '@mui/material'; -import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined'; -import FavoriteBorderOutlinedIcon from '@mui/icons-material/FavoriteBorderOutlined'; -import CompareArrowsIcon from '@mui/icons-material/CompareArrows'; -import { getDatabase, ref, onValue, set, push, child, remove } from "firebase/database"; -import Product from '../../components/product'; -import axios from 'axios'; -import { MyContext } from '../../App'; -import MapComponent from '../../components/map/ITEMmap'; -import { Email } from '@mui/icons-material'; -import useLoggedInUserEmail from '../../Hooks/useLoggedInUserEmail'; -import { db } from '../../firebase'; -import { collection, doc, getDocs, setDoc } from 'firebase/firestore'; - - +import { useRef } from "react"; +import { useState } from "react"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import { useEffect } from "react"; +import { Button } from "@mui/material"; +import ShoppingCartOutlinedIcon from "@mui/icons-material/ShoppingCartOutlined"; +import FavoriteBorderOutlinedIcon from "@mui/icons-material/FavoriteBorderOutlined"; +import CompareArrowsIcon from "@mui/icons-material/CompareArrows"; +import { + getDatabase, + ref, + onValue, + set, + push, + child, + remove, +} from "firebase/database"; +import Product from "../../components/product"; +import axios from "axios"; +import { MyContext } from "../../App"; +import MapComponent from "../../components/map/ITEMmap"; +import { Email } from "@mui/icons-material"; +import useLoggedInUserEmail from "../../Hooks/useLoggedInUserEmail"; +import { db } from "../../firebase"; +import { + collection, + doc, + getDocs, + setDoc, + deleteDoc, +} from "firebase/firestore"; const DetailsPage = (props) => { + const [zoomInage, setZoomImage] = useState( + "https://www.jiomart.com/images/product/original/490000363/maggi-2-minute-masala-noodles-70-g-product-images-o490000363-p490000363-0-202305292130.jpg" + ); + + const [bigImageSize, setBigImageSize] = useState([1500, 1500]); + const [smlImageSize, setSmlImageSize] = useState([150, 150]); + const [loggedInUserEmail, setLoggedInUseEmail] = useLoggedInUserEmail(); + + const [activeSize, setActiveSize] = useState(0); + + const [inputValue, setinputValue] = useState(1); + + const [activeTabs, setActiveTabs] = useState(0); + + const [currentProduct, setCurrentProduct] = useState({}); + const [isAdded, setIsadded] = useState(false); + const [isWishlistItemAdded, setIsWishlistItemAdded] = useState(false); + const [isLoading, setIsLoading] = useState(true); + + const context = useContext(MyContext); + + const [prodCat, setProdCat] = useState({ + parentCat: sessionStorage.getItem("parentCat"), + subCatName: sessionStorage.getItem("subCatName"), + }); + + const [relatedProducts, setRelatedProducts] = useState([]); + + const [rating, setRating] = useState(0.0); + + const [reviewsArr, setReviewsArr] = useState([]); + + const [isAlreadyAddedInCart, setisAlreadyAddedInCart] = useState(false); + const [isAlreadyAddedInWishlist, setisAlreadyAddedInWishlist] = + useState(false); + + const [reviewFields, setReviewFields] = useState({ + review: "", + userName: "", + rating: 0.0, + productId: 0, + date: "", + }); + + const zoomSliderBig = useRef(); + const zoomSlider = useRef(); + + let { id } = useParams(); + + var settings2 = { + dots: false, + infinite: false, + speed: 700, + slidesToShow: 1, + slidesToScroll: 1, + fade: false, + arrows: false, + }; + + var settings = { + dots: false, + infinite: false, + speed: 500, + slidesToShow: 5, + slidesToScroll: 1, + fade: false, + arrows: context.windowWidth > 992 ? true : false, + }; + + var related = { + dots: false, + infinite: false, + speed: 500, + slidesToShow: 4, + slidesToScroll: 1, + fade: false, + arrows: context.windowWidth > 992 ? true : false, + }; + + const goto = (index) => { + zoomSlider.current.slickGoTo(index); + zoomSliderBig.current.slickGoTo(index); + }; + + const isActive = (index) => { + setActiveSize(index); + }; + + const plus = () => { + setinputValue(inputValue + 1); + }; + + const minus = () => { + if (inputValue !== 1) { + setinputValue(inputValue - 1); + } + }; + + useEffect(() => { + window.scrollTo(0, 0); + setIsLoading(true); + props.data.length !== 0 && + props.data.map((item) => { + item.items.length !== 0 && + item.items.map((item_) => { + item_.products.length !== 0 && + item_.products.map((product) => { + if (parseInt(product.id) === parseInt(id)) { + setCurrentProduct(product); + // //console.log(product) + } + }); + }); + }); + + /// product data is getting fetched from here + //related products code + + const related_products = []; + + props.data.length !== 0 && + props.data.map((item) => { + if (prodCat.parentCat === item.cat_name) { + item.items.length !== 0 && + item.items.map((item_) => { + if (prodCat.subCatName === item_.cat_name) { + item_.products.length !== 0 && + item_.products.map((product, index) => { + if (product.id !== parseInt(id)) { + related_products.push(product); + } + }); + } + }); + } + }); - const [zoomInage, setZoomImage] = useState('https://www.jiomart.com/images/product/original/490000363/maggi-2-minute-masala-noodles-70-g-product-images-o490000363-p490000363-0-202305292130.jpg'); - - const [bigImageSize, setBigImageSize] = useState([1500, 1500]); - const [smlImageSize, setSmlImageSize] = useState([150, 150]); - const [loggedInUserEmail,setLoggedInUseEmail]=useLoggedInUserEmail(); - - const [activeSize, setActiveSize] = useState(0); - - const [inputValue, setinputValue] = useState(1); - - const [activeTabs, setActiveTabs] = useState(0); - - const [currentProduct, setCurrentProduct] = useState({}) - const [isAdded, setIsadded] = useState(false); - const [isLoading , setIsLoading] = useState(true); - - const context = useContext(MyContext); - - const [prodCat, setProdCat] = useState({ - parentCat: sessionStorage.getItem('parentCat'), - subCatName: sessionStorage.getItem('subCatName') - }) - - const [relatedProducts, setRelatedProducts] = useState([]); - - const [rating, setRating] = useState(0.0); - - const [reviewsArr, setReviewsArr] = useState([]); - - const [isAlreadyAddedInCart, setisAlreadyAddedInCart] = useState(false); - - const [reviewFields, setReviewFields] = useState({ - review: '', - userName: '', - rating: 0.0, - productId: 0, - date: '' - }) - - - const zoomSliderBig = useRef(); - const zoomSlider = useRef(); - - let { id } = useParams(); - - - var settings2 = { - dots: false, - infinite: false, - speed: 700, - slidesToShow: 1, - slidesToScroll: 1, - fade: false, - arrows: false, - }; - + if (related_products.length !== 0) { + setRelatedProducts(related_products); + } - var settings = { - dots: false, - infinite: false, - speed: 500, - slidesToShow: 5, - slidesToScroll: 1, - fade: false, - arrows: context.windowWidth > 992 ? true : false - }; + showReviews(); + fetchCartProducts(); - var related = { - dots: false, - infinite: false, - speed: 500, - slidesToShow: 4, - slidesToScroll: 1, - fade: false, - arrows: context.windowWidth > 992 ? true : false - }; + fetchWishlistProducts(); + setIsLoading(false); + }, []); - const goto = (index) => { + useEffect(() => { + // //console.log(currentProduct); // Log currentProduct after it has been updated + setIsLoading(false); + }, [currentProduct]); - zoomSlider.current.slickGoTo(index); - zoomSliderBig.current.slickGoTo(index); + const changeInput = (name, value) => { + if (name === "rating") { + setRating(value); } - - - const isActive = (index) => { - setActiveSize(index); + setReviewFields(() => ({ + ...reviewFields, + [name]: value, + productId: id, + date: new Date().toLocaleString(), + })); + }; + + const reviews_Arr = []; + + const submitReview = async (e) => { + e.preventDefault(); + + try { + await axios + .post("http://localhost:5000/productReviews", reviewFields) + .then((response) => { + reviews_Arr.push(response.data); + setReviewFields(() => ({ + review: "", + userName: "", + rating: 0.0, + productId: 0, + date: "", + })); + }); + } catch (error) { + //console.log(error.message); } - const plus = () => { - setinputValue(inputValue + 1) + showReviews(); + }; + + var reviews_Arr2 = []; + const showReviews = async () => { + try { + await axios + .get("https://mavrick-1.github.io/DataApi/data.json") + .then((response) => { + if (response.data.productReviews.length !== 0) { + response.data.productReviews.map((item) => { + if (parseInt(item.productId) === parseInt(id)) { + reviews_Arr2.push(item); + } + }); + } + }); + } catch (error) { + //console.log(error.message); } - const minus = () => { - if (inputValue !== 1) { - setinputValue(inputValue - 1) - } + if (reviews_Arr2.length !== 0) { + setReviewsArr(reviews_Arr2); } - - - useEffect(() => { - window.scrollTo(0, 0) - setIsLoading(true); - props.data.length !== 0 && - props.data.map((item) => { - item.items.length !== 0 && - item.items.map((item_) => { - item_.products.length !== 0 && - item_.products.map((product) => { - if (parseInt(product.id) === parseInt(id)) { - setCurrentProduct(product); - // //console.log(product) - } - }) - }) - }) - - -/// product data is getting fetched from here - //related products code - - const related_products = []; - - props.data.length !== 0 && - props.data.map((item) => { - if (prodCat.parentCat === item.cat_name) { - item.items.length !== 0 && - item.items.map((item_) => { - if (prodCat.subCatName === item_.cat_name) { - item_.products.length !== 0 && - item_.products.map((product, index) => { - if (product.id !== parseInt(id)) { - related_products.push(product) - } - - }) - } - }) - } - - }) - - - if (related_products.length !== 0) { - setRelatedProducts(related_products) - } - - - showReviews(); - - fetchCartProducts() - - setIsLoading(false); - - }, []); - - useEffect(() => { - // //console.log(currentProduct); // Log currentProduct after it has been updated - setIsLoading(false); - }, [currentProduct]); - - const changeInput = (name, value) => { - if (name === "rating") { - setRating(value); - } - setReviewFields(() => ({ - ...reviewFields, - [name]: value, - productId: id, - date: new Date().toLocaleString() - })) - - - + }; + + const addToCart = async (item) => { + try { + const user = localStorage.getItem("uid"); + const cartRef = doc(db, "carts", user); + const productRef = doc(cartRef, "products", `${item.id}`); + await setDoc(productRef, { ...item, quantity: 1 }); + setIsadded(true); + context.setCartCount(context.cartCount + 1); + } catch (error) { + console.error("Error adding item to cart:", error); } - - const reviews_Arr = []; - - const submitReview = async (e) => { - e.preventDefault(); - - try { - - await axios.post("http://localhost:5000/productReviews", reviewFields).then((response) => { - reviews_Arr.push(response.data); - setReviewFields(() => ({ - review: '', - userName: '', - rating: 0.0, - productId: 0, - date: '' - })) - }) - - } catch (error) { - //console.log(error.message); - } - - showReviews(); + }; + + const toggleWishlistItem = async (item) => { + console.log("addToWishlist"); + + if (!isAlreadyAddedInWishlist) { + console.log("Not isAlreadyAddedInWishlist"); + try { + const user = localStorage.getItem("uid"); + const wishlistRef = doc(db, "wishlists", user); + const productRef = doc(wishlistRef, "products", `${item.id}`); + await setDoc(productRef, { ...item, quantity: 1 }); + setIsWishlistItemAdded(true); + setisAlreadyAddedInWishlist(true); + context.setWishlistCount(context.wishlistCount + 1); + } catch (error) { + console.error("Error adding item to wishlist:", error); + } + } else { + console.log("isAlreadyAddedInWishlist"); + + const user = localStorage.getItem("uid"); + + const wishlistItemRef = doc(db, `wishlists/${user}/products/${item.id}`); + + try { + await deleteDoc(wishlistItemRef); + setisAlreadyAddedInWishlist(false); + context.setWishlistCount(context.wishlistCount - 1); + console.log("Wishlist item deleted successfully."); + } catch (error) { + console.error("Error deleting wishlist item:", error); + } } - - var reviews_Arr2 = []; - const showReviews = async () => { - try { - await axios.get("https://mavrick-1.github.io/DataApi/data.json").then((response) => { - if (response.data.productReviews.length !== 0) { - response.data.productReviews.map((item) => { - if (parseInt(item.productId) === parseInt(id)) { - reviews_Arr2.push(item) - } - - }) - - } - }) - } catch (error) { - //console.log(error.message); + }; + + const fetchCartProducts = async () => { + try { + const cartRef = doc(db, "carts", localStorage.getItem("uid")); + const productsCollectionRef = collection(cartRef, "products"); + const querySnapshot = await getDocs(productsCollectionRef); + querySnapshot.forEach((doc) => { + if (parseInt(doc.data()?.id) === parseInt(id)) { + setisAlreadyAddedInCart(true); } - - if (reviews_Arr2.length !== 0) { - - setReviewsArr(reviews_Arr2); - } - + }); + } catch (error) { + console.error("Error fetching cart products:", error); } - - const addToCart = async (item) => { - try { - const user=localStorage.getItem('uid') - const cartRef = doc(db, 'carts', user); - const productRef = doc(cartRef, 'products', `${item.id}`); - await setDoc(productRef, {...item, quantity: 1}); - setIsadded(true) - context.setCartCount(context.cartCount+1); - } catch (error) { - console.error('Error adding item to cart:', error); + }; + + const fetchWishlistProducts = async () => { + try { + const wishlistRef = doc(db, "wishlists", localStorage.getItem("uid")); + const productsCollectionRef = collection(wishlistRef, "products"); + const querySnapshot = await getDocs(productsCollectionRef); + querySnapshot.forEach((doc) => { + if (parseInt(doc.data()?.id) === parseInt(id)) { + setisAlreadyAddedInWishlist(true); } - }; - - const fetchCartProducts = async () => { - try { - const cartRef = doc(db, 'carts', localStorage.getItem("uid")); - const productsCollectionRef = collection(cartRef, 'products'); - const querySnapshot = await getDocs(productsCollectionRef); - querySnapshot.forEach((doc) => { - if(parseInt(doc.data()?.id)===parseInt(id)){ - setisAlreadyAddedInCart(true); - } - }); - } catch (error) { - console.error('Error fetching cart products:', error); - } - }; - - return ( - <> - - - - { - context.windowWidth < 992 && + )} +
    + {!isLoading && } +
    + +
    + {context.windowWidth > 992 && ( +
    +
    +
      +
    • + Home{" "} +
    • +
    • + + sessionStorage.setItem( + "cat", + prodCat.parentCat.split(" ").join("-").toLowerCase() + ) } - - - - } -
      - {!isLoading && } -
      - -
      - { - context.windowWidth > 992 && -
      -
      -
        -
      • Home
      • -
      • sessionStorage.setItem('cat', prodCat.parentCat.split(' ').join('-').toLowerCase())} className='text-capitalize'>{prodCat.parentCat}
      • - -
      • sessionStorage.setItem('cat', prodCat.subCatName.toLowerCase())} className='text-capitalize'>{prodCat.subCatName}
      • -
      • {currentProduct.productName}
      • -
      -
      - - -
      - } - - - - -
      -
      - - {/* productZoom code start here */} -
      -
      - - { - currentProduct.productImages !== undefined && - currentProduct.productImages.map((imgUrl, index) => { - return ( -
      - - -
      - ) - }) - } - -
      -
      - - - - - { - currentProduct.productImages !== undefined && - currentProduct.productImages.map((imgUrl, index) => { - return ( -
      - goto(index)} /> -
      - ) - }) - } - - -
      - + className="text-capitalize" + > + {prodCat.parentCat} + {" "} +
    • + +
    • + + sessionStorage.setItem( + "cat", + prodCat.subCatName.toLowerCase() + ) + } + className="text-capitalize" + > + {prodCat.subCatName} + {" "} +
    • +
    • {currentProduct.productName}
    • +
    +
    +
    + )} + +
    +
    + {/* productZoom code start here */} +
    +
    + + {currentProduct.productImages !== undefined && + currentProduct.productImages.map((imgUrl, index) => { + return ( +
    +
    - {/* productZoom code ends here */} - - - {/* product info code start here */} -
    -

    {currentProduct.productName}

    -
    - - (32 reviews) -
    - -
    - Rs {currentProduct.price} -
    - {currentProduct.discount}% Off - Rs {currentProduct.oldPrice} -
    -
    - -

    {currentProduct.description}

    - - { - currentProduct.weight !== undefined && currentProduct.weight.length !== 0 && -
    - Size / Weight: - + ); + })} + +
    + + + {currentProduct.productImages !== undefined && + currentProduct.productImages.map((imgUrl, index) => { + return ( +
    + goto(index)} + /> +
    + ); + })} +
    +
    + {/* productZoom code ends here */} + + {/* product info code start here */} +
    +

    {currentProduct.productName}

    +
    + + (32 reviews) +
    + +
    + + Rs {currentProduct.price} + +
    + + {currentProduct.discount}% Off + + + Rs {currentProduct.oldPrice} + +
    +
    + +

    {currentProduct.description}

    + + {currentProduct.weight !== undefined && + currentProduct.weight.length !== 0 && ( +
    + Size / Weight: + +
    + )} + + {currentProduct.RAM !== undefined && + currentProduct.RAM.length !== 0 && ( +
    + RAM: + +
    + )} + + {currentProduct.SIZE !== undefined && + currentProduct.SIZE.length !== 0 && ( +
    + SIZE: + +
    + )} + +
    +
    + {context.windowWidth > 992 && ( + + )} + + +
    +
    +
    + {/* product info code ends here */} +
    + +
    +
    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    + +
    + + {activeTabs === 0 && ( +
    +

    {currentProduct.description}

    +
    + )} + + {activeTabs === 1 && ( +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Stand Up +

    35″L x 24″W x 37-45″H(front to back wheel)

    +
    Folded (w/o wheels) +

    32.5″L x 18.5″W x 16.5″H

    +
    Folded (w/ wheels) +

    32.5″L x 24″W x 18.5″H

    +
    Door Pass Through +

    24

    +
    Frame +

    Aluminum

    +
    Weight (w/o wheels) +

    20 LBS

    +
    Weight Capacity +

    60 LBS

    +
    Width +

    24″

    +
    Handle height (ground to handle) +

    37-45″

    +
    Wheels +

    12″ air / wide track slick tread

    +
    Seat back height +

    21.5″

    +
    Head room (inside canopy) +

    25″

    +
    Color +

    Black, Blue, Red, White

    +
    Size +

    M, S

    +
    +
    +
    + )} + + {activeTabs === 2 && ( +
    +
    +
    +

    Customer questions & answers

    +
    + + {reviewsArr.length !== 0 && + reviewsArr !== undefined && + reviewsArr.map((item, index) => { + return ( +
    +
    +
    +
    - } - - - - { - currentProduct.RAM !== undefined && currentProduct.RAM.length !== 0 && -
    - RAM: - + + {item.userName} + +
    + +
    +
    +
    {item.date}
    +
    + +
    - } - - - { - currentProduct.SIZE !== undefined && currentProduct.SIZE.length !== 0 && -
    - SIZE: - -
    +

    {item.review}

    +
    +
    + ); + })} + +
    + +
    + +
    +

    Add a review


    +
    + +
    +
    +
    +
    + + changeInput(e.target.name, e.target.value) + } + />
    - +
    + +
    +
    + + changeInput(e.target.name, e.target.value) + } + /> +
    +
    - {/* product info code ends here */} -
    - - - -
    -
    -
      -
    • - -
    • -
    • - -
    • -
    • - -
    • - -
    - - -
    - - { - activeTabs === 0 && -
    -

    {currentProduct.description}

    -
    - - } - - - { - activeTabs === 1 && - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Stand Up -

    35″L x 24″W x 37-45″H(front to back wheel)

    -
    Folded (w/o wheels) -

    32.5″L x 18.5″W x 16.5″H

    -
    Folded (w/ wheels) -

    32.5″L x 24″W x 18.5″H

    -
    Door Pass Through -

    24

    -
    Frame -

    Aluminum

    -
    Weight (w/o wheels) -

    20 LBS

    -
    Weight Capacity -

    60 LBS

    -
    Width -

    24″

    -
    Handle height (ground to handle) -

    37-45″

    -
    Wheels -

    12″ air / wide track slick tread

    -
    Seat back height -

    21.5″

    -
    Head room (inside canopy) - -

    25″

    -
    Color -

    Black, Blue, Red, White

    -
    Size -

    M, S

    -
    -
    -
    - - } - - - - { - activeTabs === 2 && - -
    -
    -
    -

    Customer questions & answers

    -
    - - - - { - reviewsArr.length !== 0 && reviewsArr !== undefined && - reviewsArr.map((item, index) => { - - - return ( - - -
    -
    -
    - -
    - {item.userName} -
    - - -
    -
    -
    {item.date}
    -
    - -
    -
    - -

    {item.review}

    -
    - -
    - ) - - - }) - } - - - - - -
    - -
    - - - - - - - -

    Add a review


    -
    - -
    - -
    -
    -
    - changeInput(e.target.name, e.target.value)} /> -
    -
    - -
    -
    - changeInput(e.target.name, e.target.value)} - /> -
    -
    - -
    - - -
    -
    - -
    - - - -
    - - - - -
    -

    Customer reviews

    - -
    - - 4.8 out of 5 -
    - -
    - - - - -
    - 5 star -
    -
    75%
    -
    -
    - - -
    - 4 star -
    -
    50%
    -
    -
    - - - -
    - 3 star -
    -
    55%
    -
    -
    - - - -
    - 2 star -
    -
    35%
    -
    -
    - - - -
    - 1 star -
    -
    25%
    -
    -
    - - - - -
    - - - - -
    -
    - } - - - - +
    +
    +
    +
    - -
    - -
    -

    Related products

    -
    - - - { - - relatedProducts.length !== 0 && - relatedProducts.map((product, index) => { - - return ( -
    - -
    - ) - }) - } - -
    +
    +

    Customer reviews

    + +
    + + 4.8 out of 5 +
    + +
    + +
    + 5 star +
    +
    + 75% +
    +
    +
    + +
    + 4 star +
    +
    + 50% +
    +
    +
    + +
    + 3 star +
    +
    + 55% +
    +
    +
    + +
    + 2 star +
    +
    + 35% +
    +
    +
    + +
    + 1 star +
    +
    + 25% +
    +
    +
    - - +
    - - -
    - - - ) -} - - -export default DetailsPage; - + )} + + + +
    + +
    +

    Related products

    +
    + + {relatedProducts.length !== 0 && + relatedProducts.map((product, index) => { + return ( +
    + +
    + ); + })} +
    +
    + + + + ); +}; + +export default DetailsPage; \ No newline at end of file diff --git a/src/pages/cart/index.js b/src/pages/cart/index.js index 049ac91..d7f4dfa 100644 --- a/src/pages/cart/index.js +++ b/src/pages/cart/index.js @@ -17,14 +17,20 @@ import { useNavigate } from "react-router-dom"; import KeyboardBackspaceIcon from "@mui/icons-material/KeyboardBackspace"; import MapComponent from "../../components/map/ITEMmap"; import { db } from "../../firebase"; -import { collection, deleteDoc, doc, getDocs, onSnapshot } from "firebase/firestore"; +import { + collection, + deleteDoc, + doc, + getDocs, + onSnapshot, +} from "firebase/firestore"; const Cart = () => { const [cartItems, setCartItems] = useState([]); const [error, setError] = useState(null); const [totalPrice, setTotalPrice] = useState(0); const context = useContext(MyContext); const navigate = useNavigate(); - const [uid,setUid] = useState(localStorage.getItem("uid")) + const [uid, setUid] = useState(localStorage.getItem("uid")); useEffect(() => { try { if (context.isLogin === "true") { @@ -41,54 +47,52 @@ const Cart = () => { }, []); useEffect(() => { - fetchCartProducts() - }, [db,uid]); + fetchCartProducts(); + }, [db, uid]); const fetchCartProducts = async () => { try { - const cartRef = doc(db, 'carts', uid); - const productsCollectionRef = collection(cartRef, 'products'); + const cartRef = doc(db, "carts", uid); + const productsCollectionRef = collection(cartRef, "products"); const querySnapshot = await getDocs(productsCollectionRef); let products = []; let price = 0; querySnapshot.forEach((doc) => { products.push({ id: doc.id, ...doc.data() }); - price+= parseInt(doc.data()?.price)*(doc.data()?.quantity) + price += parseInt(doc.data()?.price) * doc.data()?.quantity; }); - context.setCartCount(products.length) + context.setCartCount(products.length); setCartItems(products); - setTotalPrice(price) + setTotalPrice(price); } catch (error) { - console.error('Error fetching cart products:', error); + console.error("Error fetching cart products:", error); } }; - const deleteCartItem = async (uid, cartItemId) => { - const cartItemRef = doc(db, 'carts', uid, 'products', cartItemId); - + const cartItemRef = doc(db, "carts", uid, "products", cartItemId); + try { await deleteDoc(cartItemRef); - fetchCartProducts() - console.log('Cart item deleted successfully.'); + fetchCartProducts(); + console.log("Cart item deleted successfully."); } catch (error) { - console.error('Error deleting cart item:', error); + console.error("Error deleting cart item:", error); } }; const deleteAllCartItems = async (uid) => { + const productsCollectionRef = collection(db, "carts", uid, "products"); - const productsCollectionRef = collection(db, 'carts', uid, 'products'); - try { const querySnapshot = await getDocs(productsCollectionRef); querySnapshot.forEach(async (doc) => { await deleteDoc(doc.ref); }); - await fetchCartProducts() - console.log('All cart items deleted successfully.'); + await fetchCartProducts(); + console.log("All cart items deleted successfully."); } catch (error) { - console.error('Error deleting cart items:', error); + console.error("Error deleting cart items:", error); } }; @@ -194,12 +198,20 @@ const Cart = () => { + {/* + /> */} @@ -214,7 +226,9 @@ const Cart = () => { deleteCartItem(uid,`${item?.id}`)} + onClick={() => + deleteCartItem(uid, `${item?.id}`) + } > @@ -306,11 +320,11 @@ const Cart = () => {

    Your Cart is Empty

    Please add some products to your cart

    - - - + + +
    diff --git a/src/pages/cart/style.css b/src/pages/cart/style.css index 542bf1d..8dd4eaf 100644 --- a/src/pages/cart/style.css +++ b/src/pages/cart/style.css @@ -1,21 +1,66 @@ +.cartSection { + width: 100%; + height: auto; + padding: 10px 0px; +} +.cartSection .clearCart { + font-weight: 600; + font-size: 18px; +} +.cartSection .clearCart svg { + font-size: 25px !important; +} -.cartSection{width: 100%; height: auto; padding: 10px 0px;} -.cartSection .clearCart{font-weight: 600; font-size: 18px;} -.cartSection .clearCart svg{font-size: 25px !important;} +.cartWrapper table thead { + background: #f1f1f1; + overflow: hidden; +} +.cartWrapper table thead th:first-child { + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; +} +.cartWrapper table thead th:last-child { + border-top-right-radius: 15px; + border-bottom-right-radius: 15px; +} -.cartWrapper table thead{background: #f1f1f1; overflow: hidden; } -.cartWrapper table thead th:first-child{border-top-left-radius: 15px; border-bottom-left-radius: 15px;} -.cartWrapper table thead th:last-child{border-top-right-radius: 15px; border-bottom-right-radius: 15px;} +.cartWrapper table tbody td { + vertical-align: middle; +} +.cartWrapper table tbody td .img { + width: 30%; + height: 150px; + padding: 5px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 5px; +} +.cartWrapper table tbody td .img img { + width: 100%; + height: 100%; + object-fit: cover; +} +.cartWrapper table tbody td .info { + width: 70%; +} +.cartWrapper table tbody td .info a { + color: rgba(0, 0, 0, 0.7); +} +.cartWrapper table tbody td .info a:hover { + text-decoration: none; +} -.cartWrapper table tbody td{vertical-align: middle;} -.cartWrapper table tbody td .img{width: 30%; height: 150px; padding: 5px; border: 1px solid rgba(0,0,0,0.1); border-radius: 5px;} -.cartWrapper table tbody td .img img{width: 100%; height: 100%; object-fit: cover;} -.cartWrapper table tbody td .info{width: 70%;} -.cartWrapper table tbody td .info a{color: rgba(0,0,0,0.7);} -.cartWrapper table tbody td .info a:hover{text-decoration: none;} +.cartWrapper table tbody td span { + font-weight: 600; + font-size: 28px; +} +.cartWrapper table tbody td span.text-g { + font-weight: bold; +} -.cartWrapper table tbody td span{font-weight: 600; font-size: 28px;} -.cartWrapper table tbody td span.text-g{font-weight: bold;} - -.cartRightBox{padding-left: 100px;} -.cartRightBox .card{position: sticky; top: 150px;} +.cartRightBox { + padding-left: 100px; +} +.cartRightBox .card { + position: sticky; + top: 150px; +} diff --git a/src/pages/wishList/index.js b/src/pages/wishList/index.js new file mode 100644 index 0000000..4e0cd2c --- /dev/null +++ b/src/pages/wishList/index.js @@ -0,0 +1,339 @@ +import React, { useContext, useState, useEffect } from "react"; +import { Link } from "react-router-dom"; +import "./style.css"; +import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; +import Rating from "@mui/material/Rating"; +import { + Button, + Card, + CardActions, + CardContent, + Typography, +} from "@mui/material"; +import QuantityBox from "../../components/quantityBox"; +import { MyContext } from "../../App"; +import { getDatabase, ref, onValue, remove } from "firebase/database"; +import { useNavigate } from "react-router-dom"; +import KeyboardBackspaceIcon from "@mui/icons-material/KeyboardBackspace"; +import MapComponent from "../../components/map/ITEMmap"; +import { db } from "../../firebase"; +import { + collection, + deleteDoc, + doc, + getDocs, + onSnapshot, +} from "firebase/firestore"; +const WishList = () => { + const [wishlistItems, setWishlistItems] = useState([]); + const [error, setError] = useState(null); + const [totalPrice, setTotalPrice] = useState(0); + const context = useContext(MyContext); + const navigate = useNavigate(); + const [uid, setUid] = useState(localStorage.getItem("uid")); + + console.log(wishlistItems); + useEffect(() => { + try { + if (context.isLogin === "true") { + fetchWishlistProducts(); + } else { + navigate("/signIn"); // Navigate to About Us page if not logged in + } + + window.scrollTo(0, 0); + } catch (error) { + console.error("Error:", error); + setError("Failed to fetch data from the server"); // Set error state if there's an error with database connection + } + }, []); + + useEffect(() => { + fetchWishlistProducts(); + }, [db, uid]); + + const fetchWishlistProducts = async () => { + try { + const wishlistsRef = doc(db, "wishlists", uid); + const productsCollectionRef = collection(wishlistsRef, "products"); + const querySnapshot = await getDocs(productsCollectionRef); + let products = []; + let price = 0; + querySnapshot.forEach((doc) => { + products.push({ id: doc.id, ...doc.data() }); + price += parseInt(doc.data()?.price) * doc.data()?.quantity; + }); + context.setWishlistCount(products.length); + console.log(products); + setWishlistItems(products); + setTotalPrice(price); + } catch (error) { + console.error("Error fetching wishlist products:", error); + } + }; + + const deleteWishlistItem = async (uid, wishlistItemId) => { + const wishlistItemRef = doc( + db, + "wishlists", + uid, + "products", + wishlistItemId + ); + + try { + await deleteDoc(wishlistItemRef); + fetchWishlistProducts(); + console.log("Wishlist item deleted successfully."); + } catch (error) { + console.error("Error deleting wishlist item:", error); + } + }; + + const deleteAllWishlistItems = async (uid) => { + const productsCollectionRef = collection(db, "wishlists", uid, "products"); + + try { + const querySnapshot = await getDocs(productsCollectionRef); + querySnapshot.forEach(async (doc) => { + await deleteDoc(doc.ref); + }); + await fetchWishlistProducts(); + console.log("All wishlist items deleted successfully."); + } catch (error) { + console.error("Error deleting wishlist items:", error); + } + }; + + const updateWishlist = (items) => { + setWishlistItems(items); + }; + + return ( + <> + {wishlistItems.length > 0 ? ( + // Render cart section if cartItems array is not empty + <> + {context.windowWidth > 992 && ( +
    +
    +
      +
    • + Home +
    • +
    • Shop
    • +
    • Wishlist
    • +
    +
    +
    + )} +
    +
    +
    +
    +
    +
    +

    Your Wishlist

    +

    + There are{" "} + {wishlistItems.length}{" "} + products in your Wishlist +

    +
    + + deleteAllWishlistItems(uid)} + > + Clear Wishlist + +
    + +
    +
    + + + + + + + + + + + + + {wishlistItems.length !== 0 && + wishlistItems.map((item, index) => { + return ( + + + + + + + + + + + + ); + })} + +
    ProductUnit PriceQuantitySubtotalRemove
    +
    +
    + + + +
    + +
    + +

    {item.productName}

    + + {" "} + + ({parseFloat(item.rating)}) + +
    +
    +
    + + Rs:{" "} + {parseInt(item.price.split(",").join(""))} + + + + + + Rs.{" "} + {parseInt( + item.price.split(",").join("") + ) * parseInt(item.quantity)} + + + + deleteWishlistItem(uid, `${item?.id}`) + } + > + + +
    +
    +
    + +
    + +
    + + + + {/* */} +
    +
    + +
    +
    +
    +
    Subtotal
    +

    + + {wishlistItems.length !== 0 && + wishlistItems + .map( + (item) => + parseInt(item.price.split(",").join("")) * + item.quantity + ) + .reduce((total, value) => total + value, 0)} + +

    +
    + +
    +
    Shipping
    +

    + Free +

    +
    + +
    +
    Estimate for
    +

    + United Kingdom +

    +
    + +
    +
    Total
    +

    + + {wishlistItems.length !== 0 && + wishlistItems + .map( + (item) => + parseInt(item.price.split(",").join("")) * + item.quantity + ) + .reduce((total, value) => total + value, 0)} + +

    +
    + +
    + +
    +
    +
    +
    +
    {" "} + + ) : ( + // Render message indicating cart is empty if cartItems array is empty +
    +
    +
    +
    +

    Your Wishlist is Empty

    +

    Please add some products to your wishlist

    + + + +
    +
    +
    +
    + )} + + ); +}; + +export default WishList; diff --git a/src/pages/wishList/style.css b/src/pages/wishList/style.css new file mode 100644 index 0000000..8dd4eaf --- /dev/null +++ b/src/pages/wishList/style.css @@ -0,0 +1,66 @@ +.cartSection { + width: 100%; + height: auto; + padding: 10px 0px; +} +.cartSection .clearCart { + font-weight: 600; + font-size: 18px; +} +.cartSection .clearCart svg { + font-size: 25px !important; +} + +.cartWrapper table thead { + background: #f1f1f1; + overflow: hidden; +} +.cartWrapper table thead th:first-child { + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; +} +.cartWrapper table thead th:last-child { + border-top-right-radius: 15px; + border-bottom-right-radius: 15px; +} + +.cartWrapper table tbody td { + vertical-align: middle; +} +.cartWrapper table tbody td .img { + width: 30%; + height: 150px; + padding: 5px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 5px; +} +.cartWrapper table tbody td .img img { + width: 100%; + height: 100%; + object-fit: cover; +} +.cartWrapper table tbody td .info { + width: 70%; +} +.cartWrapper table tbody td .info a { + color: rgba(0, 0, 0, 0.7); +} +.cartWrapper table tbody td .info a:hover { + text-decoration: none; +} + +.cartWrapper table tbody td span { + font-weight: 600; + font-size: 28px; +} +.cartWrapper table tbody td span.text-g { + font-weight: bold; +} + +.cartRightBox { + padding-left: 100px; +} +.cartRightBox .card { + position: sticky; + top: 150px; +}