1
0
Fork 0

Use of Server Components for easier Data fetching + start use of v2 API

This commit is contained in:
Neshura 2023-06-10 16:14:53 +02:00
parent 49ceda5575
commit f23c9dc0f1
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
6 changed files with 195 additions and 5 deletions

View file

@ -1,12 +1,14 @@
'use client';
import '@/app/globals.css';
import { Game, GameGroup } from '@/types/stellaris';
import { GameView } from '@/components/gui/game-view';
import { generateUrl } from '@/components/server/fetchers';
export default async function Home() {
const games = await fetch(generateUrl('/games')).then((res) => res.json())
export default function Home() {
return (
<main>
<div>
<p>Empire Overview goes here evenutally</p>
</div>
<GameView games={games}/>
</main>
)
}

View file

@ -0,0 +1,85 @@
import { Game, GameGroup } from "@/types/stellaris";
import { Dropdown } from "@nextui-org/react";
import { Dispatch, Key, SetStateAction, Suspense } from "react";
import { fetchGameGroups } from "@/components/server/fetchers";
type SelectionType = "all" | Set<Key>;
export const GameGroupSelect = (
props: {
game: Game,
groups: [GameGroup[], Dispatch<SetStateAction<Array<GameGroup>>>],
currentGroups: [GameGroup[], Dispatch<SetStateAction<Array<GameGroup>>>]
}) => {
const currentGame = props.game;
const [gameGroups, setGameGroups] = props.groups;
const [currentGameGroups, setCurrentGameGroups] = props.currentGroups;
const changeSelection = (keys: SelectionType) => {
if (keys != "all") {
let newSelection: GameGroup[] = [];
keys.forEach(key => {
gameGroups.forEach(group => {
if (key == group.name) {
newSelection.push(group);
}
})
});
setCurrentGameGroups(newSelection)
}
}
return (
<>
<Suspense>
<DataHandler game={currentGame} groups={[gameGroups, setGameGroups]} currentGroups={[currentGameGroups, setCurrentGameGroups]} />
</Suspense>
<Dropdown>
<Dropdown.Button flat color="secondary" css={{ tt: "capitalize" }}>
{currentGameGroups.map(elem => elem.name).join(", ")}
</Dropdown.Button>
<Dropdown.Menu
aria-label="Multiple selection actions"
color="secondary"
disallowEmptySelection
selectionMode="multiple"
selectedKeys={currentGameGroups.map(elem => elem.name)}
onSelectionChange={changeSelection}
items={gameGroups}
>
{gameGroups.map((item) => (
<Dropdown.Item
key={item.name}
color="default"
>
{item.name}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
</>
)
}
const DataHandler = async (
props: {
game: Game,
groups: [GameGroup[], Dispatch<SetStateAction<Array<GameGroup>>>],
currentGroups: [GameGroup[], Dispatch<SetStateAction<Array<GameGroup>>>]
}) => {
if (props) {
const currentGame = props.game;
const [gameGroups, setGameGroups] = props.groups;
const [currentGameGroups, setCurrentGameGroups] = props.currentGroups;
if (!gameGroups[0] || gameGroups[0].game_id != currentGame.id) {
setGameGroups(await fetchGameGroups(currentGame));
}
else if (!currentGameGroups[0] || currentGameGroups[0].game_id != gameGroups[0].game_id) {
setCurrentGameGroups(gameGroups);
}
}
return <></>
}

View file

@ -0,0 +1,43 @@
import { Game } from "@/types/stellaris";
import { Dropdown } from "@nextui-org/react";
import { Dispatch, Key, SetStateAction, useState } from "react";
type SelectionType = "all" | Set<Key>;
export const GameSelect = (props: { games: Game[], currentGame: Game | undefined, setCurrentGame: Dispatch<SetStateAction<Game>> }) => {
const changeSelection = (keys: SelectionType) => {
if (keys != "all") {
props.games.forEach(game => {
if (game.name == keys.keys().next().value) [
props.setCurrentGame(game)
]
})
}
}
return (
<Dropdown>
<Dropdown.Button flat color="secondary" css={{ tt: "capitalize" }}>
{props.currentGame ? props.currentGame.name : "-"}
</Dropdown.Button>
<Dropdown.Menu
aria-label="Single selection actions"
color="secondary"
disallowEmptySelection
selectionMode="single"
selectedKeys={[props.currentGame ? props.currentGame.name : "-"]}
onSelectionChange={changeSelection}
items={props.games}
>
{props.games.map((item) => (
<Dropdown.Item
key={item.name}
color="default"
>
{item.name}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
)
}

View file

@ -0,0 +1,22 @@
'use client';
import { Game } from "@/types/stellaris";
import { GameSelect } from "./game-select";
import { useState } from 'react';
import { GameGroupSelect } from "./game-group-select";
import { SSRProvider } from "react-bootstrap";
export const GameView = (props: { games: Game[] }) => {
const [currentGame, setCurrentGame] = useState(props.games[0]);
const [gameGroups, setGameGroups] = useState([{id: 0, name: "", game_id: 0}]);
const [currentGameGroups, setCurrentGameGroups] = useState(gameGroups);
return (
<>
<SSRProvider>
<GameSelect games={props.games} currentGame={currentGame} setCurrentGame={setCurrentGame} />
<GameGroupSelect game={currentGame} groups={[gameGroups, setGameGroups]} currentGroups={[currentGameGroups, setCurrentGameGroups]} />
</SSRProvider>
</>
)
}

View file

@ -0,0 +1,27 @@
import { Game } from "@/types/stellaris"
type Parameter = {
key: string,
val: string | number
}
const baseUrl = 'http://stellaris.neshweb.net/api/v2'
export const generateUrl = (url: string, params?: Parameter[]) => {
let query: string = baseUrl + url;
if (params && params.length > 0) {
query = query + '?';
params.forEach((param, idx) => {
query = query + param.key + '=' + param.val;
if (idx + 1 != params.length) {
query = query + '&';
}
});
}
return query;
}
export const fetchGameGroups = async (game: Game) => {
const gameGroups = await fetch(generateUrl('/game_groups', [{key: "game_id", val: game.id}])).then((res) => res.json())
return gameGroups
}

View file

@ -64,3 +64,14 @@ export enum Species {
Toxoid = 11,
Machine = 12,
}
export type Game = {
id: number,
name: string
}
export type GameGroup = {
id: number,
game_id: number,
name: string
}