Skip to content

Commit

Permalink
added gamebutton and favorite section
Browse files Browse the repository at this point in the history
  • Loading branch information
cophilot committed Aug 7, 2024
1 parent 04f7992 commit 0bda511
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/Routes.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Route, Routes as ReactRoutes, HashRouter } from 'react-router-dom';
import HomeView from './views/HomeView';
import ExpandableTable from './views/ExpandableTable';
import getAllGames from './allGames';
import { getAllGames } from './allGames';
import StringUtils from './utils/StringUtils';
import CreateCustomView from './views/CreateCustomView/CreateCustomView';

Expand Down
13 changes: 12 additions & 1 deletion src/allGames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Wizard from './games/wizard/main';
import Wingspan from './games/wingspan/main';
import ForestShuffle from './games/forest-shuffle/main';

export default function getAllGames() {
export function getAllGames() {
return [
Everdell,
Calico,
Expand All @@ -25,3 +25,14 @@ export default function getAllGames() {
ForestShuffle,
];
}

export function getSortedGames() {
const games = getAllGames();
games.sort((a, b) => a.definition.title.localeCompare(b.definition.title));
return games;
}

export function getSortedGameNames(): string[] {
const games = getSortedGames();
return games.map((game) => game.definition.title);
}
3 changes: 3 additions & 0 deletions src/components/FavoriteGameSection/FavoriteGameSection.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.btn-template {
border: 2px dashed var(--font-color);
}
77 changes: 77 additions & 0 deletions src/components/FavoriteGameSection/FavoriteGameSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useState } from 'react';
import './FavoriteGameSection.scss';
import { getSortedGameNames } from '../../allGames';
import LocalStorageService from '../../utils/LocalStorageService';
import GameButton from '../GameButton/GameButton';

/**
* This is a FavoriteGameSection component
* @author cophilot
* @version 1.0.0
* @created 2024-8-7
*/
function FavoriteGameSection() {
const [addingMode, setAddingMode] = useState(false);
const [favoriteGames, setFavoriteGamesInternal] = useState<string[]>(
LocalStorageService.getFavoriteGames()
);
const games = getSortedGameNames();

const setFavoriteGames = (favoriteGames: string[]) => {
setFavoriteGamesInternal(favoriteGames);
LocalStorageService.setFavoriteGames(favoriteGames);
};

const templateButtonStyle = { border: '2px dashed var(--font-color)' };

const onGameClick = (game: string) => {
if (addingMode) {
if (favoriteGames.includes(game)) {
setFavoriteGames(favoriteGames.filter((g) => g !== game));
} else {
setFavoriteGames([...favoriteGames, game]);
}
}
};

return (
<div className="ver">
{addingMode
? games.map((game) => (
<button
key={game}
className={
'btn wide ' +
(favoriteGames.includes(game) ? 'selected' : '')
}
style={
favoriteGames.includes(game)
? {}
: templateButtonStyle
}
onClick={() => onGameClick(game)}>
{game}
</button>
))
: favoriteGames.map((game) => (
<GameButton game={game} key={game} />
))}
<i
className={
'bi icon ' + getIconClassName(addingMode, favoriteGames)
}
onClick={() => setAddingMode(!addingMode)}></i>
</div>
);
}
export default FavoriteGameSection;

function getIconClassName(addingMode: boolean, favoriteGames: string[]) {
if (addingMode) {
return 'bi-check-lg';
}
if (favoriteGames.length === 0) {
return 'bi-plus-circle';
}
return 'bi-pencil-square';
}
Empty file.
43 changes: 43 additions & 0 deletions src/components/GameButton/GameButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useNavigate } from 'react-router-dom';
import './GameButton.scss';
import StringUtils from '../../utils/StringUtils';

interface GameButtonProps {
game: string;
asLink?: boolean;
link?: string;
}

/**
* This is a GameButton component
* @author cophilot
* @version 1.0.0
* @created 2024-8-7
*/
function GameButton({ game, asLink = false, link = '' }: GameButtonProps) {
const navigate = useNavigate();

if (asLink) {
return (
<div className="btn selected" style={{ width: '250px' }}>
<a
className=""
href={link}
target="_blank"
style={{ color: 'white' }}>
{game} <i className="bi bi-arrow-up-right-square"></i>
</a>
</div>
);
}
return (
<button
className="btn selected wide"
onClick={() => {
navigate(`/game/${StringUtils.gameNameToPath(game)}`);
}}>
{game}{' '}
</button>
);
}
export default GameButton;
6 changes: 6 additions & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,9 @@ a {
.imp {
color: var(--primary-color);
}

.icon {
font-size: 30px;
margin: 10px;
cursor: pointer;
}
20 changes: 20 additions & 0 deletions src/utils/LocalStorageService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default class LocalStorageService {
private static FAVORITE_GAMES_KEY = 'bsh-favorite-games';

static getFavoriteGames() {
const favoriteGames = localStorage.getItem(
LocalStorageService.FAVORITE_GAMES_KEY
);
if (favoriteGames === null) {
return [];
}
return JSON.parse(favoriteGames);
}

static setFavoriteGames(favoriteGames: string[]) {
localStorage.setItem(
LocalStorageService.FAVORITE_GAMES_KEY,
JSON.stringify(favoriteGames)
);
}
}
46 changes: 12 additions & 34 deletions src/views/HomeView.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useEffect } from 'react';
import StyleUtils from '../api/utils/StyleUtils';
import { useNavigate } from 'react-router-dom';
import StringUtils from '../utils/StringUtils';
import By from '../components/By';
import getAllGames from '../allGames';
import { getSortedGameNames } from '../allGames';
import Logo from '../components/Logo';
import DevMessage from '../components/DevMessage';
import GameButton from '../components/GameButton/GameButton';
import FavoriteGameSection from '../components/FavoriteGameSection/FavoriteGameSection';

export default function HomeView() {
const navigate = useNavigate();
Expand All @@ -14,8 +15,7 @@ export default function HomeView() {
document.title = 'BoardScoreHub';
}, []);

const games = getAllGames().map((game) => game.definition.title);
games.sort((a, b) => a.localeCompare(b));
const games = getSortedGameNames();

return (
<div>
Expand All @@ -32,10 +32,12 @@ export default function HomeView() {
</button>
{/* <button className="btn selected wide">Fix size Table</button> */}
</div>
<h2>Favorites</h2>
<FavoriteGameSection />
<h2>Games</h2>
<div className="ver">
{games.map((game) => (
<LinkGameButton key={game} game={game} />
<GameButton key={game} game={game} />
))}
</div>
<p>
Expand All @@ -50,7 +52,11 @@ export default function HomeView() {
</p>
<h2>External</h2>
<div className="ver">
<LinkGameButton game="Cascadia$x$https://cascoria.philipp-bonin.com/#/" />
<GameButton
game="Cascadia"
asLink
link="https://cascoria.philipp-bonin.com/#/"
/>
</div>
<h2>Custom</h2>
<div className="msg">
Expand All @@ -67,31 +73,3 @@ export default function HomeView() {
</div>
);
}

function LinkGameButton({ game }: { game: string }) {
const navigate = useNavigate();
if (game.includes('$x$')) {
const [name, link] = game.split('$x$');
return (
<div className="btn selected" style={{ width: '250px' }}>
<a
className=""
href={link}
target="_blank"
style={{ color: 'white' }}>
{name} <i className="bi bi-arrow-up-right-square"></i>
</a>
</div>
);
}

return (
<button
className="btn selected wide"
onClick={() => {
navigate(`/game/${StringUtils.gameNameToPath(game)}`);
}}>
{game}
</button>
);
}

0 comments on commit 0bda511

Please sign in to comment.