page height#

main
alex 2024-05-30 12:38:26 +02:00
parent c9c07ffa93
commit d100e93b33
16 changed files with 357 additions and 201 deletions

View File

@ -1,70 +1 @@
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
The page will reload when you make changes.\
You may also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
# Product Pipeline

29
iframe.html Normal file
View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<iframe
id="shx-product-pipeline"
style="width: 100%; border: none; height: 1257px"
src="https://shxproductpipeline.ex.umbach.dev/"
title="Produkt Pipeline"
scrolling="no"
onload="
(function() {
function resizeIframe(event) {
if (event.origin == 'https://shxproductpipeline.ex.umbach.dev') {
const iframe = document.getElementById('shx-product-pipeline');
iframe.style.height = event.data + 'px';
}
}
window.addEventListener('message', resizeIframe, false)
})();
"
></iframe>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
public/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
public/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -10,7 +10,7 @@
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Produkt Pipeline</title>
<title>Product Pipeline</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -1,25 +1,20 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "Product Pipeline",
"name": "Product Pipeline by Shinnex",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"theme_color": "#ffffff",
"background_color": "#ffffff"
}

BIN
public/mstile-150x150.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,112 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="2108.000000pt" height="2108.000000pt" viewBox="0 0 2108.000000 2108.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,2108.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M14378 18315 c-1 -1 -55 -5 -118 -9 -118 -6 -204 -13 -300 -22 -30
-3 -73 -7 -95 -9 -53 -5 -156 -17 -175 -20 -8 -2 -42 -6 -75 -10 -33 -3 -132
-18 -220 -32 -88 -14 -169 -27 -180 -28 -11 -2 -31 -6 -45 -8 -14 -3 -50 -11
-80 -16 -428 -84 -785 -199 -983 -317 -73 -44 -278 -174 -292 -186 -5 -5 -84
-61 -175 -125 -91 -64 -167 -119 -170 -123 -3 -3 -57 -43 -120 -90 -63 -47
-117 -87 -120 -90 -3 -3 -45 -37 -95 -75 -92 -70 -273 -215 -331 -264 -9 -8
-57 -48 -108 -90 -50 -42 -104 -88 -121 -103 -16 -15 -41 -36 -55 -48 -186
-160 -354 -328 -409 -408 -148 -218 -276 -614 -307 -943 -3 -41 -8 -77 -10
-80 -5 -8 -17 -251 -17 -344 0 -109 12 -288 23 -355 5 -30 12 -75 15 -100 4
-24 8 -47 10 -51 2 -3 7 -21 10 -40 10 -57 55 -181 88 -244 17 -33 57 -85 88
-116 45 -45 68 -59 108 -69 56 -13 134 -8 185 14 72 30 126 136 142 281 3 28
8 64 10 80 3 17 7 241 9 499 l5 469 22 18 c22 17 305 230 364 274 21 16 534
402 644 485 695 526 825 604 917 557 38 -20 64 -74 103 -215 17 -59 35 -122
41 -140 29 -89 5 -130 -82 -138 -107 -11 -196 -53 -334 -161 -16 -13 -35 -27
-40 -31 -38 -27 -169 -146 -275 -249 -69 -67 -143 -136 -165 -153 -53 -42
-148 -90 -179 -90 -14 0 -36 -4 -49 -9 -57 -22 -73 -64 -81 -206 -7 -111 -41
-190 -95 -217 -76 -38 -108 -95 -93 -165 10 -43 8 -66 -10 -132 -8 -33 -31
-64 -90 -125 -110 -115 -111 -122 -23 -346 65 -168 65 -167 71 -212 8 -54 -9
-96 -67 -164 -28 -32 -59 -77 -69 -98 -23 -49 -19 -118 9 -181 48 -109 46
-224 -8 -377 -63 -181 -216 -427 -411 -662 -19 -24 -53 -64 -75 -91 -113 -138
-218 -248 -470 -500 -198 -198 -387 -379 -474 -455 -47 -40 -154 -135 -170
-151 -13 -13 -168 -146 -261 -225 -14 -12 -59 -50 -100 -86 -124 -106 -451
-373 -665 -541 -110 -87 -212 -168 -227 -180 -15 -12 -39 -31 -54 -42 -15 -11
-59 -45 -98 -76 -39 -30 -201 -153 -361 -273 -159 -119 -298 -223 -308 -231
-9 -8 -21 -15 -26 -15 -5 0 -11 -4 -13 -9 -3 -8 -110 -88 -284 -210 -27 -19
-51 -37 -54 -41 -19 -22 -392 -274 -580 -392 -244 -152 -647 -368 -865 -462
-22 -10 -51 -24 -65 -31 -87 -45 -466 -193 -660 -258 -228 -76 -560 -165 -735
-196 -33 -6 -71 -13 -85 -16 -60 -13 -318 -45 -408 -52 -138 -10 -387 -6 -479
7 -43 6 -89 13 -103 15 -119 17 -294 82 -382 143 -338 233 -249 675 247 1231
167 187 494 487 640 586 27 19 82 56 120 83 122 83 315 197 535 317 126 69
1198 600 1545 766 56 27 346 178 430 224 138 76 331 183 362 201 17 11 80 48
140 84 59 36 114 66 121 68 6 2 12 7 12 12 0 4 8 10 18 13 20 7 226 143 367
244 118 83 276 205 366 283 70 60 324 311 379 375 243 280 453 648 494 865 15
78 12 116 -13 150 -16 21 -27 25 -69 25 -63 -1 -136 -47 -234 -146 -74 -75
-109 -121 -221 -286 -188 -280 -340 -452 -563 -644 -239 -206 -480 -361 -854
-551 -167 -85 -323 -157 -515 -238 -109 -46 -159 -67 -190 -81 -47 -21 -537
-209 -544 -209 -5 0 -26 -8 -47 -17 -22 -9 -43 -18 -49 -19 -14 -3 -316 -113
-340 -124 -11 -5 -87 -34 -170 -65 -82 -31 -161 -61 -175 -67 -14 -6 -34 -14
-45 -19 -257 -106 -395 -164 -458 -193 -43 -20 -80 -36 -82 -36 -22 0 -551
-264 -745 -372 -366 -204 -731 -455 -990 -683 -65 -57 -306 -300 -350 -354
-25 -29 -50 -59 -55 -65 -16 -17 -109 -138 -127 -166 -10 -14 -35 -51 -58 -84
-22 -32 -40 -60 -40 -62 0 -2 -16 -28 -35 -58 -32 -50 -153 -291 -182 -361
-73 -179 -144 -423 -178 -610 -39 -216 -50 -348 -50 -600 0 -240 6 -307 42
-505 30 -170 113 -400 200 -559 31 -57 127 -206 143 -221 3 -3 17 -21 31 -40
56 -75 227 -239 324 -312 28 -21 55 -41 60 -45 39 -32 170 -111 266 -161 281
-150 621 -257 1076 -341 63 -12 153 -38 172 -50 25 -16 4 -38 -69 -77 -110
-57 -196 -147 -255 -265 -74 -146 -97 -314 -64 -464 39 -178 134 -274 269
-270 87 2 138 43 174 137 20 54 64 101 121 130 81 42 190 66 292 64 70 -1 77
-3 96 -27 16 -23 19 -42 18 -120 0 -52 -3 -112 -6 -134 -11 -79 -13 -341 -4
-400 20 -125 71 -228 130 -264 64 -39 149 -7 217 82 41 54 122 192 122 208 0
5 4 9 9 9 5 0 14 14 21 30 7 17 16 30 21 30 4 0 10 9 14 19 11 36 152 168 207
195 179 88 325 -25 374 -289 40 -214 48 -244 84 -317 31 -62 37 -70 84 -106
54 -41 128 -24 192 46 72 78 151 275 179 442 16 96 66 221 99 249 52 43 354
-130 503 -288 24 -24 43 -49 44 -55 7 -88 20 -131 51 -167 78 -89 223 -77 335
27 39 36 99 136 117 194 5 14 10 30 11 35 47 144 63 322 38 425 -7 30 -15 64
-17 76 -2 11 -21 53 -41 93 -45 91 -133 180 -238 241 -42 24 -79 50 -81 57 -3
8 9 15 32 20 64 14 781 6 1172 -12 47 -2 150 -6 230 -9 80 -4 172 -8 205 -11
33 -2 110 -7 170 -10 61 -3 130 -8 155 -10 25 -2 83 -6 130 -10 47 -3 96 -8
110 -10 14 -2 54 -7 90 -10 76 -7 110 -28 126 -75 15 -44 1 -89 -43 -139 -50
-59 -109 -88 -260 -127 -361 -92 -574 -252 -659 -494 -34 -97 -24 -264 25
-402 78 -223 178 -308 296 -252 19 9 76 57 127 107 151 148 278 200 688 281
104 20 231 49 315 72 152 41 161 41 178 7 19 -36 26 -82 32 -207 10 -209 20
-289 50 -421 25 -107 93 -252 146 -309 138 -150 298 -93 417 150 38 76 73 204
122 440 26 129 50 237 53 240 5 5 8 3 261 -240 233 -223 236 -226 331 -300
264 -208 519 -270 623 -152 95 108 71 300 -74 603 -62 129 -66 153 -29 153 22
0 161 -49 239 -85 102 -46 223 38 277 193 48 134 19 358 -68 537 -88 179 -185
247 -380 264 -212 19 -304 53 -519 194 -51 33 -93 62 -91 63 4 4 80 13 162 19
44 4 96 8 115 10 19 2 76 6 125 10 50 4 104 8 120 11 17 2 68 6 115 9 47 3
101 8 120 10 19 3 85 7 145 11 61 3 126 7 145 9 32 2 208 12 375 21 475 25
1273 24 1410 -1 41 -8 85 -25 116 -46 14 -10 46 -23 70 -28 118 -27 206 107
163 247 -16 53 -36 82 -145 210 -42 49 -106 132 -142 183 -136 195 -186 225
-387 233 -168 7 -253 27 -292 70 -27 29 -30 52 -12 88 38 74 149 153 387 277
86 45 174 91 195 103 20 11 65 36 100 55 87 47 224 131 306 187 156 107 229
125 283 71 7 -7 26 -55 44 -106 49 -147 138 -312 279 -524 234 -350 290 -470
260 -560 -7 -20 -39 -64 -72 -98 -74 -77 -106 -137 -128 -247 -69 -339 117
-699 343 -663 43 7 92 51 106 97 6 17 12 59 15 94 5 74 31 124 66 129 14 2 36
5 50 7 14 2 58 14 98 26 106 32 120 16 127 -159 5 -112 6 -120 25 -191 43
-161 168 -313 265 -321 91 -7 134 33 169 156 72 248 250 357 439 267 100 -47
177 -134 258 -289 63 -120 99 -172 167 -238 154 -152 326 -131 417 50 20 38
38 83 41 99 3 16 7 32 9 36 10 16 18 142 20 295 1 141 4 169 16 167 16 -4 289
-140 304 -152 6 -4 28 -18 50 -30 86 -47 235 -163 332 -257 136 -132 172 -144
283 -87 133 67 204 219 196 415 -16 361 -290 744 -581 809 -27 6 -84 13 -127
15 -127 6 -220 31 -283 76 -51 38 -166 82 -280 107 -297 68 -350 83 -419 117
-151 75 -282 235 -458 565 -20 36 -52 97 -73 135 -150 276 -337 690 -360 795
-2 8 -13 49 -24 90 -38 141 -52 246 -51 385 1 90 2 104 15 205 15 126 101 413
165 555 51 114 138 381 156 480 45 255 50 602 17 1185 -9 157 -9 300 0 365 3
28 9 68 12 90 8 55 41 176 72 260 47 128 198 412 225 423 4 2 8 8 8 13 0 12
114 162 205 269 38 45 326 333 385 385 136 121 265 224 444 357 72 53 142 105
156 116 29 22 153 105 440 295 217 144 314 211 420 289 77 57 76 56 116 88 17
14 48 39 69 55 148 114 345 305 436 420 172 219 269 436 304 680 2 17 7 47 10
69 3 21 8 116 10 210 5 159 8 206 21 296 9 65 34 140 51 152 9 7 39 35 66 62
116 114 241 479 342 1001 10 55 44 259 49 300 3 22 8 57 11 78 10 72 14 103
20 167 3 36 8 83 11 105 2 22 6 135 8 250 5 305 -15 417 -95 536 -156 232
-547 451 -1031 578 -178 47 -310 71 -538 97 -86 10 -406 10 -495 1 -152 -17
-256 -42 -395 -98 -167 -67 -355 -118 -490 -134 -30 -3 -68 -9 -85 -11 -115
-20 -442 -5 -580 25 -92 21 -224 70 -245 91 -11 11 -127 85 -165 106 -135 73
-426 169 -575 189 -25 3 -52 8 -60 10 -8 2 -51 7 -95 11 -44 3 -89 9 -100 11
-22 6 -711 14 -717 8z m2487 -1651 c44 -21 83 -94 67 -128 -14 -31 -70 -45
-159 -42 -115 5 -154 45 -112 115 36 60 137 87 204 55z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -20,6 +20,7 @@
font-size: 40px;
font-weight: bold;
margin: 0;
padding-top: 12px;
}
.cards-container {
@ -34,14 +35,13 @@
gap: 12px;
padding: 20px;
width: 100%;
max-width: 400px;
max-width: 800px;
}
.card {
background-color: #fff;
padding: 16px 20px;
border-radius: 40px;
/* text-align: left; */
}
.card span {

View File

@ -22,6 +22,28 @@ function SkeletonPlaceholder() {
);
}
function ShowMoreButton({ onClick }) {
return (
<Flex justify="center">
<button
onClick={onClick}
style={{
backgroundColor: "#af9363",
color: "#fff",
borderRadius: 40,
padding: "11.5px 19px",
border: "none",
cursor: "pointer",
fontSize: "16px",
letterSpacing: "1.2px",
}}
>
Alle anzeigen
</button>
</Flex>
);
}
function UseVoteLocalStorage() {
const getVotes = () => {
const votes = localStorage.getItem("shx-product-pipeline-votes");
@ -127,9 +149,12 @@ function VoteRequest(name, up) {
function App() {
const { votes, vote, setVotes } = UseVoteLocalStorage();
const votesRef = useRef(votes);
const pageHeightRef = useRef(0);
useEffect(() => {
votesRef.current = votes;
sendPageHeightToIframe();
}, [votes]);
const [products, setProducts] = useState({
@ -138,6 +163,15 @@ function App() {
FutureProducts: [],
});
const [showMore, setShowMore] = useState({
newProducts: false,
inWorkProducts: false,
futureProducts: false,
});
// update page height on click on show more button
useEffect(() => sendPageHeightToIframe(), [showMore]);
useEffect(() => {
const fetchProducts = () =>
fetch("https://devdash.ex.umbach.dev/api/v1/productpipeline")
@ -156,9 +190,19 @@ function App() {
fetchProducts();
setInterval(() => fetchProducts(), 3000);
setInterval(() => fetchProducts(), 5000);
}, []);
// function to send the height to the iframe
function sendPageHeightToIframe() {
const height = document.body.scrollHeight;
if (pageHeightRef.current === height) return;
pageHeightRef.current = height;
window.parent.postMessage(height, "*");
}
return (
<div className="app">
<div className="container" style={{ paddingTop: 20 }}>
@ -169,20 +213,33 @@ function App() {
<div className="cards">
{products.NewProducts.length > 0 ? (
<>
{products.NewProducts.map((product, index) => (
<Card
key={index}
name={product.Name}
productVariant={product.Variant}
productCharacteristics={product.Characteristics}
rightComponent={
<RightOutlined
style={{ fontSize: 18 }}
onClick={() => window.open(product.Url)}
{products.NewProducts.map(
(product, index) =>
(showMore.newProducts || index < 5) && (
<Card
key={index}
name={product.Name}
productVariant={product.Variant}
productCharacteristics={product.Characteristics}
rightComponent={
<RightOutlined
style={{ fontSize: 18 }}
onClick={() => window.open(product.Url)}
/>
}
/>
)
)}
{products.NewProducts.length > 5 && !showMore.newProducts && (
<ShowMoreButton
onClick={() =>
setShowMore((sM) => {
return { ...sM, newProducts: true };
})
}
/>
))}
)}
</>
) : (
<SkeletonPlaceholder />
@ -197,15 +254,29 @@ function App() {
<div className="cards">
{products.InWorkProducts.length > 0 ? (
<>
{products.InWorkProducts.map((product, index) => (
<Card
key={index}
name={product.Name}
productVariant={product.Variant}
productCharacteristics={product.Characteristics}
rightComponent={<Badge status="processing" />}
/>
))}
{products.InWorkProducts.map(
(product, index) =>
(showMore.inWorkProducts || index < 5) && (
<Card
key={index}
name={product.Name}
productVariant={product.Variant}
productCharacteristics={product.Characteristics}
rightComponent={<Badge status="processing" />}
/>
)
)}
{products.InWorkProducts.length > 5 &&
!showMore.inWorkProducts && (
<ShowMoreButton
onClick={() =>
setShowMore((sM) => {
return { ...sM, inWorkProducts: true };
})
}
/>
)}
</>
) : (
<SkeletonPlaceholder />
@ -225,102 +296,120 @@ function App() {
a.Name.localeCompare(b.Name)
)*/
.sort((a, b) => b.Votes - a.Votes)
.map((product, index) => (
<motion.div
key={product.Name}
layout
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<Card
name={product.Name}
rankingPosition={index + 1}
productVariant={product.Variant}
productCharacteristics={product.Characteristics}
rightComponent={
<div style={{ display: "flex", gap: 12 }}>
<DislikeOutlined
style={{
color:
votes.findIndex(
(vote) =>
vote.n === product.Name && vote.t === 0
) > -1
? "red"
: "#000",
}}
onClick={() => {
if (
votes.findIndex(
(vote) =>
vote.n === product.Name && vote.t === 0
) === -1
) {
VoteRequest(product.Name, false);
vote(product.Name, false);
.map(
(product, index) =>
(showMore.futureProducts || index < 5) && (
<motion.div
key={product.Name}
layout
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<Card
name={product.Name}
rankingPosition={index + 1}
productVariant={product.Variant}
productCharacteristics={product.Characteristics}
rightComponent={
<div style={{ display: "flex", gap: 12 }}>
<DislikeOutlined
style={{
color:
votes.findIndex(
(vote) =>
vote.n === product.Name &&
vote.t === 0
) > -1
? "red"
: "#000",
}}
onClick={() => {
if (
votes.findIndex(
(vote) =>
vote.n === product.Name &&
vote.t === 0
) === -1
) {
VoteRequest(product.Name, false);
vote(product.Name, false);
// simulate vote before request is made
setProducts((products) => {
const newArr = products.FutureProducts.map(
(p) =>
p.Name === product.Name
? { ...p, Votes: p.Votes - 1 }
: p
);
// simulate vote before request is made
setProducts((products) => {
const newArr =
products.FutureProducts.map((p) =>
p.Name === product.Name
? { ...p, Votes: p.Votes - 1 }
: p
);
return {
...products,
FutureProducts: newArr,
};
});
}
}}
/>
<span>{product.Votes}</span>
<LikeOutlined
style={{
color:
votes.findIndex(
(vote) =>
vote.n === product.Name && vote.t === 1
) > -1
? "green"
: "#000",
}}
onClick={() => {
if (
votes.findIndex(
(vote) =>
vote.n === product.Name && vote.t === 1
) === -1
) {
VoteRequest(product.Name, true);
vote(product.Name, true);
return {
...products,
FutureProducts: newArr,
};
});
}
}}
/>
<span>{product.Votes}</span>
<LikeOutlined
style={{
color:
votes.findIndex(
(vote) =>
vote.n === product.Name &&
vote.t === 1
) > -1
? "green"
: "#000",
}}
onClick={() => {
if (
votes.findIndex(
(vote) =>
vote.n === product.Name &&
vote.t === 1
) === -1
) {
VoteRequest(product.Name, true);
vote(product.Name, true);
// simulate vote before request is made
setProducts((products) => {
const newArr = products.FutureProducts.map(
(p) =>
p.Name === product.Name
? { ...p, Votes: p.Votes + 1 }
: p
);
// simulate vote before request is made
setProducts((products) => {
const newArr =
products.FutureProducts.map((p) =>
p.Name === product.Name
? { ...p, Votes: p.Votes + 1 }
: p
);
return {
...products,
FutureProducts: newArr,
};
});
}
}}
/>
</div>
}
/>
</motion.div>
))}
return {
...products,
FutureProducts: newArr,
};
});
}
}}
/>
</div>
}
/>
</motion.div>
)
)}
{products.FutureProducts.length > 5 &&
!showMore.futureProducts && (
<ShowMoreButton
onClick={() =>
setShowMore((sM) => {
return { ...sM, futureProducts: true };
})
}
/>
)}
</>
) : (
<SkeletonPlaceholder />