Support page

This commit is contained in:
Kalle 2023-01-23 00:39:21 +02:00
parent 318f7a5043
commit 057c4cf18d
11 changed files with 292 additions and 11 deletions

View File

@ -0,0 +1,12 @@
export function HeartIcon({ className }: { className?: string }) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className={className}
>
<path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 01-.383-.218 25.18 25.18 0 01-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0112 5.052 5.5 5.5 0 0116.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 01-4.244 3.17 15.247 15.247 0 01-.383.219l-.022.012-.007.004-.003.001a.752.752 0 01-.704 0l-.003-.001z" />
</svg>
);
}

View File

@ -7,10 +7,10 @@ import {
FAQ_PAGE,
SENDOU_INK_DISCORD_URL,
SENDOU_INK_GITHUB_URL,
SENDOU_INK_PATREON_URL,
SENDOU_INK_TWITTER_URL,
SENDOU_LOVE_EMOJI_PATH,
SPLATOON_2_SENDOU_IN_URL,
SUPPORT_PAGE,
userPage,
} from "~/utils/urls";
import { DiscordIcon } from "../icons/Discord";
@ -69,17 +69,12 @@ export function Footer({
</div>{" "}
<DiscordIcon className="layout__footer__social-icon discord" />
</a>
<a
className="layout__footer__social-link"
href={SENDOU_INK_PATREON_URL}
target="_blank"
rel="noreferrer"
>
<Link className="layout__footer__social-link" to={SUPPORT_PAGE}>
<div className="layout__footer__social-header">
Patreon<p>{t("footer.patreon.subtitle")}</p>
</div>{" "}
<PatreonIcon className="layout__footer__social-icon patreon" />
</a>
</Link>
</div>
{patrons.length > 0 ? (
<div>

View File

@ -9,6 +9,10 @@ import { SideNav } from "./SideNav";
import { UserItem } from "./UserItem";
import { LanguageChanger } from "./LanguageChanger";
import { ThemeChanger } from "./ThemeChanger";
import { LinkButton } from "../Button";
import { SUPPORT_PAGE } from "~/utils/urls";
import { HeartIcon } from "../icons/Heart";
import { useUser } from "~/modules/auth";
function useBreadcrumbs() {
const { t } = useTranslation();
@ -39,6 +43,7 @@ export const Layout = React.memo(function Layout({
patrons?: RootLoaderData["patrons"];
isCatchBoundary?: boolean;
}) {
const user = useUser();
const { t } = useTranslation(["common"]);
const location = useLocation();
const breadcrumbs = useBreadcrumbs();
@ -65,14 +70,37 @@ export const Layout = React.memo(function Layout({
})}
{isFrontPage ? (
<>
<div className="layout__breadcrumb-separator">-</div>
<div className="layout__breadcrumb">
<div className="layout__breadcrumb-separator mobile-hidden">
-
</div>
<div className="layout__breadcrumb mobile-hidden">
{t("common:websiteSubtitle")}
</div>
{typeof user?.patronTier !== "number" ? (
<LinkButton
to={SUPPORT_PAGE}
size="tiny"
icon={<HeartIcon />}
variant="outlined"
className="ml-auto desktop-hidden"
>
{t("common:pages.support")}
</LinkButton>
) : null}
</>
) : null}
</div>
<div className="layout__header__right-container">
{typeof user?.patronTier !== "number" ? (
<LinkButton
to={SUPPORT_PAGE}
size="tiny"
icon={<HeartIcon />}
variant="outlined"
>
{t("common:pages.support")}
</LinkButton>
) : null}
<LanguageChanger />
<ThemeChanger />
{!isCatchBoundary ? <UserItem /> : null}

View File

@ -0,0 +1,167 @@
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { Main } from "~/components/Main";
import styles from "../support.css";
import * as React from "react";
import { CheckmarkIcon } from "~/components/icons/Checkmark";
import { useTranslation } from "~/hooks/useTranslation";
import { Badge } from "~/components/Badge";
import { LinkButton } from "~/components/Button";
import {
PATREON_HOW_TO_CONNECT_DISCORD_URL,
SENDOU_INK_PATREON_URL,
} from "~/utils/urls";
import { Popover } from "~/components/Popover";
import { Trans } from "react-i18next";
import { makeTitle } from "~/utils/strings";
import { useSetTitle } from "~/hooks/useSetTitle";
export const meta: MetaFunction = () => {
return {
title: makeTitle("Support"),
};
};
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
// 1 = support
// 2 = supporter
// 3 = supporter+
const PERKS = [
{
tier: 1,
name: "supportMyWork",
extraInfo: false,
},
{
tier: 1,
name: "nameInFooter",
extraInfo: false,
},
{
tier: 2,
name: "badge",
extraInfo: false,
},
{
tier: 2,
name: "discordColorRole",
extraInfo: true,
},
{
tier: 2,
name: "seePlusPercentage",
extraInfo: true,
},
{
tier: 2,
name: "autoValidatePictures",
extraInfo: true,
},
] as const;
export default function SupportPage() {
const { t } = useTranslation();
useSetTitle(t("pages.support"));
return (
<Main className="stack lg">
<div className="stack md">
<p>{t("support.intro.first")}</p>
<p>{t("support.intro.second")}</p>
<SupportTable />
</div>
<LinkButton
size="big"
to={SENDOU_INK_PATREON_URL}
isExternal
className="mx-auto"
>
{t("support.action")}
</LinkButton>
<p className="text-sm text-lighter">
<Trans t={t} i18nKey="support.footer">
After becoming a new patron you should connect{" "}
<a
href={PATREON_HOW_TO_CONNECT_DISCORD_URL}
target="_blank"
rel="noreferrer"
>
your Discord on Patreon.com
</a>
. Afterwards the perks will take effect within 2 hours. If any
questions or problems contact Sendou for support.
</Trans>
</p>
</Main>
);
}
function SupportTable() {
const { t } = useTranslation();
return (
<div className="support__table">
<div />
<div>Support</div>
<div>Supporter</div>
<div>Supporter+</div>
{PERKS.map((perk) => {
return (
<React.Fragment key={perk.name}>
<div className="justify-self-start">
{t(`support.perk.${perk.name}`)}
{perk.extraInfo ? (
<Popover
containerClassName="support__popover"
triggerClassName="support__popover-trigger"
buttonChildren={<>?</>}
>
{t(`support.perk.${perk.name}.extra` as any)}
</Popover>
) : null}
</div>
<div>
{perk.tier === 1 ? (
<CheckmarkIcon className="support__checkmark" />
) : null}
</div>
{perk.name === "badge" ? (
<div>
<Badge
isAnimated
badge={{ code: "patreon", displayName: "" }}
size={32}
/>
</div>
) : (
<div>
{perk.tier <= 2 ? (
<CheckmarkIcon className="support__checkmark" />
) : null}
</div>
)}
{perk.name === "badge" ? (
<div>
<Badge
isAnimated
badge={{
code: "patreon_plus",
displayName: "",
}}
size={32}
/>
</div>
) : (
<div>
{perk.tier <= 3 ? (
<CheckmarkIcon className="support__checkmark" />
) : null}
</div>
)}
</React.Fragment>
);
})}
</div>
);
}

View File

@ -0,0 +1,29 @@
.support__table {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
place-items: center;
font-size: var(--fonts-sm);
row-gap: var(--s-2);
}
.support__checkmark {
color: var(--theme-success);
width: 25px;
}
.support__popover {
display: inline;
margin-inline-start: var(--s-2);
}
.support__popover-trigger {
display: inline;
height: 1rem;
padding: 0;
border: none;
background-color: transparent;
color: var(--theme);
font-size: var(--fonts-md);
font-weight: var(--bold);
outline: initial;
}

View File

@ -84,6 +84,7 @@ export interface RootLoaderData {
| "plusTier"
| "customUrl"
| "discordName"
| "patronTier"
>;
}
@ -108,6 +109,7 @@ export const loader: LoaderFunction = async ({ request }) => {
id: user.id,
plusTier: user.plusTier,
customUrl: user.customUrl,
patronTier: user.patronTier,
}
: undefined,
},

View File

@ -310,3 +310,9 @@
transform: translateX(-0.3rem);
}
}
@media screen and (max-width: 480px) {
.layout__breadcrumb-container {
width: 100%;
}
}

View File

@ -206,6 +206,10 @@
align-self: flex-start;
}
.justify-self-start {
justify-self: flex-start;
}
.flex-wrap {
flex-wrap: wrap;
}
@ -221,3 +225,21 @@
.label-no-spacing {
--label-margin: 0;
}
.mobile-hidden {
display: none;
}
.desktop-hidden {
display: inherit;
}
@media screen and (min-width: 480px) {
.mobile-hidden {
display: inherit;
}
.desktop-hidden {
display: none;
}
}

View File

@ -43,6 +43,8 @@ export const SENDOU_INK_DISCORD_URL = "https://discord.gg/sendou";
export const SENDOU_TWITTER_URL = "https://twitter.com/sendouc";
export const SENDOU_INK_TWITTER_URL = "https://twitter.com/sendouink";
export const SENDOU_INK_PATREON_URL = "https://patreon.com/sendou";
export const PATREON_HOW_TO_CONNECT_DISCORD_URL =
"https://support.patreon.com/hc/en-us/articles/212052266-How-do-I-connect-Discord-to-Patreon-Patron-";
export const SENDOU_INK_GITHUB_URL = "https://github.com/Sendouc/sendou.ink";
export const GITHUB_CONTRIBUTORS_URL =
"https://github.com/Sendouc/sendou.ink/graphs/contributors";
@ -63,6 +65,7 @@ export const LOG_OUT_URL = "/auth/logout";
export const ADMIN_PAGE = "/admin";
export const ARTICLES_MAIN_PAGE = "/a";
export const FAQ_PAGE = "/faq";
export const SUPPORT_PAGE = "/support";
export const CONTRIBUTIONS_PAGE = "/contributions";
export const BADGES_PAGE = "/badges";
export const BUILDS_PAGE = "/builds";

View File

@ -15,6 +15,7 @@
"pages.myPage": "My Page",
"pages.u": "User Search",
"pages.t": "Teams",
"pages.support": "Support",
"header.profile": "Profile",
"header.logout": "Log out",
@ -133,5 +134,19 @@
"upload.type.team-banner": "team picture banner",
"upload.commonExplanation": "Before the image is publicly displayed a moderator will validate it. Images uploaded by patrons are shown without validation.",
"upload.afterExplanation_one": "You have {{count}} image pending. The image will show up automatically after validation.",
"upload.afterExplanation_other": "You have {{count}} images pending. The images will show up automatically after validation."
"upload.afterExplanation_other": "You have {{count}} images pending. The images will show up automatically after validation.",
"support.intro.first": "Hello! I'm Sendou and sendou.ink is my project to provide tools and resources for the Splatoon community. The goal is to help everyone to improve and enjoy Splatoon whether you are brand new to the game or a seasoned veteran.",
"support.intro.second": "If you like what I'm doing this page details how you can support my work and gain perks. Your support helps me pay for the hosting as well as sponsor my time spent on continuously impoving the project.",
"support.action": "Support on Patreon",
"support.footer": "After becoming a new patron you should connect <2>your Discord on Patreon.com</2>. Afterwards the perks will take effect within 2 hours. If any questions or problems contact Sendou for support.",
"support.perk.supportMyWork": "Support my work",
"support.perk.nameInFooter": "Name in footer",
"support.perk.discordColorRole": "Discord color role",
"support.perk.discordColorRole.extra": "You can have custom color role on Plus Server and sendou.ink's Discord server. Use the /color command of the Lohi bot.",
"support.perk.badge": "Profile badge",
"support.perk.seePlusPercentage": "See Plus Server voting percentage",
"support.perk.seePlusPercentage.extra": "Normally only failed suggests see their voting percentage. With this you can see your own percentage.",
"support.perk.autoValidatePictures": "Auto validate uploaded pictures",
"support.perk.autoValidatePictures.extra": "Any images you upload (e.g. team profile/banner picture) get automatically validated. Normally it needs a moderator approval first. Note that this doesn't apply to images that were already submitted."
}

View File

@ -24,6 +24,8 @@ module.exports = {
route("/to/:id/join", "features/tournament/routes/to.$id.join.tsx");
});
route("/support", "features/info/routes/support.tsx");
route("/t", "features/team/routes/t.tsx");
route("/t/:customUrl", "features/team/routes/t.$customUrl.tsx");
route("/t/:customUrl/edit", "features/team/routes/t.$customUrl.edit.tsx");