Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alex+Ryan/Add Lockout Period #563

Draft
wants to merge 34 commits into
base: develop
Choose a base branch
from

Conversation

alexappleget
Copy link
Contributor

@alexappleget alexappleget commented Sep 25, 2024

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

Copy link

appwrite bot commented Sep 25, 2024

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

Copy link

vercel bot commented Sep 25, 2024

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

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

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
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
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

Copy link

@braydoncoyer braydoncoyer Oct 23, 2024

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);
}

afterEach(() => {
getUTCDaySpy.mockRestore();
getUTCHoursSpy.mockRestore();
})

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
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.

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

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
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 :)

Copy link
Member

@ryandotfurrer ryandotfurrer Oct 14, 2024

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!

const day = currentDateAndTime.getUTCDay();
const hours = currentDateAndTime.getUTCHours();
if (
(day === 5 && hours >= 0) || // Thursday at 9pm EST

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
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.

Copy link
Member

@ryandotfurrer ryandotfurrer Oct 14, 2024

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.

day === 1 || // Monday
(day === 2 && hours < 12) // Tuesday at 9am EST
) {
setLockedOut(true);

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
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
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

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!

components/LeagueEntries/LeagueEntries.tsx Show resolved Hide resolved
const day = currentDateAndTime.getUTCDay();
const hours = currentDateAndTime.getUTCHours();
if (
(day === 5 && hours >= 0) || // Thursday at 9pm EST
Copy link
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
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
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
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
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
Collaborator

@shashilo shashilo Oct 14, 2024

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
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
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
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
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
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
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.

@ryandotfurrer ryandotfurrer self-assigned this Oct 14, 2024
*/
const useIsUserLockedOut = (): boolean => {
const [lockedOut, setLockedOut] = useState<boolean>(false);
useEffect(() => {
Copy link
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
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