diff --git a/apps/frontend/src/models/CardType.ts b/apps/frontend/src/models/CardType.ts index a6627731f6a28..92b90804ab20f 100644 --- a/apps/frontend/src/models/CardType.ts +++ b/apps/frontend/src/models/CardType.ts @@ -6,3 +6,30 @@ export const CardType = { WAKATIME: "wakatime", } as const; export type CardType = (typeof CardType)[keyof typeof CardType]; + +export const CardCategory = { + /** + * Cards describing a single repo or gist. + * They accept `show_owner` and use the `_repocard` theme variants. + */ + REPO: "repo", + /** + * Cards describing a user: stats, top languages and WakaTime. + */ + USER: "user", +} as const; +export type CardCategory = (typeof CardCategory)[keyof typeof CardCategory]; + +/** + * Category each card belongs to. + * + * Exhaustive by construction: a new {@link CardType} will not compile until it + * is categorised here, rather than silently falling into one of the branches. + */ +export const CATEGORY_BY_CARD_TYPE: Record = { + [CardType.STATS]: CardCategory.USER, + [CardType.TOP_LANGS]: CardCategory.USER, + [CardType.WAKATIME]: CardCategory.USER, + [CardType.PIN]: CardCategory.REPO, + [CardType.GIST]: CardCategory.REPO, +}; diff --git a/apps/frontend/src/pages/Home/Home.tsx b/apps/frontend/src/pages/Home/Home.tsx index aff974c83852e..52788559be50a 100644 --- a/apps/frontend/src/pages/Home/Home.tsx +++ b/apps/frontend/src/pages/Home/Home.tsx @@ -1,3 +1,4 @@ +import type { ThemeName } from "@stats-organization/github-readme-stats-core"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { JSX } from "react"; import { useDispatch } from "react-redux"; @@ -8,7 +9,11 @@ import { authenticate } from "../../api/user"; import { DEFAULT_OPTION as LANGUAGES_DEFAULT_LAYOUT } from "../../components/Home/LanguagesLayoutSection"; import { DEFAULT_OPTION as WAKATIME_DEFAULT_LAYOUT } from "../../components/Home/WakatimeLayoutSection"; import { DEMO_USER } from "../../constants"; -import { CardType } from "../../models/CardType"; +import { + CATEGORY_BY_CARD_TYPE, + CardCategory, + CardType, +} from "../../models/CardType"; import { STAGE_LABELS } from "../../models/Stage"; import type { StageIndex } from "../../models/Stage"; import { useTheme } from "../../redux/selectors/themeSelectors"; @@ -34,17 +39,13 @@ interface HomeScreenProps { setStage: (stageIndex: StageIndex) => void; } -function getDefaultTheme(isDark: boolean, isRepoCard: boolean): string { - if (isRepoCard) { +function getDefaultTheme(isDark: boolean, category: CardCategory): ThemeName { + if (category === CardCategory.REPO) { return isDark ? "dark_github_repocard" : "light_github_repocard"; } return isDark ? "dark_github" : "light_github"; } -function isRepoCard(selectedCard: CardType): boolean { - return selectedCard === CardType.PIN || selectedCard === CardType.GIST; -} - export function HomeScreen({ stage, setStage }: HomeScreenProps): JSX.Element { const [isLoading, setIsLoading] = useState(false); @@ -77,7 +78,10 @@ export function HomeScreen({ stage, setStage }: HomeScreenProps): JSX.Element { } const { isDark } = useTheme(); - const [theme, setTheme] = useState(() => getDefaultTheme(isDark, false)); + const cardCategory = CATEGORY_BY_CARD_TYPE[selectedCard]; + const [theme, setTheme] = useState(() => + getDefaultTheme(isDark, cardCategory), + ); const handleCardTypeChange = (cardType: CardType) => { if (cardType === CardType.TOP_LANGS) { @@ -94,8 +98,8 @@ export function HomeScreen({ stage, setStage }: HomeScreenProps): JSX.Element { })); } - if (theme === getDefaultTheme(isDark, isRepoCard(selectedCard))) { - setTheme(getDefaultTheme(isDark, isRepoCard(cardType))); + if (theme === getDefaultTheme(isDark, cardCategory)) { + setTheme(getDefaultTheme(isDark, CATEGORY_BY_CARD_TYPE[cardType])); } setSelectedCard(cardType); @@ -114,8 +118,8 @@ export function HomeScreen({ stage, setStage }: HomeScreenProps): JSX.Element { // Preview builder for the customize stage, dark-themed to match the surroundings. const customizeCardBuilder = useMemo( - () => cardBuilder.theme(getDefaultTheme(isDark, isRepoCard(selectedCard))), - [cardBuilder, isDark, selectedCard], + () => cardBuilder.theme(getDefaultTheme(isDark, cardCategory)), + [cardBuilder, isDark, cardCategory], ); // for stage four @@ -254,7 +258,7 @@ export function HomeScreen({ stage, setStage }: HomeScreenProps): JSX.Element { { setTheme(theme); setStage(4); diff --git a/apps/frontend/src/pages/Home/stages/Customize.tsx b/apps/frontend/src/pages/Home/stages/Customize.tsx index 50c828ec55d04..3336aaeaf7ef3 100644 --- a/apps/frontend/src/pages/Home/stages/Customize.tsx +++ b/apps/frontend/src/pages/Home/stages/Customize.tsx @@ -13,7 +13,11 @@ import { DEMO_USER, DEMO_WAKATIME_USER, } from "../../../constants"; -import { CardType } from "../../../models/CardType"; +import { + CATEGORY_BY_CARD_TYPE, + CardCategory, + CardType, +} from "../../../models/CardType"; import type { CardUrlBuilder } from "../../../models/CardUrl"; import type { StageIndex } from "../../../models/Stage"; import { useIsAuthenticated } from "../../../redux/selectors/userSelectors"; @@ -367,7 +371,7 @@ export function CustomizeStage({ }} /> )} - {(cardType === CardType.PIN || cardType === CardType.GIST) && ( + {CATEGORY_BY_CARD_TYPE[cardType] === CardCategory.REPO && ( = [ "default", "default_repocard", "github_dark", @@ -49,18 +50,19 @@ const nonRepoCardThemes = forPicker( interface ThemeStageProps { card: CardUrlBuilder; theme: string; - isRepoCard: boolean; - onThemeChange: (theme: string) => void; + category: CardCategory; + onThemeChange: (theme: ThemeName) => void; } export function ThemeStage({ theme, card, - isRepoCard, + category, onThemeChange, }: ThemeStageProps): JSX.Element { const { isDark } = useTheme(); - const themeList = isRepoCard ? repoCardThemes : nonRepoCardThemes; + const themeList = + category === CardCategory.REPO ? repoCardThemes : nonRepoCardThemes; return ( <>