diff --git a/package-lock.json b/package-lock.json index a3c6c909..3af8300c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,13 +19,16 @@ "axios": "^1.7.2", "cors": "^2.8.5", "dotenv": "^16.4.5", + "emoji-picker-react": "^4.11.1", "formik": "^2.4.6", "html-webpack-plugin": "^5.6.0", + "jwt-decode": "^4.0.0", "mini-css-extract-plugin": "^2.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-helmet": "^6.1.0", "react-icons": "^5.2.1", + "react-input-emoji": "^5.9.0", "react-loader-spinner": "^6.1.6", "react-redux": "^9.1.2", "react-router-dom": "^6.24.0", @@ -2180,6 +2183,22 @@ "node": ">=10.0.0" } }, + "node_modules/@emoji-mart/data": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emoji-mart/data/-/data-1.2.1.tgz", + "integrity": "sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==", + "license": "MIT" + }, + "node_modules/@emoji-mart/react": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emoji-mart/react/-/react-1.1.1.tgz", + "integrity": "sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g==", + "license": "MIT", + "peerDependencies": { + "emoji-mart": "^5.2", + "react": "^16.8 || ^17 || ^18" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.12.0", "license": "MIT", @@ -12499,6 +12518,27 @@ "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, + "node_modules/emoji-mart": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/emoji-mart/-/emoji-mart-5.6.0.tgz", + "integrity": "sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==", + "license": "MIT" + }, + "node_modules/emoji-picker-react": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.11.1.tgz", + "integrity": "sha512-e3vhGcZyyNu7GqJaXzgoVxtASXs97duAP/vh7aL88dHJcW72DjuwYMjipzNBCjPFxXwUiQas483SKCAxPwwaUQ==", + "license": "MIT", + "dependencies": { + "flairup": "1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "dev": true, @@ -14472,6 +14512,8 @@ }, "node_modules/file-loader": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dev": true, "license": "MIT", "dependencies": { @@ -14673,6 +14715,12 @@ "node": ">=6" } }, + "node_modules/flairup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flairup/-/flairup-1.0.0.tgz", + "integrity": "sha512-IKlE+pNvL2R+kVL1kEhUYqRxVqeFnjiIvHWDMLFXNaqyUdFXQM2wte44EfMYJNHkW16X991t2Zg8apKkhv7OBA==", + "license": "MIT" + }, "node_modules/flat": { "version": "5.0.2", "dev": true, @@ -19647,6 +19695,15 @@ "node": ">=8" } }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/keyv": { "version": "4.5.4", "dev": true, @@ -22596,6 +22653,24 @@ "react": "^18.3.1" } }, + "node_modules/react-easy-emoji": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/react-easy-emoji/-/react-easy-emoji-1.8.1.tgz", + "integrity": "sha512-wAf2x+cjwtOlLfXnjc0J3k5B2PDZdoxd1BjtfKr5tq2AL7t2ygvByJQWgFOyN28xg3qe8EKBM6pKxGP+qrGWuQ==", + "license": "MIT", + "dependencies": { + "string-replace-to-array": "^2.1.0" + }, + "peerDependencies": { + "@types/react": ">=0.14.0", + "react": ">=0.14.27" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-element-to-jsx-string": { "version": "15.0.0", "dev": true, @@ -22647,6 +22722,26 @@ "react": "*" } }, + "node_modules/react-input-emoji": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/react-input-emoji/-/react-input-emoji-5.9.0.tgz", + "integrity": "sha512-37Bbg4DEI4UXQ/tNSG3shIA0iFqk3vkhvfTZSQxi/oweeB/870G/6lvp65Ebex2rNM+UlwjMmR80rlJQwl78lQ==", + "license": "MIT", + "dependencies": { + "@emoji-mart/data": "1.2.1", + "@emoji-mart/react": "1.1.1", + "emoji-mart": "5.6.0", + "react-easy-emoji": "^1.8.1" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": ">=17.0.x", + "react-dom": ">=17.0.x" + } + }, "node_modules/react-is": { "version": "16.13.1", "license": "MIT" @@ -24265,6 +24360,12 @@ "node": ">=10" } }, + "node_modules/string-replace-to-array": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-replace-to-array/-/string-replace-to-array-2.1.1.tgz", + "integrity": "sha512-i31csTEoIrcB8pusAF72Z0WsF04sbdiH4s0egpcmFj30SgHYdYd1swmZ7Zb1qFryJ5DbZR6z4rSjOzoUcrWUWw==", + "license": "MIT" + }, "node_modules/string-width": { "version": "5.1.2", "dev": true, diff --git a/package.json b/package.json index f7ea46c1..ba875b81 100644 --- a/package.json +++ b/package.json @@ -21,13 +21,16 @@ "axios": "^1.7.2", "cors": "^2.8.5", "dotenv": "^16.4.5", + "emoji-picker-react": "^4.11.1", "formik": "^2.4.6", "html-webpack-plugin": "^5.6.0", + "jwt-decode": "^4.0.0", "mini-css-extract-plugin": "^2.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-helmet": "^6.1.0", "react-icons": "^5.2.1", + "react-input-emoji": "^5.9.0", "react-loader-spinner": "^6.1.6", "react-redux": "^9.1.2", "react-router-dom": "^6.24.0", diff --git a/public/assets/notification.mp3 b/public/assets/notification.mp3 new file mode 100644 index 00000000..0cd8d683 Binary files /dev/null and b/public/assets/notification.mp3 differ diff --git a/src/App.scss b/src/App.scss index 8a27a8d2..55c86793 100644 --- a/src/App.scss +++ b/src/App.scss @@ -30,5 +30,6 @@ @import "./assets/styles/tables.scss"; @import "./assets/styles/adminDashboard.scss"; @import "./assets/styles/users.scss"; +@import "./assets/styles/liveChat.scss"; @import "./assets//styles/UserProfile.scss"; @import "./assets/styles/SellerSideProduct.scss"; diff --git a/src/assets/styles/LandingPage.scss b/src/assets/styles/LandingPage.scss index 98b48e14..a9b41e22 100644 --- a/src/assets/styles/LandingPage.scss +++ b/src/assets/styles/LandingPage.scss @@ -1,6 +1,6 @@ .landing-container { padding: 3rem 2rem 4rem 5rem; - + background-color: $container-color; .loader { display: flex; justify-content: center; @@ -20,15 +20,130 @@ border-radius: 0.5rem; padding: 2rem; } + .head { display: flex; justify-content: space-between; align-items: center; + h1 { font-size: 3.6rem; } } - + + .filters { + display: flex; + align-items: start; + margin: 20px 0; + background-color: $third-color; + padding: 2rem 1rem; + border-radius: 1rem; + } + + .filters div { + display: flex; + align-items: center; + gap: 1rem; + font-size: 1.5rem; + } + + .filters { + label { + width: 15rem; + } + .span{ + width: 20rem; + } + } + + input[type="range"] { + -webkit-appearance: none; + width: 100%; + height: 8px; + background: #ddd; + border-radius: 5px; + outline: none; + } + + input[type="range"]::-webkit-slider-runnable-track { + width: 100%; + height: 8px; + cursor: pointer; + background: #ddd; + border-radius: 5px; + } + + input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 20px; + width: 20px; + background: #ff6d18; + border-radius: 50%; + margin-top: -6px; + cursor: pointer; + } + + input[type="range"]::-moz-range-track { + width: 100%; + height: 8px; + background: #ddd; + border-radius: 5px; + cursor: pointer; + } + + input[type="range"]::-moz-range-thumb { + height: 20px; + width: 20px; + background: #ff6d18; + border-radius: 50%; + cursor: pointer; + } + + input[type="range"]::-ms-track { + width: 100%; + height: 5px; + cursor: pointer; + background: transparent; + border-color: transparent; + color: transparent; + } + + input[type="range"]::-ms-fill-lower { + background: #ddd; + border-radius: 5px; + } + + input[type="range"]::-ms-fill-upper { + background: #ddd; + border-radius: 5px; + } + + input[type="range"]::-ms-thumb { + height: 10px; + width: 10px; + background: #ff6d18; + border-radius: 50%; + cursor: pointer; + margin-top: 0; + } + + input[type="range"]:focus { + outline: none; + } + + input[type="range"]:hover::-webkit-slider-runnable-track { + background: #ccc; + } + + input[type="range"]:hover::-moz-range-track { + background: #ccc; + } + + input[type="range"]:hover::-ms-fill-lower, + input[type="range"]:hover::-ms-fill-upper { + background: #ccc; + } + .product-list { display: grid; justify-items: center; @@ -45,44 +160,47 @@ .not-found-img img { width: 40vw; } + .not-found-text { - font-family: $text-family; - font-weight: 700; - font-size: 1.2rem; - margin-top: 1rem; - margin-bottom: 2rem; - text-align: center; - line-height: 1.5; - letter-spacing: 0.05em; - color: $text2-color; - text-decoration: none; - transition: all 0.3s ease-in-out; + font-family: $text-family; + font-weight: 700; + font-size: 1.2rem; + margin-top: 1rem; + margin-bottom: 2rem; + text-align: center; + line-height: 1.5; + letter-spacing: 0.05em; + color: $text2-color; + text-decoration: none; + transition: all 0.3s ease-in-out; } + .btn-link { - border: none; - background-color: $primary-color; - padding: 1rem 4rem; - text-decoration: none; - color: $white-color; - font-family: $text-family; - font-weight: 700; - font-size: 1.2rem; - border-radius: 2rem; - cursor: pointer; + border: none; + background-color: $primary-color; + padding: 1rem 4rem; + text-decoration: none; + color: $white-color; + font-family: $text-family; + font-weight: 700; + font-size: 1.2rem; + border-radius: 2rem; + cursor: pointer; } .btn-link:hover { - background-color: $white-color; - color: $primary-color; - border: 1px solid $border-color; - box-shadow: 2px 2px 10px rgba(0,0,0,0.5); - transition: all 0.3s ease-in-out; + background-color: $white-color; + color: $primary-color; + border: 1px solid $border-color; + box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5); + transition: all 0.3s ease-in-out; } } @media screen and (max-width: 768px) { .landing-container { padding: 3rem 4rem 4rem 4rem; + .head { h1 { font-size: 2.6rem; diff --git a/src/assets/styles/Product.scss b/src/assets/styles/Product.scss index 23d83890..ecf1af2e 100644 --- a/src/assets/styles/Product.scss +++ b/src/assets/styles/Product.scss @@ -1,19 +1,19 @@ .product { - border: 1px solid $border-color; border-radius: 1rem; overflow: hidden; width: 26rem; margin-top: 2rem; - box-shadow: 0.5rem 0.5rem 0.5rem rgba(0, 0, 0, 0.2); - background-color: $white; + box-shadow: 0.1rem 0.1rem 0.5rem rgba(0, 0, 0, 0.2); + background-color: $secondary-color-light; &:hover { transform: scale(1.05); box-shadow: 1rem 1rem 1rem rgba(0, 0, 0, 0.3); + transition: all 0.2s ease-in-out; } .product-image-container { position: relative; - height: 18.8rem; + height: 25rem; cursor: pointer; .discount-badge { @@ -39,7 +39,7 @@ .product-info { padding: 1rem; - background-color: $secondary-color-light; + .product-name { font-size: 1.7rem; diff --git a/src/assets/styles/ViewCart.scss b/src/assets/styles/ViewCart.scss index e41d91b2..35402ef0 100644 --- a/src/assets/styles/ViewCart.scss +++ b/src/assets/styles/ViewCart.scss @@ -1,140 +1,194 @@ FaCheckSquare { color: $primary-color; } + .cart-section { - display: flex; - flex-direction: row; - .cart-products { - flex: 2; - margin: 10px; - .cart { - border: 1px solid $border-color; - border-radius: 10px; - margin-bottom: 10px; - .title { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - border-bottom: 2px solid $border-color; - margin: 10px; - gap: 10px; - .check { - margin: 5px; - } - h2 { - padding-left: 5px; - margin-bottom: 12px; - font-size: 20px; - flex: 1; - } - .checkout-btn { - background: $primary-color; - cursor: pointer; - width: 8%; - color: $white; - border-radius: 5px; - border: none; - height: 20px; - margin-top: -1px; - } + background-color: $secondary-color-light; - .delete { - cursor: pointer; - font-size: 12px; - margin-top: 2px; - } - } - .products-list { - display: flex; - flex-direction: column; - .product-box { + .clear-cart { + border: none; + justify-content: end; + align-items: end; + display: flex; + width: 100%; + margin-bottom: 1rem; + background-color: $secondary-color-light; + + .delete { + border: none; + background-color: $primary-color; + color: $white; + font-size: 1.5rem; + padding: 1rem; + border-radius: 5px; + display: flex; + cursor: pointer; + } + + .deleteIcon { + font-size: 2rem; + margin-right: 1rem; + cursor: pointer; + } + } + + .cartSection { + display: flex; + .cart-products { + flex: 2; + margin: 10px; + + .cart { + border: 1px solid $border-color; + border-radius: 10px; + margin-bottom: 10px; + margin-left: 1rem; + + .title { display: flex; flex-direction: row; - padding: 10px; + flex-wrap: nowrap; + border-bottom: 2px solid $border-color; + margin: 10px; + gap: 10px; + .check { - padding: 10px; + margin: 5px; } - .image { - border: 2px solid $border-color; - border-radius: 10px; - width: 180px; - height: 135px; - img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 10px; - } + + h2 { + padding-left: 5px; + margin-bottom: 12px; + font-size: 20px; + flex: 1; + } + + .checkout-btn { + background: $primary-color; + cursor: pointer; + width: 8%; + color: $white; + border-radius: 5px; + border: none; + height: 20px; + margin-top: -1px; + } + + .delete { + cursor: pointer; + font-size: 12px; + margin-top: 2px; } - .description { - flex: 4; - padding: 5px; - h4 { - font-weight: 500; - margin: 5px; - margin-bottom: 10px; - font-size: 18px; - cursor: pointer; + } + + .products-list { + display: flex; + flex-direction: column; + + .product-box { + display: flex; + flex-direction: row; + padding: 10px; + + .check { + padding: 10px; } - .flexer { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - .left { - flex: 1; - .discount { - background: $icon-color-unopacity; - padding: 3px; - border-radius: 5px; - margin: 5px; - margin-bottom: 10px; - font-size: 16px; - } - .price { - margin: 5px; - margin-bottom: 10px; - font-size: 16px; - } + + .image { + border: 2px solid $border-color; + border-radius: 10px; + width: 180px; + height: 135px; + + img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 10px; + } + } + + .description { + flex: 4; + padding: 5px; + + h4 { + font-weight: 500; + margin: 5px; + margin-bottom: 10px; + font-size: 18px; + cursor: pointer; } - .controls { - .quantity { - background: $border-color; - padding: 3px; - border-radius: 20px; - margin-bottom: 10px; - button { - background: $red-color; - border: 0; - border-radius: 50%; - color: $background-color; - padding: 5px; - width: 20px; - height: 20px; - font-size: 12px; - cursor:pointer; + + .flexer { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + + .left { + flex: 1; + + .discount { + background: $icon-color-unopacity; + padding: 3px; + border-radius: 5px; + margin: 5px; + margin-bottom: 10px; + font-size: 16px; } - input { - background: transparent; - border: 0; - width: 20px; - padding-left: 10px; - padding-right: 10px; - text-align: center; - align-items: center; + + .price { + margin: 5px; + margin-bottom: 10px; + font-size: 16px; } } - .other { - text-align: right; - button { - color: $primary-color; - background: transparent; - border: 0; - font-size: 20px; - margin-right: 3rem; - cursor: pointer; + + .controls { + .quantity { + background: $border-color; + padding: 3px; + border-radius: 20px; + margin-bottom: 10px; + + button { + background: $red-color; + border: 0; + border-radius: 50%; + color: $background-color; + padding: 5px; + width: 20px; + height: 20px; + font-size: 12px; + cursor: pointer; + } + + input { + background: transparent; + border: 0; + width: 20px; + padding-left: 10px; + padding-right: 10px; + text-align: center; + align-items: center; + } } - .delete { - margin-left: 30px; + + .other { + text-align: right; + + button { + color: $primary-color; + background: transparent; + border: 0; + font-size: 20px; + margin-right: 3rem; + cursor: pointer; + } + + .delete { + margin-left: 30px; + } } } } @@ -143,113 +197,137 @@ FaCheckSquare { } } } - } - .checkout-details { - flex: 1; - margin: 10px; - .voucher-shipping { - border: 2px solid $border-color; - border-radius: 10px; - padding: 5px; - .box { - p { - color: $black; - font-size: 16px; + + .checkout-details { + flex: 1; + margin: 10px; + + .voucher-shipping { + border: 2px solid $border-color; + border-radius: 10px; + padding: 1rem; + margin-top: 5rem; + + .box { + p { + color: $black; + font-size: 16px; + padding: 1rem; + } + + .info { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + font-size: 14px; + padding: 1.5rem; + border: 2px solid $border-color; + border-radius: 10px; + + .icon { + color: $red-color; + } + + .text { + margin-left: 5px; + } + } + } + } + + .order-details { + border: 2px solid $border-color; + padding: 10px; + border-radius: 10px; + margin-top: 10px; + + h3 { + color: $primary-color; + font-size: 18px; padding: 5px; } - .info { + + .row { display: flex; - flex-direction: row; - flex-wrap: nowrap; - font-size: 14px; - padding: 10px; - border: 2px solid $border-color; - border-radius: 10px; - .icon { - color: $red-color; - } - .text { - margin-left: 5px; + font-weight: 600; + font-size: 16px; + color: $black; + padding: 5px; + + .left { + flex: 1; } } - } - } - .order-details { - border: 2px solid $border-color; - padding: 10px; - border-radius: 10px; - margin-top: 10px; - h3 { - color: $primary-color; - font-size: 18px; - padding: 5px; - } - .row { - display: flex; - font-weight: 600; - font-size: 16px; - color: $black; - padding: 5px; - .left { - flex: 1; + + .last { + border-bottom: 2px solid $border-color; + } + + button { + background: $primary-color; + width: 100%; + border-radius: 5px; + border: none; + color: $white; + padding: 10px; + } - } - .last { - border-bottom: 2px solid $border-color; - } - button { - background: $primary-color; - width: 100%; - border-radius: 5px; - border: none; - color: $white; - padding: 10px; - } } } } + @media only screen and (max-width: 720px) { .cart-section { display: flex; flex-direction: column; padding: 20px; + .cart-products { flex: 2; margin: 10px; + .cart { border: 1px solid $border-color; border-radius: 10px; margin-bottom: 10px; + .title { display: flex; flex-direction: row; flex-wrap: nowrap; border-bottom: 2px solid $border-color; margin: 10px; + .check { margin: 5px; } + h2 { padding-left: 5px; margin-bottom: 10px; font-size: 20px; } } + .products-list { display: flex; flex-direction: column; + .product-box { display: flex; flex-direction: column; padding: 10px; + .check { display: none; } + .image { border: 2px solid $border-color; border-radius: 10px; text-align: center; + img { width: 100%; height: 100%; @@ -257,21 +335,26 @@ FaCheckSquare { text-align: center; } } + .description { flex: 3; padding: 5px; + h4 { font-weight: 500; margin: 5px; margin-bottom: 10px; font-size: 18px; } + .flexer { display: flex; flex-direction: row; flex-wrap: nowrap; + .left { flex: 1; + .discount { background: $icon-color-unopacity; padding: 3px; @@ -280,20 +363,24 @@ FaCheckSquare { margin-bottom: 10px; font-size: 14px; } + .price { margin: 5px; margin-bottom: 10px; font-size: 14px; } } + .controls { display: flex; flex-direction: column; + .quantity { background: $border-color; padding: 3px; border-radius: 20px; margin-bottom: 10px; + button { background: $red-color; border: 0; @@ -305,6 +392,7 @@ FaCheckSquare { font-size: 10px; border: none; } + input { background: transparent; border: 0; @@ -315,8 +403,10 @@ FaCheckSquare { align-items: center; } } + .other { text-align: right; + button { color: $primary-color; background: transparent; @@ -332,18 +422,22 @@ FaCheckSquare { } } } + .checkout-details { flex: 1; margin: 10px; + .voucher-shipping { border: 2px solid $border-color; border-radius: 10px; padding: 5px; + .box { p { color: $black; font-size: 16px; } + .info { display: flex; flex-direction: row; @@ -352,71 +446,55 @@ FaCheckSquare { padding: 10px; border: 2px solid $border-color; border-radius: 10px; + .icon { color: $red-color; } + .text { margin-left: 5px; } } } } + .order-details { border: 2px solid $border-color; padding: 10px; border-radius: 10px; margin-top: 10px; + h3 { color: $primary-color; font-size: 18px; padding: 5px; } + .row { display: flex; font-weight: 600; font-size: 16px; color: $black; padding: 5px; + .left { flex: 1; } } + .last { border-bottom: 2px solid $border-color; } + button { background: $primary-color; width: 100%; border-radius: 5px; color: $white; padding: 10px; - + } } } } -} -.clear-cart { - margin-top: 1rem; - margin-left: 26.5rem; - border: none; - justify-content: center; - align-items: center; - display: flex; - width: 100%; - .delete { - border: none; - background-color: $primary-color; - color: $white; - font-size: 1.5rem; - padding: 1rem; - border-radius: 5px; - display: flex; - cursor: pointer; - } - .deleteIcon { - font-size: 2rem; - margin-right: 1rem; - cursor: pointer; - } -} +} \ No newline at end of file diff --git a/src/assets/styles/liveChat.scss b/src/assets/styles/liveChat.scss new file mode 100644 index 00000000..71d96021 --- /dev/null +++ b/src/assets/styles/liveChat.scss @@ -0,0 +1,456 @@ +.floating-chat-icon { + position: fixed; + bottom: 20px; + right: 20px; + background-color: $primary-color; + border-radius: 50%; + width: 60px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + animation: bounce 2s infinite; + + .chat-icon { + width: 30px; + height: 30px; + fill: white; + transition: fill 0.3s; + } + + .unreadCount { + position: absolute; + top: -5px; + right: -5px; + background-color: red; + color: white; + border-radius: 50%; + width: 20px; + height: 20px; + text-align: center; + line-height: 20px; + font-weight: bold; + font-size: 1.3rem; + border: 3px solid $white-color; + } +} + +@keyframes bounce { + + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-10px); + } +} + +.live-chat { + position: fixed; + bottom: 0; + right: 2rem; + width: 55rem; + height: 65rem; + background-color: $secondary-color-light; + border: none; + border-radius: 10px 10px 0 0; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); + display: flex; + flex-direction: column; + max-height: 100vh; + max-width: 100vw; + overflow: hidden; + z-index: 1000; + + + + &.minimized { + height: 5rem; + width: 39rem; + + .chat-messages, + .chat-input { + display: none; + + + } + + .chat-header { + p { + color: $white-color; + font-weight: bold; + font-size: 1.8rem; + margin: 0; + } + + .chat-controls { + margin: 0; + } + } + } + + .chat-header { + background-color: $primary-color; + padding: 10px; + border-radius: 10px 10px 0 0; + display: flex; + justify-content: space-between; + + p { + margin-left: 2rem; + color: $white-color; + font-weight: bold; + font-size: 1.8rem; + display: flex; + align-items: center; + } + + .chat-controls { + gap: 1rem !important; + } + } + + .chat-messages { + flex: 1; + padding: 10px; + overflow-y: auto; + display: flex; + flex-direction: column; + + .system-message { + text-align: center; + color: #999; + font-style: italic; + } + + .unread-badge-container { + text-align: center; + margin-bottom: 10px; + } + + .unread-badge { + display: inline-block; + padding: 5px 0; + background-color: transparent; + color: $primary-color; + font-weight: bold; + font-size: 12px; + text-transform: uppercase; + + } + + .unread-badge::before, + .unread-badge::after { + content: ""; + display: inline-block; + width: 15rem; + height: 2px; + background-color: $primary-color; + vertical-align: middle; + margin: 0 20px; + } + + .chat-message { + display: flex; + align-items: center; + margin: 1rem .5rem; + max-width: 100%; + position: relative; + + .profile-image { + width: 40px; + height: 40px; + border-radius: 50%; + border: 1px solid $primary-color; + overflow: hidden; + margin-right: 10px; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } + } + + &-right { + flex-direction: row-reverse; + + .profile-image { + margin-left: 10px; + margin-right: 0; + } + + .message-content { + background-color: $primary-color-light; + color: $text-color; + border-radius: 5px 5px 5px 5px; + padding: 5px 15px; + position: relative; + font-size: 2rem; + max-width: 40rem; + right: .9rem; + + .images-container { + display: flex; + + img { + height: 26rem; + width: 25rem; + object-fit: contain; + border: 1px solid $primary-color; + cursor: pointer; + transition: transform 0.2s ease-in-out; + } + + .zoomIn { + position: absolute; + transform: scale(0); + cursor: pointer; + top: 50%; + left: 50%; + z-index: 1; + font-size: 3rem; + color: $primary-color; + } + } + + .imageDisplay img:hover { + transform: scale(1.01); + } + + .imageDisplay:hover .zoomIn { + transform: scale(1); + transition: transform 0.2s ease-in-out; + } + + &:before { + content: ''; + position: absolute; + top: 50%; + right: -19px; + border-width: 10px; + border-style: solid; + border-color: transparent transparent transparent $primary-color-light; + transform: translateY(-50%); + } + } + } + + &-left { + .message-content { + background-color: $third-color; + color: $text-color; + border-radius: 5px 5px 5px 5px; + padding: 5px 15px; + position: relative; + font-size: 2rem; + left: .8rem; + max-width: 40rem; + + + .images-container { + display: flex; + gap: 5px; + + img { + width: 25rem; + height: 26rem; + object-fit: contain; + border: 1px solid $text-color; + cursor: pointer; + transition: transform 0.2s ease-in-out; + } + + .zoomIn { + position: absolute; + transform: scale(0); + cursor: pointer; + top: 50%; + left: 50%; + z-index: 1; + font-size: 3rem; + color: $primary-color; + } + } + + .imageDisplay img:hover { + transform: scale(1.01); + } + + .imageDisplay:hover .zoomIn { + transform: scale(1); + transition: transform 0.2s ease-in-out; + } + + &:before { + content: ''; + position: absolute; + top: 50%; + left: -19px; + border-width: 10px; + border-style: solid; + border-color: transparent $third-color transparent transparent; + transform: translateY(-50%); + } + } + } + + .username { + display: block; + font-weight: bold; + color: $text-color; + margin-bottom: 5px; + font-size: 1.2rem; + opacity: .75; + } + + .timestamp { + display: block; + font-size: 0.65em; + margin-top: 5px; + opacity: 0.7; + color: $text-color; + } + + .unread { + background-color: #f0f0f0; + } + + } + } + + .chat-inputs { + display: flex; + padding: 10px; + border-top: 1px solid #ddd; + flex-direction: column; + + .imagesDiv { + display: flex; + flex-direction: row; + gap: 10px; + overflow-x: auto; + max-width: 100%; + padding: 10px; + box-sizing: border-box; + + .imageDisplay { + position: relative; + width: 15rem; + height: 15rem; + flex: 0 0 auto; + img { + width: 100%; + height: 100%; + border-radius: .5rem; + } + + .closeIcon { + position: absolute; + top: -1rem; + right: -1rem; + color: invert(1); + font-size: 30px; + font-weight: bold; + cursor: pointer; + border: none; + outline: none; + } + + .closeIcon:hover, + .closeIcon:focus { + color: $primary-color; + text-decoration: none; + transform: rotate(180deg); + transition: transform 0.2s ease-in-out; + } + } + } + + + .chat-input { + display: flex; + justify-content: center; + align-items: center; + padding: 10px; + + .input{ + flex: 1; + padding: 1.5rem; + border-radius: 5rem; + border: 1px solid $primary-color; + margin-right: 10px; + font-size: 1.8rem; + height: 2rem; + } + .emoji-picker-container { + position: absolute; + top: 4%; + z-index: 1000; + } + .send-btn { + color: $primary-color; + font-size: 5rem; + cursor: pointer; + } + } + + } + +} + +.modal { + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + overflow: auto; + background-color: rgba(0, 0, 0, 0.8); + z-index: 1000; + display: flex; + justify-content: center; + align-items: center; +} + +.modal-content { + position: relative; + max-width: 100%; + max-height: 100%; + align-items: center; + justify-content: center; +} + +.modal-image { + max-width: 100vw; + max-height: 100vh; + display: block; + width: auto; + height: auto; + margin: auto; +} + +.close { + position: absolute; + top: 10px; + right: 20px; + color: invert(1); + font-size: 30px; + font-weight: bold; + cursor: pointer; + border: none; + outline: none; +} + +.close:hover, +.close:focus { + color: $primary-color; + text-decoration: none; + cursor: pointer; + transform: rotate(90deg); + transition: transform 0.2s ease-in-out; +} \ No newline at end of file diff --git a/src/assets/styles/style.scss b/src/assets/styles/style.scss index 0c27ca08..b7525a0f 100644 --- a/src/assets/styles/style.scss +++ b/src/assets/styles/style.scss @@ -36,6 +36,7 @@ body { ::-webkit-scrollbar { width: 0.2rem; + display: none; } ::-webkit-scrollbar-track { diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index 39074b92..3aac1a15 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -45,7 +45,7 @@ const Header: React.FC = () => { useSocket(); const categories = Array.from({ length: 5 }, (_, i) => i + 1); useEffect(() => { - if (tokenLogin.trim()) { + if (tokenLogin?.trim()) { setToken(tokenLogin); } else { const token = localStorage.getItem('token') || ''; diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 92aa0f32..070c6ecd 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -3,12 +3,14 @@ import React from "react"; import Header from "./Header"; import { Outlet } from "react-router-dom"; import Footer from "./Footer"; +import LiveChat from "../live-chat/LiveChat"; export default function Layout() { return ( <>
+ {/* */}