diff --git a/boxofficefantasy_project/settings.py b/boxofficefantasy_project/settings.py index 1c13048..95ed5ef 100644 --- a/boxofficefantasy_project/settings.py +++ b/boxofficefantasy_project/settings.py @@ -26,7 +26,7 @@ SECRET_KEY = "django-insecure-_rrxhe5i6uqap!52u(1zi8x$820duvf5s_!9!bc4ghbyyktol0 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ["localhost"] +ALLOWED_HOSTS = ["localhost", "kif.local"] # TMDB API KEY TMDB_API_KEY = os.environ.get("TMDB_API_KEY") diff --git a/draft/constants.py b/draft/constants.py index 9b654b4..a308a31 100644 --- a/draft/constants.py +++ b/draft/constants.py @@ -32,6 +32,7 @@ class DraftMessage(StrEnum): BID_START_INFORM = "bid.start.inform" # server -> client (movie, ends_at) BID_START_REQUEST = "bid.start.request" # server -> client (movie, ends_at) BID_PLACE_REQUEST = "bid.place.request" # client -> server (amount) + BID_PLACE_CONFIRM = "bid.update.confirm" # server -> client (high bid) BID_UPDATE_INFORM = "bid.update.inform" # server -> client (high bid) BID_END_INFORM = "bid.end.inform" # server -> client (winner) diff --git a/draft/consumers.py b/draft/consumers.py index c1bdebf..832a93a 100644 --- a/draft/consumers.py +++ b/draft/consumers.py @@ -99,6 +99,7 @@ class DraftConsumerBase(AsyncJsonWebsocketConsumer): return self.user.is_authenticated async def receive_json(self, content): + logger.info(f"receiving message {content}") event_type = content.get("type") if event_type == DraftMessage.STATUS_SYNC_REQUEST: await self.send_json( @@ -206,7 +207,7 @@ class DraftAdminConsumer(DraftConsumerBase): { "type": "broadcast.session", "subtype": DraftMessage.BID_START_INFORM, - "payload": self.get_draft_status(), + "payload": {**self.draft_state}, }, ) @@ -314,6 +315,18 @@ class DraftParticipantConsumer(DraftConsumerBase): }, }, ) + + if event_type == DraftMessage.BID_PLACE_REQUEST: + bid_amount = content.get('payload',{}).get('bid_amount') + self.draft_state.place_bid(self.user, bid_amount) + await self.channel_layer.group_send( + self.group_names.session, + { + "type": "broadcast.session", + "subtype": DraftMessage.BID_PLACE_CONFIRM, + "payload": {**self.draft_state}, + }, + ) # === Broadcast handlers === diff --git a/draft/state.py b/draft/state.py index cf9dd1a..1f5e095 100644 --- a/draft/state.py +++ b/draft/state.py @@ -181,13 +181,15 @@ class DraftStateManager: self.cache.set(self.cache_keys.current_movie, movie_id) self.cache.delete(self.cache_keys.bids) - def place_bid(self, user_id: int, amount: int): + def place_bid(self, user: User, amount: int|str): + if isinstance(amount, str): + amount = int(amount) bids = self.get_bids() - bids[user_id] = amount + bids.append({"user":user.username, "amount":amount}) self.cache.set(self.cache_keys.bids, json.dumps(bids)) def get_bids(self) -> dict: - return json.loads(self.cache.get(self.cache_keys.bids) or "{}") + return json.loads(self.cache.get(self.cache_keys.bids) or "[]") def current_movie(self) -> Movie | None: movie_id = self.cache.get(self.cache_keys.current_movie) @@ -216,7 +218,7 @@ class DraftStateManager: "draft_index": self.draft_index, "connected_participants": self.connected_participants, "current_movie": self.cache.get(self.cache_keys.current_movie), - # "bids": self.get_bids(), + "bids": self.get_bids(), "bidding_timer_end": self.get_timer_end(), "bidding_timer_start": self.get_timer_start(), "current_pick": picks[0] if picks else None, diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5fc2d31..7c08895 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,6 +7,7 @@ "dependencies": { "bootstrap": "^5.3.7", "react": "^18.3.1", + "react-bootstrap": "^2.10.10", "react-dom": "^18.3.1" }, "devDependencies": { @@ -1709,6 +1710,15 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -2221,12 +2231,89 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, + "node_modules/@react-aria/ssr": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", + "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.9.4.tgz", + "integrity": "sha512-N4C7haUc3vn4LTwVUPlkJN8Ach/+yIMvRuTVIhjilNHqegY60SGLrzud6errOMNJwSnmYFnt1J0H/k8FE3A4KA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@popperjs/core": "^2.11.8", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.5.0", + "@types/warning": "^3.0.3", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.4", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/@restart/hooks": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.5.1.tgz", + "integrity": "sha512-EMoH04NHS1pbn07iLTjIjgttuqb7qu4+/EyhAx27MHpoENcB2ZdSsLTNxmKD+WEPnZigo62Qc8zjGnNxoSE/5Q==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -2375,6 +2462,12 @@ "@types/node": "*" } }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", @@ -2389,6 +2482,24 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/react": { + "version": "19.1.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.10.tgz", + "integrity": "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", @@ -2439,6 +2550,12 @@ "@types/node": "*" } }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==", + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -3169,6 +3286,12 @@ "node": ">=6.0" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -3372,6 +3495,12 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3435,6 +3564,15 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -3480,6 +3618,16 @@ "node": ">=6" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4232,6 +4380,15 @@ "node": ">=10.13.0" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ipaddr.js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", @@ -4768,6 +4925,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -5084,6 +5250,30 @@ "dev": true, "license": "MIT" }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "license": "MIT", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -5172,6 +5362,37 @@ "node": ">=0.10.0" } }, + "node_modules/react-bootstrap": { + "version": "2.10.10", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.10.tgz", + "integrity": "sha512-gMckKUqn8aK/vCnfwoBpBVFUGT9SVQxwsYrp9yDHt0arXMamxALerliKBxr1TPbntirK/HGrUAHYbAeQTa9GHQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.7", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.9.4", + "@types/prop-types": "^15.7.12", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -5185,6 +5406,34 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "license": "MIT" + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -6123,7 +6372,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/type-is": { @@ -6140,6 +6388,21 @@ "node": ">= 0.6" } }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, "node_modules/undici-types": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", @@ -6269,6 +6532,15 @@ "node": ">= 0.8" } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/watchpack": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index 1938f1d..10db024 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -18,6 +18,7 @@ "dependencies": { "bootstrap": "^5.3.7", "react": "^18.3.1", + "react-bootstrap": "^2.10.10", "react-dom": "^18.3.1" } } diff --git a/frontend/src/apps/draft/common/ParticipantList.jsx b/frontend/src/apps/draft/common/ParticipantList.jsx index b33f012..ee1363b 100644 --- a/frontend/src/apps/draft/common/ParticipantList.jsx +++ b/frontend/src/apps/draft/common/ParticipantList.jsx @@ -6,8 +6,8 @@ export const ParticipantList = ({ isAdmin, draftState, draftDetails, currentUser const { draft_order, draft_index, connected_participants } = draftState const { participants } = draftDetails - const ListTag = draft_order.length > 0 ? "ol" : "ul" - const listItems = draft_order.length > 0 ? draft_order.map(d => participants.find(p => p.username == d)) : participants + const ListTag = draft_order?.length > 0 ? "ol" : "ul" + const listItems = draft_order?.length > 0 ? draft_order.map(d => participants.find(p => p.username == d)) : participants return ( diff --git a/frontend/src/apps/draft/common/WebSocketStatus.jsx b/frontend/src/apps/draft/common/WebSocketStatus.jsx index 9324233..4ca70d8 100644 --- a/frontend/src/apps/draft/common/WebSocketStatus.jsx +++ b/frontend/src/apps/draft/common/WebSocketStatus.jsx @@ -6,6 +6,9 @@ export const WebSocketStatus = ({ socket }) => { console.log('socket changed', socket) if (!socket) return; + // Set initial state according to readyState + setIsConnected(socket.readyState === 1); + const handleOpen = () => { console.log('socket open'); setIsConnected(true) }; const handleClose = () => { console.log('socket close'); setIsConnected(false) }; const handleError = () => { console.log('socket error'); setIsConnected(false) }; diff --git a/frontend/src/apps/draft/common/utils.js b/frontend/src/apps/draft/common/utils.js index 13c87ac..02ad344 100644 --- a/frontend/src/apps/draft/common/utils.js +++ b/frontend/src/apps/draft/common/utils.js @@ -49,7 +49,8 @@ export const handleDraftStatusMessages = (event, setDraftState) => { bidding_timer_end, bidding_timer_start, current_pick, - next_picks + next_picks, + bids } = payload; if (type == DraftMessage.STATUS_SYNC_INFORM) { @@ -66,6 +67,7 @@ export const handleDraftStatusMessages = (event, setDraftState) => { ...(bidding_timer_end ? { bidding_timer_end: Number(bidding_timer_end) } : {}), ...(current_pick ? { current_pick } : {}), ...(next_picks ? { next_picks } : {}), + ...(bids ? {bids} : {}) })); }; diff --git a/frontend/src/apps/draft/participant/DraftParticipant.jsx b/frontend/src/apps/draft/participant/DraftParticipant.jsx index 8067f65..77d8ce4 100644 --- a/frontend/src/apps/draft/participant/DraftParticipant.jsx +++ b/frontend/src/apps/draft/participant/DraftParticipant.jsx @@ -1,5 +1,5 @@ // DraftAdmin.jsx -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useRef } from "react"; import { useWebSocket } from "../common/WebSocketContext.jsx"; import { WebSocketStatus } from "../common/WebSocketStatus.jsx"; @@ -9,11 +9,13 @@ import { DraftMoviePool } from "../common/DraftMoviePool.jsx"; import { ParticipantList } from "../common/ParticipantList.jsx"; import { DraftCountdownClock } from "../common/DraftCountdownClock.jsx" import { handleDraftStatusMessages } from '../common/utils.js' +// import { Collapse } from 'bootstrap/dist/js/bootstrap.bundle.min.js'; +import { Collapse, ListGroup } from "react-bootstrap"; -const NominateMenu = ({ socket, draftState, draftDetails, currentUser }) => { + +const NominateMenu = ({ socket, draftState, draftDetails, currentUser, }) => { if (!socket || isEmptyObject(draftDetails) || isEmptyObject(draftState)) return; - const currentDrafter = draftState.draft_order[draftState.draft_index] - if (currentUser != currentDrafter) return; + const [open, setOpen] = useState(false); const { movies } = draftDetails const requestNomination = (event) => { @@ -28,21 +30,35 @@ const NominateMenu = ({ socket, draftState, draftDetails, currentUser }) => { })) } + useEffect(() => { + if (isEmptyObject(draftState) || isEmptyObject(draftState.current_pick)) return; + + if (currentUser == draftState.current_pick.participant) { + setOpen(true) + } else { + setOpen(false) + } + + // collapse.toggle() + }, [draftState]) + return ( -