Skip to content

Commit

Permalink
Update footy-report extension (#10183)
Browse files Browse the repository at this point in the history
* Add footy-report extension

- Merge pull request #22 from thuoe/next
- Merge pull request #21 from thuoe/docs/2023-12-26-changelog
- docs: update changelog
- Merge pull request #20 from thuoe/feature/thu-33-redesign-test-api-command
- docs: update screenshots
- chore: delete unused assets
- feat: action to open ext preferences
- feat: use form to test API access token
- Merge pull request #19 from thuoe/bugfix/fetch-teams
- fix: optional position name
- Merge pull request #2 from thuoe/feature/thu-15-raycast-create-search-command
- Merge pull request #10 from thuoe/feature/thu-26-create-command-screenshots
- docs: include command screenshots in README.md
- docs: player stats screenshot
- docs: team list screenshot
- docs: update team details & API screenshots
- docs: delete outdated screenshots
- docs: create command screenshots
- Merge pull request #17 from thuoe/bugfix/type-errors
- build: include build step during CI pipeline
- fix: type error fetch teams hook
- fix: type error command arg
- fix: type errors for fetching fixtures
- fix: type erros from player stats
- fix: 2d array type further improvements
- fix: array type
- fix: multidimensional array type
- Merge pull request #18 from thuoe/feature/unit-tests
- build: test step to ci job
- test: create markdown from 2d array
- test: grouping obj
- test: format & select fields
- build: install jest
- Merge pull request #16 from thuoe/feature/thu-32-search-command-create-readme
- docs: add missing command subheading
- docs: create README.md template
- Merge pull request #15 from thuoe/feature/thu-29-player-markdown-season-stats
- feat: include yellow/red card stats
- refactor: set/filter events
- fix: map player id
- feat: fetch player stats across seasons for teams
- feat: create markdown table function
- Merge remote-tracking branch \'origin/next\' into feature/thu-15-raycast-create-search-command
- Merge pull request #14 from thuoe/chore/gh-actions-ci
- build: provide extension description
- refactor: ci pipeline
- Merge remote-tracking branch \'origin/next\' into feature/thu-15-raycast-create-search-command
- Merge pull request #13 from thuoe/feature/thu-28-create-extension-icon
- feat: create extension icon
- feat: create argument to search by team name
- feat: group squad by positions in grid view
- feat: create grouping function
- feat: create simple grid view for squad players
- feat: map tvstations to fixture calendar events
- feat: provide calendar name preference
- feat: wrap action in confirmation alert
- feat: create calendar event action for upcoming fixtures
- feat: icon for player details action button
- feat: introduce limit across fixture list items
- feat: populate upcoming fixtures list section
- fix: correct time range when fetching fixtures
- fix: rename fixture list category
- refactor: format fixture timestamp during response mapping
- feat: fetch latest fixtures and populate list items
- fix: correct squad subtitle count
- fix: populate title & placeholder with team name
- refactor: generic function to compute select fields
- fix: maximise player image size in markdown
- feat: create player details view
- feat: map player dob
- feat: restructure search command to search, favorite & display teams details
- feat: create new view for team details using dummy data
- build: create alias for shared types
- feat: create hook to fetch team with player info
- fix: invoke custom hook after change to path & provide execute flag
- refactor: rename search team command
- fix: prevent persisting dropdown value
- feat: create dropdown with team sections using dummy data
- feat(command): create search command template
- Merge pull request #12 from thuoe/chore/env-var-gh-actions
- chore: default env vars for gh actions
- chore: create basic ci pipeline (#11)
- Merge pull request #6 from thuoe/chore/local-dev-improvements
- fix: add missing package
- chore: format remaining files
- chore: update editorconfig
- chore: format code on save
- chore: create editorconfig file
- Merge pull request #5 from thuoe/feature/thu-23-create-preferences
- refactor: remove optional chaining
- refactor: create custom hook for API call
- feat: test API command
- chore: provide ESLint config (#4)
- Merge pull request #1 from thuoe/feature/thu-14-create-project-template
- feat: create simple command template
- Initial commit

* Update footy-report extension

- Merge pull request #26 from thuoe/next
- Merge pull request #25 from thuoe/bugfix/squad-details
- fix: map fixture id to item key
- fix: increase limit of squad players rendered in grid
- chore: remove console log
- fix: display age && render if dob provided
- fix: show seasons based on relevant team
- fix: filter season stats if no details found
- fix: render players without shirt no
- Merge pull request #23 from thuoe/main

* Update footy-report extension

- Merge pull request #29 from thuoe/next
- Merge pull request #28 from thuoe/feature/thu-34-error-handling-faulty-api-tokens
- fix: handle errors across views
- refactor: hooks response types
- fix: handle hook data responses if invalid token is found
- fix: provide error from promise hook
- feat: create error toast hook
- Merge pull request #27 from thuoe/main

* Update footy-report extension

- Merge pull request #32 from thuoe/next
- Merge pull request #31 from thuoe/feature/thu-35-api-test-command-validate-sportmonks-endpoint
- feat: validate endpoint before submit
- Merge pull request #30 from thuoe/main

* Update CHANGELOG.md and optimise images

* Update footy-report extension

- Merge pull request #37 from thuoe/next
- Merge pull request #36 from thuoe/chore/sync-raycast-repo
- Merge branch \'contributions/merge-1705420963700882000\' into chore/sync-raycast-repo
- Pull contributions
- Merge pull request #35 from thuoe/next
- Merge pull request #24 from thuoe/feature/thu-18-raycast-command-search-league-standings
- docs: update timestamp
- fix: filter only domestic leagues
- Merge remote-tracking branch \'origin/next\' into feature/thu-18-raycast-command-search-league-standings
- docs: include install button (#34)
- Merge pull request #33 from thuoe/main
- Merge remote-tracking branch \'origin/next\' into feature/thu-18-raycast-command-search-league-standings
- docs: update changelog
- feat: action to open team details from standing
- docs: include command screenshot
- feat: include search bar placeholder
- fix: map league id
- feat: display standing once league is selected
- feat: map recent form for each standing
- fix: map image path
- feat: map matches played
- feat: create hook to fetch league standing data
- fix: map active season
- feat: fetch leagues

* Already an install button 🙂

* fix: error handle invalid api tokens for fetching standings (#38)

* fix: linting issues (#39)

* fix: error handle fetch league hook (#40)

* Update README.md

* Update CHANGELOG.md and optimise images

---------

Co-authored-by: raycastbot <[email protected]>
Co-authored-by: Per Nielsen Tikær <[email protected]>
  • Loading branch information
3 people authored Jan 21, 2024
1 parent 137d9d9 commit 3a8ef7d
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 1 deletion.
4 changes: 4 additions & 0 deletions extensions/footy-report/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Footy Report Changelog

## [New Command] - 2024-01-16

- **Search League Standings** A command to search for league standings, displaying position, points, wins, loss and draws

## [Initial Version] - 2023-12-26

- Create new `Search Team` command
Expand Down
4 changes: 3 additions & 1 deletion extensions/footy-report/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ Trigger a simple API endpoint test using a SportsMonk API token to identify a su

### Search League Standings

🛠️ Under development
![League Standings](metadata/footy-report-5.png)

View league standing by displaying position, points, wins, draws and losses

### Search League Stats

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions extensions/footy-report/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
"required": true
}
]
},
{
"name": "searchLeagueStandings",
"title": "Search League Standings",
"description": "View league standing by displaying position, points, wins, draws and losses",
"mode": "view"
}
],
"dependencies": {
Expand Down
100 changes: 100 additions & 0 deletions extensions/footy-report/src/components/Standings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
Action,
ActionPanel,
Color,
Icon,
List,
useNavigation,
} from "@raycast/api";
import { useFetchStandings, useFetchTeams } from "@src/hooks";
import { useEffect, useState } from "react";
import TeamDetails from "@src/components/TeamDetails";

const Standings = ({ seasonId }: { seasonId: string }) => {
const { push } = useNavigation();
const [teamName, setTeamName] = useState<string>("");
const { data: standings, isLoading } = useFetchStandings(seasonId);
const { data: teamsFound, isLoading: isTeamLoading } = useFetchTeams(
teamName,
{
image_path: true,
},
);

useEffect(() => {
if (teamsFound.length > 0 && !isTeamLoading) {
const [team] = teamsFound;
push(<TeamDetails team={team} />);
}
}, [JSON.stringify(teamsFound)]);

return (
<List
searchBarPlaceholder={"Search team"}
isLoading={isLoading || isTeamLoading}
>
{standings.length === 0 ? (
<List.EmptyView title="No League Standings Found!" />
) : (
standings.map((standing) => {
return (
<List.Item
title={standing.position.toString()}
icon={{ source: standing.img_path }}
key={standing.name}
subtitle={standing.name}
keywords={[standing.name]}
actions={
<ActionPanel>
<Action
title="Open Team Details"
onAction={() => {
setTeamName(standing.name);
}}
/>
</ActionPanel>
}
accessories={[
{
text: {
value: `PL: ${standing.played}`,
color: Color.Orange,
},
},
{
text: { value: `W: ${standing.wins}`, color: Color.Green },
},
{
text: {
value: `D: ${standing.draws}`,
color: Color.SecondaryText,
},
},
{
text: { value: `L: ${standing.losses}`, color: Color.Red },
},
{
text: { value: `PTS: ${standing.points}`, color: Color.Blue },
},
...standing.recentForm.map((form) => {
const tintColor =
form.result === "W"
? Color.Green
: form.result === "D"
? Color.SecondaryText
: Color.Red;
return {
icon: { source: Icon.CircleFilled, tintColor },
tooltip: form.name,
};
}),
]}
/>
);
})
)}
</List>
);
};

export default Standings;
2 changes: 2 additions & 0 deletions extensions/footy-report/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ export { default as useSportMonksClient } from "@src/hooks/useSportMonksClient";
export { default as useFetchTeams } from "@src/hooks/useFetchTeams";
export { default as useFetchFixtures } from "@src/hooks/useFetchFixtures";
export { default as useFetchPlayerStats } from "@src/hooks/useFetchPlayerStats";
export { default as useFetchLeagues } from "@src/hooks/useFetchLeagues";
export { default as useFetchStandings } from "@src/hooks/useFetchStandings";
export { default as useErrorToast } from "@src/hooks/useErrorToast";
1 change: 1 addition & 0 deletions extensions/footy-report/src/hooks/useFetchFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const useFetchFixtures = (teamId: string, selectFields: SelectFields) => {
name: fixtureData.name,
starting_at: new Date(fixtureData.starting_at),
league: {
id: league.id,
name: league.name,
image_path: league.image_path,
},
Expand Down
49 changes: 49 additions & 0 deletions extensions/footy-report/src/hooks/useFetchLeagues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { HookResponse, League } from "@src/types";
import useSportMonksClient from "./useSportMonksClient";

type SportMonksSeason = {
id: string;
name: string;
is_current: boolean;
};

type SportMonksLeagueRespsonse = {
id: string;
name: string;
image_path: string;
seasons: SportMonksSeason[];
sub_type: string;
};

const useFetchLeagues = (name: string) => {
const { data, isLoading, revalidate } = useSportMonksClient({
method: "get",
path: `/leagues/search/${name}?include=seasons`,
execute: name.length > 0,
});
const hookResponse: HookResponse<League, typeof revalidate> = {
data: [],
isLoading,
error: null,
revalidate,
};

if (data?.status === 401) {
return { ...hookResponse, error: "Invalid API Token" };
}

const response: SportMonksLeagueRespsonse[] = data?.data;
const finalData =
response
?.filter((league) => league.sub_type === "domestic")
?.map(({ seasons, ...league }) => ({
id: league.id,
name: league.name,
image_path: league.image_path,
season: seasons.find((season) => season.is_current),
})) ?? [];

return { ...hookResponse, data: finalData };
};

export default useFetchLeagues;
76 changes: 76 additions & 0 deletions extensions/footy-report/src/hooks/useFetchStandings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { HookResponse, Standing } from "@src/types";
import useSportMonksClient from "@src/hooks/useSportMonksClient";

type Participant = {
name: string;
image_path: string;
};

type Form = {
fixture: {
name: string;
result_info: string;
starting_at_timestamp: number;
};
form: "W" | "D" | "L";
};

type SportMonksStandingResponse = {
position: number;
points: number;
form: Form[];
participant: Participant;
};

const MAX_FORM_FIXTURES = 4;

const useFetchStandings = (seasonId: string) => {
const { data, isLoading, revalidate } = useSportMonksClient({
method: "get",
path: `/standings/seasons/${seasonId}?include=form.fixture;participant`,
});

const hookResponse: HookResponse<Standing, typeof revalidate> = {
data: [],
isLoading,
error: null,
revalidate,
};

if (data?.status === 401) {
return { ...hookResponse, error: "Invalid API Token" };
}

const response: SportMonksStandingResponse[] = data?.data;

const finalData: Standing[] =
response?.map(({ participant, ...rest }) => {
return {
name: participant.name,
img_path: participant.image_path,
position: rest.position,
points: rest.points,
played: rest.form.length,
wins: rest.form.filter(({ form }) => form === "W").length,
losses: rest.form.filter(({ form }) => form === "L").length,
draws: rest.form.filter(({ form }) => form === "D").length,
recentForm: rest.form
.sort((a, b) => {
return (
new Date(a.fixture.starting_at_timestamp).getTime() -
new Date(b.fixture.starting_at_timestamp).getTime()
);
})
.map(({ form, fixture }) => ({
result: form,
name: fixture.name,
}))
.reverse()
.slice(0, MAX_FORM_FIXTURES),
};
}) ?? [];

return { ...hookResponse, data: finalData };
};

export default useFetchStandings;
Loading

0 comments on commit 3a8ef7d

Please sign in to comment.