mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-11 05:36:10 -05:00
Teams: Add to nav
This commit is contained in:
@@ -88,5 +88,13 @@
|
||||
"invert(30%) sepia(73%) saturate(4089%) hue-rotate(326deg) brightness(96%) contrast(104%)",
|
||||
"invert(55%) sepia(20%) saturate(738%) hue-rotate(224deg) brightness(86%) contrast(88%)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "t",
|
||||
"url": "t",
|
||||
"filters": [
|
||||
"invert(99%) sepia(3%) saturate(615%) hue-rotate(199deg) brightness(115%) contrast(88%)",
|
||||
"invert(23%) sepia(90%) saturate(2049%) hue-rotate(329deg) brightness(95%) contrast(107%)"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,27 +8,45 @@ import { writeAsyncIterableToWritable } from "@remix-run/node";
|
||||
import { nanoid } from "nanoid";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
const {
|
||||
STORAGE_END_POINT,
|
||||
STORAGE_ACCESS_KEY,
|
||||
STORAGE_SECRET,
|
||||
STORAGE_REGION,
|
||||
STORAGE_BUCKET,
|
||||
} = process.env;
|
||||
const envVars = () => {
|
||||
const {
|
||||
STORAGE_END_POINT,
|
||||
STORAGE_ACCESS_KEY,
|
||||
STORAGE_SECRET,
|
||||
STORAGE_REGION,
|
||||
STORAGE_BUCKET,
|
||||
} = process.env;
|
||||
|
||||
if (
|
||||
!(
|
||||
STORAGE_ACCESS_KEY &&
|
||||
STORAGE_END_POINT &&
|
||||
STORAGE_SECRET &&
|
||||
STORAGE_REGION &&
|
||||
STORAGE_BUCKET
|
||||
)
|
||||
) {
|
||||
throw new Error(`Storage is missing required configuration.`);
|
||||
}
|
||||
if (
|
||||
!(
|
||||
STORAGE_ACCESS_KEY &&
|
||||
STORAGE_END_POINT &&
|
||||
STORAGE_SECRET &&
|
||||
STORAGE_REGION &&
|
||||
STORAGE_BUCKET
|
||||
)
|
||||
) {
|
||||
throw new Error(`Storage is missing required configuration.`);
|
||||
}
|
||||
|
||||
return {
|
||||
STORAGE_END_POINT,
|
||||
STORAGE_ACCESS_KEY,
|
||||
STORAGE_SECRET,
|
||||
STORAGE_REGION,
|
||||
STORAGE_BUCKET,
|
||||
};
|
||||
};
|
||||
|
||||
const uploadStream = ({ Key }: Pick<AWS.S3.Types.PutObjectRequest, "Key">) => {
|
||||
const {
|
||||
STORAGE_END_POINT,
|
||||
STORAGE_ACCESS_KEY,
|
||||
STORAGE_SECRET,
|
||||
STORAGE_REGION,
|
||||
STORAGE_BUCKET,
|
||||
} = envVars();
|
||||
|
||||
const s3 = new AWS.S3({
|
||||
endpoint: STORAGE_END_POINT,
|
||||
s3ForcePathStyle: false,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { LinksFunction } from "@remix-run/node";
|
||||
import type {
|
||||
LinksFunction,
|
||||
MetaFunction,
|
||||
SerializeFrom,
|
||||
} from "@remix-run/node";
|
||||
import {
|
||||
type LoaderArgs,
|
||||
redirect,
|
||||
@@ -20,6 +24,7 @@ import {
|
||||
} from "~/utils/remix";
|
||||
import {
|
||||
mySlugify,
|
||||
navIconUrl,
|
||||
teamPage,
|
||||
TEAM_SEARCH_PAGE,
|
||||
uploadImagePage,
|
||||
@@ -35,18 +40,41 @@ import { deleteTeam } from "../queries/deleteTeam.server";
|
||||
import { Button } from "~/components/Button";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import styles from "../team.css";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
};
|
||||
|
||||
export const meta: MetaFunction = ({
|
||||
data,
|
||||
}: {
|
||||
data: SerializeFrom<typeof loader>;
|
||||
}) => {
|
||||
if (!data) return {};
|
||||
|
||||
return {
|
||||
title: makeTitle(data.team.name),
|
||||
};
|
||||
};
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["team"],
|
||||
// breadcrumb: () => ({
|
||||
// imgPath: navIconUrl("object-damage-calculator"),
|
||||
// href: OBJECT_DAMAGE_CALCULATOR_URL,
|
||||
// type: "IMAGE",
|
||||
// }),
|
||||
breadcrumb: ({ match }) => {
|
||||
const data = match.data as SerializeFrom<typeof loader>;
|
||||
return [
|
||||
{
|
||||
imgPath: navIconUrl("t"),
|
||||
href: TEAM_SEARCH_PAGE,
|
||||
type: "IMAGE",
|
||||
},
|
||||
{
|
||||
text: data.team.name,
|
||||
href: teamPage(data.team.customUrl),
|
||||
type: "TEXT",
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
|
||||
@@ -12,8 +12,8 @@ import { useTranslation } from "~/hooks/useTranslation";
|
||||
import { requireUser } from "~/modules/auth";
|
||||
import {
|
||||
notFoundIfFalsy,
|
||||
type SendouRouteHandle,
|
||||
validate,
|
||||
type SendouRouteHandle,
|
||||
} from "~/utils/remix";
|
||||
import { teamPage } from "~/utils/urls";
|
||||
import { addNewTeamMember } from "../queries/addNewTeamMember.server";
|
||||
@@ -53,11 +53,6 @@ export const action: ActionFunction = async ({ request, params }) => {
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["team"],
|
||||
// breadcrumb: () => ({
|
||||
// imgPath: navIconUrl("object-damage-calculator"),
|
||||
// href: OBJECT_DAMAGE_CALCULATOR_URL,
|
||||
// type: "IMAGE",
|
||||
// }),
|
||||
};
|
||||
|
||||
export const loader = async ({ request, params }: LoaderArgs) => {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { LinksFunction } from "@remix-run/node";
|
||||
import type {
|
||||
LinksFunction,
|
||||
MetaFunction,
|
||||
SerializeFrom,
|
||||
} from "@remix-run/node";
|
||||
import {
|
||||
redirect,
|
||||
type ActionFunction,
|
||||
@@ -18,9 +22,14 @@ import { useTranslation } from "~/hooks/useTranslation";
|
||||
import { requireUser, useUser } from "~/modules/auth";
|
||||
import type { SendouRouteHandle } from "~/utils/remix";
|
||||
import { notFoundIfFalsy, parseRequestFormData, validate } from "~/utils/remix";
|
||||
import { discordFullName } from "~/utils/strings";
|
||||
import { discordFullName, makeTitle } from "~/utils/strings";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import { joinTeamPage, teamPage } from "~/utils/urls";
|
||||
import {
|
||||
joinTeamPage,
|
||||
navIconUrl,
|
||||
teamPage,
|
||||
TEAM_SEARCH_PAGE,
|
||||
} from "~/utils/urls";
|
||||
import { editRole } from "../queries/editRole.server";
|
||||
import { findByIdentifier } from "../queries/findByIdentifier.server";
|
||||
import { inviteCodeById } from "../queries/inviteCodeById.server";
|
||||
@@ -37,6 +46,18 @@ export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
};
|
||||
|
||||
export const meta: MetaFunction = ({
|
||||
data,
|
||||
}: {
|
||||
data: SerializeFrom<typeof loader>;
|
||||
}) => {
|
||||
if (!data) return {};
|
||||
|
||||
return {
|
||||
title: makeTitle(data.team.name),
|
||||
};
|
||||
};
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
|
||||
@@ -86,11 +107,21 @@ export const action: ActionFunction = async ({ request, params }) => {
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["team"],
|
||||
// breadcrumb: () => ({
|
||||
// imgPath: navIconUrl("object-damage-calculator"),
|
||||
// href: OBJECT_DAMAGE_CALCULATOR_URL,
|
||||
// type: "IMAGE",
|
||||
// }),
|
||||
breadcrumb: ({ match }) => {
|
||||
const data = match.data as SerializeFrom<typeof loader>;
|
||||
return [
|
||||
{
|
||||
imgPath: navIconUrl("t"),
|
||||
href: TEAM_SEARCH_PAGE,
|
||||
type: "IMAGE",
|
||||
},
|
||||
{
|
||||
text: data.team.name,
|
||||
href: teamPage(data.team.customUrl),
|
||||
type: "TEXT",
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
export const loader = async ({ request, params }: LoaderArgs) => {
|
||||
|
||||
@@ -23,6 +23,9 @@ import { makeTitle } from "~/utils/strings";
|
||||
import {
|
||||
editTeamPage,
|
||||
manageTeamRosterPage,
|
||||
navIconUrl,
|
||||
teamPage,
|
||||
TEAM_SEARCH_PAGE,
|
||||
userPage,
|
||||
userSubmittedImage,
|
||||
} from "~/utils/urls";
|
||||
@@ -65,11 +68,21 @@ export const action: ActionFunction = async ({ request, params }) => {
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["team"],
|
||||
// breadcrumb: () => ({
|
||||
// imgPath: navIconUrl("object-damage-calculator"),
|
||||
// href: OBJECT_DAMAGE_CALCULATOR_URL,
|
||||
// type: "IMAGE",
|
||||
// }),
|
||||
breadcrumb: ({ match }) => {
|
||||
const data = match.data as SerializeFrom<typeof loader>;
|
||||
return [
|
||||
{
|
||||
imgPath: navIconUrl("t"),
|
||||
href: TEAM_SEARCH_PAGE,
|
||||
type: "IMAGE",
|
||||
},
|
||||
{
|
||||
text: data.team.name,
|
||||
href: teamPage(data.team.customUrl),
|
||||
type: "TEXT",
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
export const loader = ({ params }: LoaderArgs) => {
|
||||
|
||||
@@ -2,6 +2,8 @@ import type {
|
||||
ActionFunction,
|
||||
LinksFunction,
|
||||
LoaderArgs,
|
||||
MetaFunction,
|
||||
SerializeFrom,
|
||||
} from "@remix-run/node";
|
||||
import { redirect } from "@remix-run/node";
|
||||
import {
|
||||
@@ -21,11 +23,14 @@ import { Main } from "~/components/Main";
|
||||
import { SubmitButton } from "~/components/SubmitButton";
|
||||
import { useTranslation } from "~/hooks/useTranslation";
|
||||
import { getUser, requireUser, useUser } from "~/modules/auth";
|
||||
import { i18next } from "~/modules/i18n";
|
||||
import { joinListToNaturalString } from "~/utils/arrays";
|
||||
import type { SendouRouteHandle } from "~/utils/remix";
|
||||
import { parseRequestFormData, validate } from "~/utils/remix";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import {
|
||||
mySlugify,
|
||||
navIconUrl,
|
||||
teamPage,
|
||||
TEAM_SEARCH_PAGE,
|
||||
userSubmittedImage,
|
||||
@@ -36,6 +41,18 @@ import { TEAM } from "../team-constants";
|
||||
import { createTeamSchema } from "../team-schemas.server";
|
||||
import styles from "../team.css";
|
||||
|
||||
export const meta: MetaFunction = ({
|
||||
data,
|
||||
}: {
|
||||
data: SerializeFrom<typeof loader>;
|
||||
}) => {
|
||||
if (!data) return {};
|
||||
|
||||
return {
|
||||
title: data.title,
|
||||
};
|
||||
};
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
};
|
||||
@@ -73,15 +90,16 @@ export const action: ActionFunction = async ({ request }) => {
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["team"],
|
||||
// breadcrumb: () => ({
|
||||
// imgPath: navIconUrl("object-damage-calculator"),
|
||||
// href: OBJECT_DAMAGE_CALCULATOR_URL,
|
||||
// type: "IMAGE",
|
||||
// }),
|
||||
breadcrumb: () => ({
|
||||
imgPath: navIconUrl("t"),
|
||||
href: TEAM_SEARCH_PAGE,
|
||||
type: "IMAGE",
|
||||
}),
|
||||
};
|
||||
|
||||
export const loader = async ({ request }: LoaderArgs) => {
|
||||
const user = await getUser(request);
|
||||
const t = await i18next.getFixedT(request);
|
||||
|
||||
const teams = allTeams().sort((teamA, teamB) => {
|
||||
// show own team first always
|
||||
@@ -122,6 +140,7 @@ export const loader = async ({ request }: LoaderArgs) => {
|
||||
});
|
||||
|
||||
return {
|
||||
title: makeTitle(t("pages.t")),
|
||||
teams,
|
||||
isMemberOfTeam: !user
|
||||
? false
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"pages.object-damage-calculator": "DMG Calc",
|
||||
"pages.myPage": "My Page",
|
||||
"pages.u": "User Search",
|
||||
"pages.t": "Teams",
|
||||
|
||||
"header.profile": "Profile",
|
||||
"header.logout": "Log out",
|
||||
|
||||
BIN
public/static-assets/img/layout/t.avif
Normal file
BIN
public/static-assets/img/layout/t.avif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
BIN
public/static-assets/img/layout/t.png
Normal file
BIN
public/static-assets/img/layout/t.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Reference in New Issue
Block a user