mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-07 11:46:09 -05:00
Merge branch 'rewrite' of https://github.com/Sendouc/sendou.ink into calendar
This commit is contained in:
@@ -4,9 +4,9 @@ import type {
|
||||
MetaFunction,
|
||||
} from "@remix-run/node";
|
||||
import { json } from "@remix-run/node";
|
||||
import { Link, Outlet, useLoaderData } from "@remix-run/react";
|
||||
import type { ShouldReloadFunction } from "@remix-run/react";
|
||||
import { Link, Outlet, useLoaderData, useSearchParams } from "@remix-run/react";
|
||||
import clsx from "clsx";
|
||||
import * as React from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
import { z } from "zod";
|
||||
import { Avatar } from "~/components/Avatar";
|
||||
@@ -115,6 +115,11 @@ export interface PlusSuggestionsLoaderData {
|
||||
suggestedForTiers: number[];
|
||||
}
|
||||
|
||||
export const unstable_shouldReload: ShouldReloadFunction = ({ submission }) => {
|
||||
// only reload if form submission not when user changes tabs
|
||||
return Boolean(submission);
|
||||
};
|
||||
|
||||
export const loader: LoaderFunction = async ({ request }) => {
|
||||
const user = await getUser(request);
|
||||
|
||||
@@ -138,13 +143,13 @@ export const loader: LoaderFunction = async ({ request }) => {
|
||||
|
||||
export default function PlusSuggestionsPage() {
|
||||
const data = useLoaderData<PlusSuggestionsLoaderData>();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const user = useUser();
|
||||
// TODO: this stays undefined when adding first suggestion
|
||||
const [tierVisible, setTierVisible] = React.useState(
|
||||
tierVisibleInitialState(data.suggestions)
|
||||
);
|
||||
const tierVisible = searchParamsToLegalTier(searchParams, data.suggestions);
|
||||
|
||||
useSetSelectedTierForFirstSuggestEffect({ tierVisible, setTierVisible });
|
||||
const handleTierChange = (tier: string) => {
|
||||
setSearchParams({ tier });
|
||||
};
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
@@ -206,7 +211,7 @@ export default function PlusSuggestionsPage() {
|
||||
name="tier"
|
||||
type="radio"
|
||||
checked={tierVisible === tier}
|
||||
onChange={() => setTierVisible(tier)}
|
||||
onChange={() => handleTierChange(tier)}
|
||||
data-cy={`plus${tier}-radio`}
|
||||
/>
|
||||
</div>
|
||||
@@ -248,6 +253,22 @@ export default function PlusSuggestionsPage() {
|
||||
);
|
||||
}
|
||||
|
||||
function searchParamsToLegalTier(
|
||||
searchParams: URLSearchParams,
|
||||
suggestions?: plusSuggestions.FindVisibleForUser
|
||||
) {
|
||||
const tierFromSearchParams = searchParams.get("tier");
|
||||
if (
|
||||
!tierFromSearchParams ||
|
||||
!suggestions ||
|
||||
!suggestions[tierFromSearchParams]
|
||||
) {
|
||||
return tierVisibleInitialState(suggestions);
|
||||
}
|
||||
|
||||
return tierFromSearchParams;
|
||||
}
|
||||
|
||||
function tierVisibleInitialState(
|
||||
suggestions?: plusSuggestions.FindVisibleForUser
|
||||
) {
|
||||
@@ -255,21 +276,6 @@ function tierVisibleInitialState(
|
||||
return String(Math.min(...Object.keys(suggestions).map(Number)));
|
||||
}
|
||||
|
||||
function useSetSelectedTierForFirstSuggestEffect({
|
||||
tierVisible,
|
||||
setTierVisible,
|
||||
}: {
|
||||
tierVisible?: string;
|
||||
setTierVisible: (tier?: string) => void;
|
||||
}) {
|
||||
const data = useLoaderData<PlusSuggestionsLoaderData>();
|
||||
React.useEffect(() => {
|
||||
if (tierVisible) return;
|
||||
|
||||
setTierVisible(tierVisibleInitialState(data.suggestions));
|
||||
}, [data, tierVisible, setTierVisible]);
|
||||
}
|
||||
|
||||
function SuggestedForInfo({ hideText = false }: { hideText?: boolean }) {
|
||||
const data = useLoaderData<PlusSuggestionsLoaderData>();
|
||||
const user = useUser();
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
} from "~/permissions";
|
||||
import { atOrError } from "~/utils/arrays";
|
||||
import { parseRequestFormData, validate } from "~/utils/remix";
|
||||
import { PLUS_SUGGESTIONS_PAGE } from "~/utils/urls";
|
||||
import { plusSuggestionPage } from "~/utils/urls";
|
||||
import { actualNumber } from "~/utils/zod";
|
||||
import type { PlusSuggestionsLoaderData } from "../suggestions";
|
||||
import { CommentTextarea } from "./new";
|
||||
@@ -60,7 +60,7 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
...nextNonCompletedVoting(new Date()),
|
||||
});
|
||||
|
||||
return redirect(PLUS_SUGGESTIONS_PAGE);
|
||||
return redirect(plusSuggestionPage());
|
||||
};
|
||||
|
||||
export default function PlusCommentModalPage() {
|
||||
@@ -86,7 +86,7 @@ export default function PlusCommentModalPage() {
|
||||
targetPlusTier: Number(tierSuggestedTo),
|
||||
})
|
||||
) {
|
||||
return <Redirect to={PLUS_SUGGESTIONS_PAGE} />;
|
||||
return <Redirect to={plusSuggestionPage()} />;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -104,7 +104,7 @@ export default function PlusCommentModalPage() {
|
||||
Submit
|
||||
</Button>
|
||||
<LinkButton
|
||||
to={PLUS_SUGGESTIONS_PAGE}
|
||||
to={plusSuggestionPage()}
|
||||
variant="minimal-destructive"
|
||||
tiny
|
||||
>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
playerAlreadyMember,
|
||||
playerAlreadySuggested,
|
||||
} from "~/permissions";
|
||||
import { PLUS_SUGGESTIONS_PAGE } from "~/utils/urls";
|
||||
import { plusSuggestionPage } from "~/utils/urls";
|
||||
import type { PlusSuggestionsLoaderData } from "../suggestions";
|
||||
import * as React from "react";
|
||||
import { Label } from "~/components/Label";
|
||||
@@ -80,7 +80,7 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
...nextNonCompletedVoting(new Date()),
|
||||
});
|
||||
|
||||
return redirect(PLUS_SUGGESTIONS_PAGE);
|
||||
return redirect(plusSuggestionPage(data.tier));
|
||||
};
|
||||
|
||||
export default function PlusNewSuggestionModalPage() {
|
||||
@@ -111,7 +111,7 @@ export default function PlusNewSuggestionModalPage() {
|
||||
}) ||
|
||||
!targetPlusTier
|
||||
) {
|
||||
return <Redirect to={PLUS_SUGGESTIONS_PAGE} />;
|
||||
return <Redirect to={plusSuggestionPage()} />;
|
||||
}
|
||||
|
||||
const selectedUserErrorMessage = getSelectedUserErrorMessage({
|
||||
@@ -160,7 +160,7 @@ export default function PlusNewSuggestionModalPage() {
|
||||
Submit
|
||||
</Button>
|
||||
<LinkButton
|
||||
to={PLUS_SUGGESTIONS_PAGE}
|
||||
to={plusSuggestionPage()}
|
||||
variant="minimal-destructive"
|
||||
tiny
|
||||
>
|
||||
|
||||
@@ -12,7 +12,6 @@ export const LEAN_TWITTER = "https://twitter.com/LeanYoshi";
|
||||
export const UBERU_TWITTER = "https://twitter.com/uberu5";
|
||||
export const LOG_IN_URL = "/auth";
|
||||
export const LOG_OUT_URL = "/auth/logout";
|
||||
export const PLUS_SUGGESTIONS_PAGE = "/plus/suggestions";
|
||||
export const ADMIN_PAGE = "/admin";
|
||||
export const FAQ_PAGE = "/faq";
|
||||
export const CONTRIBUTIONS_PAGE = "/contributions";
|
||||
@@ -23,6 +22,8 @@ export const userPage = (discordId: string) => `/u/${discordId}`;
|
||||
export const impersonateUrl = (idToLogInAs: number) =>
|
||||
`/auth/impersonate?id=${idToLogInAs}`;
|
||||
export const badgePage = (badgeId: number) => `${BADGES_PAGE}/${badgeId}`;
|
||||
export const plusSuggestionPage = (tier?: string | number) =>
|
||||
`/plus/suggestions${tier ? `?tier=${tier}` : ""}`;
|
||||
|
||||
export const badgeUrl = ({
|
||||
code,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PLUS_SUGGESTIONS_PAGE } from "~/utils/urls";
|
||||
import { plusSuggestionPage } from "~/utils/urls";
|
||||
|
||||
export {};
|
||||
|
||||
@@ -9,13 +9,13 @@ describe("Plus suggestions page", () => {
|
||||
|
||||
it("views suggestions status as non plus member", function () {
|
||||
cy.auth(151);
|
||||
cy.visit(PLUS_SUGGESTIONS_PAGE);
|
||||
cy.visit(plusSuggestionPage());
|
||||
cy.contains("You are suggested");
|
||||
});
|
||||
|
||||
it("adds a comment and deletes one", () => {
|
||||
cy.auth();
|
||||
cy.visit(PLUS_SUGGESTIONS_PAGE);
|
||||
cy.visit(plusSuggestionPage());
|
||||
|
||||
cy.getCy("suggested-user-name")
|
||||
.first()
|
||||
@@ -45,7 +45,7 @@ describe("Plus suggestions page", () => {
|
||||
it("adds a new suggestion, validates suggested user and deletes it", () => {
|
||||
cy.clock(new Date(Date.UTC(2022, 5, 15))); // let's make sure voting is not happening
|
||||
cy.auth();
|
||||
cy.visit(PLUS_SUGGESTIONS_PAGE);
|
||||
cy.visit(plusSuggestionPage());
|
||||
|
||||
cy.getCy("new-suggest-button").click();
|
||||
cy.getCy("tier-select").select("2");
|
||||
|
||||
Reference in New Issue
Block a user