Skip to content

Alex+Ryan/Add Lockout Period - #563

Draft
alexappleget wants to merge 34 commits into
developfrom
Alex+Ryan/add-lockout-period
Draft

Alex+Ryan/Add Lockout Period#563
alexappleget wants to merge 34 commits into
developfrom
Alex+Ryan/add-lockout-period

Conversation

@alexappleget

@alexappleget alexappleget commented Sep 25, 2024

Copy link
Copy Markdown
Contributor

Closes #525

Took over Ryan's task and cherry picked his commits over.

  • Added lockout period to disable pick buttons and then added lockout to the onWeeklyPickChange api function to throw a notification error saying picks are locked.

UPDATE: Created a custom useHook for the lockout period as useLockout()

Everything works as it should. With this new useHook, you can import the useLockout hook anywhere and just do const lockedOut = useLockout() and it'll know if lockedOut is true or false.

image
image
image
image
image

@appwrite

appwrite Bot commented Sep 25, 2024

Copy link
Copy Markdown

Gridiron Survivor Application 6616ea581ef9f5521c7d

Function ID Status Action
Your function has been successfully deployed.

Project name: Gridiron Survivor Application
Project ID: 6616ea581ef9f5521c7d

Function ID Status Action
userAuth 6626fef885a9f630442b ready Ready View Logs

Only deployments on the production branch are activated automatically. If you'd like to activate this deployment, navigate to your deployments. Learn more about Appwrite Function deployments.

💡 Did you know?
You can use Avatars API to generate QR code for any text or URLs

@vercel

vercel Bot commented Sep 25, 2024

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
gridiron-survivor ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 15, 2024 11:27pm
gridiron-survivor-storybook ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 15, 2024 11:27pm

Comment thread app/(main)/league/[leagueId]/entry/[entryId]/week/Week.tsx Outdated
Comment thread app/(main)/league/[leagueId]/entry/[entryId]/week/Week.tsx Outdated
/>
</Link>
<LinkCustom
aria-disabled={isLockedOut === true ? 'true' : 'false'}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexappleget This was a question previously brought up on my PR. Chris had suggested removing isLockedOut as a prop from the parent component, settings the default state to false, and seeing if that would allow us to remove the truthy/falsy values.

The truthy/falsy values being isLockedOut === true

So instead it could be rewritten as a true ternary: aria-disabled={isLockedOut ? 'true' : 'false'}

Comment thread components/LeagueEntries/LeagueEntries.tsx

checkLockout();

const intervalId = setInterval(checkLockout, 60 * 60 * 1000);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexappleget that is correct.

/>
</Link>
<LinkCustom
aria-disabled={isLockedOut === true ? 'true' : 'false'}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Danielle254 Yes, I too agree. That is how I originally tried developing it but it was not working as intended.

As per my previous comment, @chris-nowicki thought this may be to it being in the parent component as a prop.

await onWeeklyPickChange(params);
setUserPick(teamSelect);
router.push(`/league/${league}/entry/all`);
if (lockedOut) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to nest this if statement in the try block?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. So what it does is run the api functions inside the try block. But, if its during the lockdown period it will block the api functions from running and instead run the toast notification. It is a way to stop hackers from hitting the api's when they shouldn't.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@braydoncoyer please let me know if you need more info on this

@braydoncoyer braydoncoyer Oct 23, 2024

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexappleget @ryandotfurrer Yep, I get the purpose of the Try block. I think I was more asking if the try block could be moved inside the conditional to better represent which part of the code may cause/throw an error.

I'll leave this as a nit because as-is this likely works. However, I'm always a big fan of being more specific about which part of the code may need to have errors caught.

if (lockedOut) {
  ... code
} else {
  try {
    await onWeeklyPickChange(params);
    setUserPick(teamSelect);
    ...
  } catch (error) {
   ...
  }
  console.error(params);
}

Comment thread hooks/useLockout.test.ts Outdated
afterEach(() => {
getUTCDaySpy.mockRestore();
getUTCHoursSpy.mockRestore();
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we get a newline here? If Prettier or another formatter is run in a pipeline, feel free to ignore.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@braydoncoyer done and will be reflected in the next push.

Comment thread hooks/useLockout.ts Outdated
* Function to constantly check the current time every hour and set the lockout accordingly.
* @returns - The value of lockedOut.
*/
const useLockout = (): boolean => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this hook returns a binary value to indicate a user's ability to perform a task, would a more specific name be effective?

Ex: useIsUserLockedOut

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually like this name. I moreso just used useLockout to match everything. I'll change it :)

@ryanfurrer ryanfurrer Oct 14, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@braydoncoyer this has been updated by @alexappleget. Please resolve this convo when you can; thanks!

Comment thread hooks/useLockout.ts Outdated
const day = currentDateAndTime.getUTCDay();
const hours = currentDateAndTime.getUTCHours();
if (
(day === 5 && hours >= 0) || // Thursday at 9pm EST

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we care about time zones? I'm still ramping up and this may be a well-known answer but one I think is worth me asking.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these numbers are UTC time which is 4 hours ahead of me. I left the comments for easy visual understanding. It handles when the lockdown period is.

@ryanfurrer ryanfurrer Oct 14, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we care about time zones? I'm still ramping up and this may be a well-known answer but one I think is worth me asking.

@braydoncoyer I used UTC so we don't have to worry about time zones. I only left the comments in there for reference, like Alex said.

Not to mention, however, that Appwrite also uses UTC. So if we need to tie this in with that we don't need to make changes again.

Comment thread hooks/useLockout.ts
day === 1 || // Monday
(day === 2 && hours < 12) // Tuesday at 9am EST
) {
setLockedOut(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we may be updating this state regardless if the value has changed.

I wonder if a check could be made to ensure we only update state if the value has changed.

      const isLockedOut =
        (day === 5 && hours >= 0) || // Thursday at 9pm EST
        day > 5 || // Friday and Saturday
        day === 0 || // Sunday
        day === 1 || // Monday
        (day === 2 && hours < 12); // Tuesday at 9am EST

      if (isLockedOut !== lockedOut) {
        setLockedOut(isLockedOut);
      }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize that I dont follow. When Ryan made this function, it is to handle the buttons being disabled, etc. During the specific days/times itll keep lockedOut as true which will lock everything down. Then outside of those days/times itll have it set to false which will unlock everything for users to use. And with the interval it checks the time every hour.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@braydoncoyer like @alexappleget said, this is simply checking several statements and, if any of them are true, it will change the state. Are you saying you think this is changing the state multiple times?

Below is a screenshot of what it is achieving; notice the user cannot click and the links are disabled.
CleanShot 2024-10-14 at 17 31 46@2x

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryandotfurrer Thanks for the clarification!

My original comment could have been more clear. I think that we may set state to a value (let's say true) even if the value is already true. This seems redundant. It may not actually work like this -- I'd have to pull down and test locally, but perhaps you know the answer off the top of your head!

Comment thread components/LeagueEntries/LeagueEntries.tsx
Comment thread hooks/useIsUserLockedOut.ts Outdated
const day = currentDateAndTime.getUTCDay();
const hours = currentDateAndTime.getUTCHours();
if (
(day === 5 && hours >= 0) || // Thursday at 9pm EST

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have the other change to not allow picks if a game has been played, let's update the lockdown period to Sat midnight. 95% of the NFL games are on Sun/Mon.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated in latest commit

*/
const useIsUserLockedOut = (): boolean => {
const [lockedOut, setLockedOut] = useState<boolean>(false);
useEffect(() => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this have to be a useEffect?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a useEffect as it is sets up the setInterval which checks the time every hour.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why is it needed? Looks like the code can function without it. useEffects will cause unnecessary re-renders if one uses it incorrectly. Figure out if the code needs it, and if it renders too many times.


checkLockout();

const intervalId = setInterval(checkLockout, 60 * 60 * 1000);

@shashilo shashilo Oct 14, 2024

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, what is 60, 60, and 1000? Put these into CONST instead, so anyone can read and understand what each value means. Also, what's the reasoning behind useing setInterval?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

60 * 60 * 1000 creates a setInterval that checks the time once per hour. The reasoning behind the setInterval is so that it checks the time every hour and can appropriately update the state of setLockedOut.

What do you mean by COST?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a long week. I meant CONST. A constant variable. What represents these individual numbers?

await onWeeklyPickChange(params);
setUserPick(teamSelect);
router.push(`/league/${league}/entry/all`);
if (lockedOut) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any new unit tests for this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add these in ASAP.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shashilo can you elaborate what test exactly you're looking for?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a conditional statement, so you need to have a positive and negative unit tests for this. Checking that both conditions are accurate when their conditions are met.

@ryanfurrer ryanfurrer self-assigned this Oct 14, 2024
*/
const useIsUserLockedOut = (): boolean => {
const [lockedOut, setLockedOut] = useState<boolean>(false);
useEffect(() => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why is it needed? Looks like the code can function without it. useEffects will cause unnecessary re-renders if one uses it incorrectly. Figure out if the code needs it, and if it renders too many times.


checkLockout();

const intervalId = setInterval(checkLockout, 60 * 60 * 1000);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a long week. I meant CONST. A constant variable. What represents these individual numbers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add lockout period where users cannot make picks

6 participants