Skip to content

Commit

Permalink
Update footy-report extension
Browse files Browse the repository at this point in the history
- Merge pull request raycast#37 from thuoe/next
- Merge pull request raycast#36 from thuoe/chore/sync-raycast-repo
- Merge branch \'contributions/merge-1705420963700882000\' into chore/sync-raycast-repo
- Pull contributions
- Merge pull request raycast#35 from thuoe/next
- Merge pull request raycast#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 (raycast#34)
- Merge pull request raycast#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
  • Loading branch information
thuoe committed Jan 16, 2024
1 parent b745c60 commit 74f53f5
Show file tree
Hide file tree
Showing 11 changed files with 372 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
8 changes: 7 additions & 1 deletion extensions/footy-report/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
Raycast extension to find your essential football match day info and stats
</h3>

<p align="center">
<a title="Install footy-report Raycast Extension" href="https://www.raycast.com/thuoe/footy-report"><img src="https://www.raycast.com/thuoe/footy-report/[email protected]?v=1.1" height="64" alt="" style="height: 64px;"></a>
</p>

![Header](metadata/footy-report-1.png)

## ⚠️ Prerequisites
Expand All @@ -34,7 +38,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
36 changes: 36 additions & 0 deletions extensions/footy-report/src/hooks/useFetchLeagues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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 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 { data: finalData, isLoading, revalidate };
};

export default useFetchLeagues;
64 changes: 64 additions & 0 deletions extensions/footy-report/src/hooks/useFetchStandings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import useSportMonksClient from "./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 response: SportMonksStandingResponse[] = data?.data;

const finalData =
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 { data: finalData, isLoading, revalidate };
};

export default useFetchStandings;
Loading

0 comments on commit 74f53f5

Please sign in to comment.