-
Notifications
You must be signed in to change notification settings - Fork 1
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
ui/ux: update week page #370
Changes from 9 commits
393e5bc
af1912a
de0ec33
068aad8
0ffdec6
6021a54
1995b8c
31b1a58
7c086e9
37e9f5a
ab7cfea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ | |
|
||
'use client'; | ||
import React, { JSX, useEffect, useState } from 'react'; | ||
import { Button } from '@/components/Button/Button'; | ||
import { | ||
FormField, | ||
FormItem, | ||
|
@@ -18,6 +17,10 @@ import { parseUserPick } from '@/utils/utils'; | |
import { zodResolver } from '@hookform/resolvers/zod'; | ||
import { useDataStore } from '@/store/dataStore'; | ||
import { ISchedule } from './WeekTeams.interface'; | ||
import LinkCustom from '@/components/LinkCustom/LinkCustom'; | ||
import { ChevronLeft } from 'lucide-react'; | ||
import { getCurrentLeague } from '@/api/apiFunctions'; | ||
import { ILeague } from '@/api/apiFunctions.interface'; | ||
import WeekTeams from './WeekTeams'; | ||
|
||
/** | ||
|
@@ -28,12 +31,22 @@ import WeekTeams from './WeekTeams'; | |
// eslint-disable-next-line no-unused-vars | ||
const Week = ({ entry, league, NFLTeams, week }: IWeekProps): JSX.Element => { | ||
const [schedule, setSchedule] = useState<ISchedule[]>([]); | ||
const [selectedLeague, setSelectedLeague] = useState<ILeague | undefined>(); | ||
const [isLoading, setIsLoading] = useState<boolean>(true); | ||
const [userPick, setUserPick] = useState<string>(''); | ||
|
||
const { user, updateWeeklyPicks, weeklyPicks } = useDataStore( | ||
(state) => state, | ||
); | ||
|
||
/** | ||
* Fetches the selected league. | ||
* @returns {Promise<void>} | ||
*/ | ||
const getSelectedLeague = async (): Promise<void> => { | ||
const res = await getCurrentLeague(league); | ||
setSelectedLeague(res); | ||
}; | ||
|
||
const NFLTeamsList = NFLTeams.map((team) => team.teamName) as [ | ||
string, | ||
...string[] | ||
|
@@ -73,12 +86,14 @@ const Week = ({ entry, league, NFLTeams, week }: IWeekProps): JSX.Element => { | |
* @param data - The form data. | ||
* @returns {void} | ||
*/ | ||
const onSubmit = async (data: z.infer<typeof FormSchema>): Promise<void> => { | ||
const onWeeklyPickChange = async ( | ||
data: React.ChangeEvent<HTMLSelectElement>, | ||
): Promise<void> => { | ||
try { | ||
const teamSelect = data.type.toLowerCase(); | ||
const teamSelect = data.target.value; | ||
const teamID = NFLTeams.find( | ||
(team) => team.teamName.toLowerCase() === teamSelect, | ||
)?.teamId; | ||
(team) => team.teamName === teamSelect, | ||
)?.teamName; | ||
|
||
const currentUserPick = parseUserPick(user.id, entry, teamID || ''); | ||
|
||
|
@@ -110,44 +125,59 @@ const Week = ({ entry, league, NFLTeams, week }: IWeekProps): JSX.Element => { | |
}; | ||
|
||
useEffect(() => { | ||
if (!selectedLeague) { | ||
getSelectedLeague(); | ||
return; | ||
} | ||
getSchedule(week); | ||
}, [week]); | ||
setIsLoading(false); | ||
}, [week, selectedLeague]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By adding |
||
|
||
if (schedule.length === 0) { | ||
if (schedule.length === 0 || isLoading) { | ||
return <p>Loading...</p>; | ||
} | ||
|
||
return ( | ||
<section className="w-full pt-8" data-testid="weekly-picks"> | ||
<h1 className="pb-8 text-center text-[2rem] font-bold text-white"> | ||
Your pick sheet | ||
</h1> | ||
|
||
<FormProvider {...form}> | ||
<form | ||
className="mx-auto flex w-[90%] max-w-3xl flex-col items-center gap-8" | ||
onSubmit={form.handleSubmit(onSubmit)} | ||
<div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No to classess Div's. This should have a class that matches the component name. |
||
<nav className="py-6 text-orange-500 hover:no-underline"> | ||
<LinkCustom | ||
className="text-orange-500 flex gap-3 items-center font-semibold text-xl hover:no-underline" | ||
href="/league/all" | ||
> | ||
<FormField | ||
control={form.control as Control<object>} | ||
name="type" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormControl> | ||
<WeekTeams | ||
schedule={schedule} | ||
field={field} | ||
userPick={userPick} | ||
/> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button label="Submit Button" type="submit" /> | ||
</form> | ||
</FormProvider> | ||
</section> | ||
<span aria-hidden="true"> | ||
<ChevronLeft size={16} /> | ||
</span> | ||
{selectedLeague?.leagueName as string} | ||
</LinkCustom> | ||
</nav> | ||
<section className="w-full pt-8" data-testid="weekly-picks"> | ||
<h1 className="pb-8 text-center text-[2rem] font-bold text-white"> | ||
Week {week} pick | ||
</h1> | ||
|
||
<FormProvider {...form}> | ||
<form className="mx-auto flex w-[90%] max-w-3xl flex-col items-center"> | ||
<FormField | ||
control={form.control as Control<object>} | ||
name="type" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormControl> | ||
<WeekTeams | ||
schedule={schedule} | ||
field={field} | ||
userPick={userPick} | ||
onWeeklyPickChange={onWeeklyPickChange} | ||
/> | ||
</FormControl> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
</form> | ||
</FormProvider> | ||
</section> | ||
</div> | ||
); | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -7,27 +7,69 @@ import { RadioGroup } from '@radix-ui/react-radio-group'; | |||||
import { IWeekTeamsProps } from './WeekTeams.interface'; | ||||||
import { WeeklyPickButton } from '@/components/WeeklyPickButton/WeeklyPickButton'; | ||||||
|
||||||
/** | ||||||
* Formats the date to 'day, mon date' format and the time to either 12 or 24-hour format based on the user's locale. | ||||||
* @param dateStr The date string to format. | ||||||
* @returns The formatted date and time string. | ||||||
*/ | ||||||
const formatDateTime = (dateStr: string): string => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not shorthand your variable names. When someone else is reading them, you want them to concise and ready to browse.
Suggested change
|
||||||
const date = new Date(dateStr); | ||||||
|
||||||
const dateOptions: Intl.DateTimeFormatOptions = { | ||||||
weekday: 'short', | ||||||
month: 'short', | ||||||
day: 'numeric', | ||||||
}; | ||||||
const timeOptions: Intl.DateTimeFormatOptions = { | ||||||
hour: 'numeric', | ||||||
minute: 'numeric', | ||||||
hour12: true, | ||||||
}; | ||||||
|
||||||
const formattedDate = date.toLocaleDateString('en-US', dateOptions); | ||||||
const formattedTime = date.toLocaleTimeString('en-US', timeOptions); | ||||||
|
||||||
return `${formattedDate} ・ ${formattedTime}`; | ||||||
}; | ||||||
|
||||||
/** | ||||||
* Renders the weekly picks page. | ||||||
* @param props The parameters for the weekly picks page. | ||||||
* @param props.field The form field. | ||||||
* @param props.schedule The schedule for the week. | ||||||
* @param props.userPick The user's pick. | ||||||
* @param props.onWeeklyPickChange The function to call when the user's pick changes. | ||||||
* @returns The rendered weekly picks page. | ||||||
*/ | ||||||
import { FormEventHandler } from 'react'; | ||||||
|
||||||
/** | ||||||
* Renders the weekly picks page. | ||||||
* @param props The parameters for the weekly picks page. | ||||||
* @param props.field The form field. | ||||||
* @param props.schedule The schedule for the week. | ||||||
* @param props.userPick The user's pick. | ||||||
* @param props.onWeeklyPickChange The function to call when the user's pick changes. | ||||||
* @returns The rendered weekly picks page. | ||||||
*/ | ||||||
const WeekTeams = ({ | ||||||
field, | ||||||
schedule, | ||||||
userPick, | ||||||
onWeeklyPickChange, | ||||||
}: IWeekTeamsProps): JSX.Element => ( | ||||||
<> | ||||||
{schedule.map((scheduledGame) => ( | ||||||
<RadioGroup | ||||||
onValueChange={field.onChange} | ||||||
defaultValue={userPick} | ||||||
key={scheduledGame.id} | ||||||
className="grid w-full grid-cols-2 gap-4" | ||||||
className="grid w-full grid-cols-2 gap-4 pb-8" | ||||||
onChange={onWeeklyPickChange as FormEventHandler<HTMLDivElement>} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No go on assertions. Unless it's a special case, it's most likely your typing that is off. In this case, We need to update IWeekTeamsProps with the correct typing. We used the generic |
||||||
> | ||||||
<div className="week-page-game-schedule col-span-2 text-center"> | ||||||
<p>{formatDateTime(scheduledGame.date)}</p> | ||||||
</div> | ||||||
{scheduledGame.competitions[0].competitors.map((competition) => ( | ||||||
<FormItem key={competition.id}> | ||||||
<FormControl> | ||||||
|
@@ -42,5 +84,4 @@ const WeekTeams = ({ | |||||
))} | ||||||
</> | ||||||
); | ||||||
|
||||||
export default WeekTeams; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: We'll need to look into Suspense in the near future.