Refetch after creating team

This commit is contained in:
Kalle (Sendou)
2021-11-21 12:36:47 +02:00
parent 052b023f98
commit 7b3775b743
10 changed files with 70 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ export function Layout(p: { children: JSXElement }) {
setMenuExpanded((expanded) => !expanded);
}
// TODO: why logo wide?
return (
<>
<header class={s.header}>

View File

@@ -3,6 +3,7 @@ import { DiscordIcon } from "../../../components/icons/Discord";
import { useUser } from "../../../utils/UserContext";
import s from "../styles/UserItem.module.css";
// TODO: redirect to same page on login
export function UserItem() {
const user = useUser();

View File

@@ -1,14 +1,12 @@
import { useData } from "solid-app-router";
import { createResource } from "solid-js";
import { InferQueryOutput, trpcClient } from "../../utils/trpc-client";
import type { UseDataResult } from "../../utils/types";
import { trpcClient } from "../../utils/trpc-client";
export default function TournamentData({
params,
}: {
params: { organization: string; tournament: string };
}) {
const [user] = createResource(
return createResource(
() => [params.organization, params.tournament],
([organization, tournament]) =>
trpcClient.query("tournament.get", {
@@ -16,10 +14,6 @@ export default function TournamentData({
tournament,
})
);
return user;
}
export function useTournamentData(delta?: number) {
return useData<UseDataResult<InferQueryOutput<"tournament.get">>>(delta);
}
export type ITournamentData = ReturnType<typeof TournamentData>;

View File

@@ -1,9 +1,10 @@
import { useData } from "solid-app-router";
import { createMemo, createSignal } from "solid-js";
import { ErrorMessage } from "../../../components/ErrorMessage";
import { trpcClient } from "../../../utils/trpc-client";
import { useForm } from "../../../utils/useForm";
import s from "../styles/ActionSection.module.css";
import { useTournamentData } from "../TournamentPage.data";
import type { ITournamentData } from "../TournamentPage.data";
const lengthIsCorrect = ({ value }: { value: string }) => {
if (value.length >= 2 && value.length <= 40) {
@@ -20,16 +21,31 @@ const uniqueName =
return `There is already a team called "${value}" registered`;
};
// TODO: show login action when not logged in
// TODO: show add members action when captain and not started
// TODO: show leave member action when not captain and not started
// TODO: show checkin action when captain and check-in started
// TODO: show report score and other in-game actions when there is a match ongoing
// TODO: outlined when no crucial action, filled when there is?
export function ActionSection() {
const [expanded, setExpanded] = createSignal(false);
const tournament = useTournamentData();
const [teamName, setTeamName] = createSignal("");
const [tournament, { refetch }] = useData<ITournamentData>();
const { validate: _validate, formSubmit: _formSubmit, errors } = useForm();
const fn = (form: HTMLFormElement) => {
return trpcClient.mutation("tournament.createTournamentTeam", {
name: "Team Olive",
tournamentId: 1,
});
const fn = async () => {
try {
await trpcClient.mutation("tournament.createTournamentTeam", {
name: teamName(),
tournamentId: tournament()!.id,
});
// TODO: mutate here?
refetch();
setExpanded(false);
} catch (e) {
console.error(e);
// TODO: deal with error
}
};
const registeredTeamNames = createMemo(() =>
@@ -60,6 +76,8 @@ export function ActionSection() {
name="team-name"
id="team-name"
required
value={teamName()}
onInput={(e) => setTeamName(e.currentTarget.value)}
// @ts-expect-error
use:_validate={[
lengthIsCorrect,

View File

@@ -1,11 +1,12 @@
import { Show } from "solid-js";
import { DiscordIcon } from "../../../components/icons/Discord";
import { TwitterIcon } from "../../../components/icons/Twitter";
import { useTournamentData } from "../TournamentPage.data";
import type { ITournamentData } from "../TournamentPage.data";
import s from "../styles/InfoBanner.module.css";
import { useData } from "solid-app-router";
export function InfoBanner() {
const tournament = useTournamentData();
const [tournament] = useData<ITournamentData>();
// TODO: skeleton
return (

View File

@@ -1,11 +1,12 @@
import { For, Show } from "solid-js";
import { modesShort, stages } from "../../../utils/constants";
import { useTournamentData } from "../TournamentPage.data";
import type { ITournamentData } from "../TournamentPage.data";
import s from "../styles/MapPoolTab.module.css";
import type { Mode } from ".prisma/client";
import { useData } from "solid-app-router";
export function MapPoolTab() {
const tournament = useTournamentData(1);
const [tournament] = useData<ITournamentData>(1);
return (
<Show when={tournament()}>

View File

@@ -1,26 +1,45 @@
import { createMemo, For, Show } from "solid-js";
import { useTournamentData } from "../TournamentPage.data";
import type { ITournamentData } from "../TournamentPage.data";
import s from "../styles/TeamsTab.module.css";
import { AvatarWithName } from "../../../components/AvatarWithName";
import type { InferQueryOutput } from "../../../utils/trpc-client";
import { useUser } from "../../../utils/UserContext";
import { useData } from "solid-app-router";
const sortCaptainFirst = (a: { captain: boolean }, b: { captain: boolean }) => {
return Number(b.captain) - Number(a.captain);
};
const sortTeamsFullFirst = (a: { members: any[] }, b: { members: any[] }) => {
const aSortValue = a.members.length >= 4 ? 1 : 0;
const bSortValue = b.members.length >= 4 ? 1 : 0;
const sortOwnTeamsAndFullTeamsFirst =
(userId?: number) =>
(
a: { members: { member: { id: number } }[] },
b: { members: { member: { id: number } }[] }
) => {
if (userId) {
const aSortValue = Number(
a.members.some(({ member }) => userId === member.id)
);
const bSortValue = Number(
b.members.some(({ member }) => userId === member.id)
);
return bSortValue - aSortValue;
};
if (aSortValue !== bSortValue) return bSortValue - aSortValue;
}
const aSortValue = a.members.length >= 4 ? 1 : 0;
const bSortValue = b.members.length >= 4 ? 1 : 0;
return bSortValue - aSortValue;
};
export function TeamsTab() {
const tournament = useTournamentData(1);
const [tournament] = useData<ITournamentData>(1);
const user = useUser();
const sortedTeams = createMemo(() =>
tournament()
?.teams.sort(sortTeamsFullFirst)
?.teams.sort(sortOwnTeamsAndFullTeamsFirst(user()?.id))
.map((team) => {
return {
...team,
@@ -29,6 +48,7 @@ export function TeamsTab() {
})
);
// TODO: looks kinda bad on mobile
return (
<div class={s.container}>
<Show when={sortedTeams()}>{(teams) => <TeamsList teams={teams} />}</Show>

View File

@@ -1,12 +1,12 @@
import { NavLink, Outlet } from "solid-app-router";
import { NavLink, Outlet, useData } from "solid-app-router";
import { InfoBanner } from "./InfoBanner";
import s from "../styles/TournamentPage.module.css";
import { useTournamentData } from "../TournamentPage.data";
import type { ITournamentData } from "../TournamentPage.data";
import { Show } from "solid-js";
import { ActionSection } from "./ActionSection";
export default function TournamentsPage() {
const tournament = useTournamentData();
const [tournament] = useData<ITournamentData>();
return (
<div class={s.container}>

View File

@@ -12,6 +12,7 @@ export async function findTournamentByNameForUrl({
nameForUrl: tournamentNameForUrl.toLowerCase(),
},
select: {
id: true,
name: true,
description: true,
startTime: true,
@@ -42,6 +43,7 @@ export async function findTournamentByNameForUrl({
captain: true,
member: {
select: {
id: true,
discordAvatar: true,
discordName: true,
discordId: true,

View File

@@ -2,6 +2,7 @@ import { createTRPCClient } from "@trpc/client";
import type { inferProcedureOutput } from "@trpc/server";
import type { AppRouter } from "../server";
// TODO: transformer superjson
export const trpcClient = createTRPCClient<AppRouter>({
url: `${import.meta.env.VITE_BACKEND_URL}/trpc`,
fetch: (input, init) => fetch(input, { ...init, credentials: "include" }),