mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-22 15:09:16 -05:00
Open art
This commit is contained in:
parent
dad6c8ea2c
commit
beffde6058
|
|
@ -3,38 +3,30 @@ import navItems from "~/components/layout/nav-items.json";
|
|||
import { useTranslation } from "~/hooks/useTranslation";
|
||||
import { navIconUrl } from "~/utils/urls";
|
||||
import { Image } from "../Image";
|
||||
import { temporaryCanAccessArtCheck } from "~/features/art";
|
||||
import { useUser } from "~/modules/auth";
|
||||
|
||||
export function SideNav() {
|
||||
const user = useUser();
|
||||
const { t } = useTranslation(["common"]);
|
||||
|
||||
return (
|
||||
<nav className="layout__side-nav layout__item_size">
|
||||
{navItems
|
||||
.filter(
|
||||
(navItem) =>
|
||||
temporaryCanAccessArtCheck(user) || navItem.name !== "art"
|
||||
)
|
||||
.map((item) => {
|
||||
return (
|
||||
<Link
|
||||
to={item.url}
|
||||
key={item.name}
|
||||
prefetch={item.prefetch ? "render" : undefined}
|
||||
>
|
||||
<div className="layout__side-nav-image-container">
|
||||
<Image
|
||||
path={navIconUrl(item.name)}
|
||||
height={32}
|
||||
width={32}
|
||||
alt={t(`common:pages.${item.name}` as any)}
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
{navItems.map((item) => {
|
||||
return (
|
||||
<Link
|
||||
to={item.url}
|
||||
key={item.name}
|
||||
prefetch={item.prefetch ? "render" : undefined}
|
||||
>
|
||||
<div className="layout__side-nav-image-container">
|
||||
<Image
|
||||
path={navIconUrl(item.name)}
|
||||
height={32}
|
||||
width={32}
|
||||
alt={t(`common:pages.${item.name}` as any)}
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
import type { User } from "~/db/types";
|
||||
|
||||
export function temporaryCanAccessArtCheck(user?: Pick<User, "isArtist">) {
|
||||
return user?.isArtist === 1;
|
||||
}
|
||||
|
||||
export function previewUrl(url: string) {
|
||||
// images with https are not hosted on spaces, this is used for local development
|
||||
if (url.includes("https")) return url;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,5 @@ export { deleteArt } from "./queries/deleteArt.server";
|
|||
export { findArtById } from "./queries/findArtById.server";
|
||||
export type { ListedArt, ArtSouce } from "./art-types";
|
||||
export { ART_SOURCES } from "./art-types";
|
||||
export { temporaryCanAccessArtCheck } from "./art-utils";
|
||||
export { NEW_ART_EXISTING_SEARCH_PARAM_KEY } from "./art-constants";
|
||||
export { deleteArtSchema } from "./art-schemas.server";
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ export const handle: SendouRouteHandle = {
|
|||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
validate(user.isArtist, "Lacking artist role", 403);
|
||||
|
||||
const searchParams = new URL(request.url).searchParams;
|
||||
const artIdRaw = searchParams.get(NEW_ART_EXISTING_SEARCH_PARAM_KEY);
|
||||
|
|
@ -111,8 +112,7 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
|
||||
export const loader = async ({ request }: LoaderArgs) => {
|
||||
const user = await requireUser(request);
|
||||
|
||||
validate(user.isArtist, "No artist role", 401);
|
||||
validate(user.isArtist, "Lacking artist role", 403);
|
||||
|
||||
const artIdRaw = new URL(request.url).searchParams.get(
|
||||
NEW_ART_EXISTING_SEARCH_PARAM_KEY
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@ import { Label } from "~/components/Label";
|
|||
import { Main } from "~/components/Main";
|
||||
import { Toggle } from "~/components/Toggle";
|
||||
import { i18next } from "~/modules/i18n";
|
||||
import { validate, type SendouRouteHandle } from "~/utils/remix";
|
||||
import { type SendouRouteHandle } from "~/utils/remix";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import { ART_PAGE, navIconUrl } from "~/utils/urls";
|
||||
import { ArtGrid } from "../components/ArtGrid";
|
||||
import { showcaseArts } from "../queries/showcaseArts.server";
|
||||
import { requireUser } from "~/modules/auth";
|
||||
import { temporaryCanAccessArtCheck } from "../art-utils";
|
||||
import { useSearchParamState } from "~/hooks/useSearchParamState";
|
||||
import { useTranslation } from "~/hooks/useTranslation";
|
||||
|
||||
|
|
@ -36,9 +34,6 @@ export const meta: V2_MetaFunction = (args) => {
|
|||
};
|
||||
|
||||
export const loader = async ({ request }: LoaderArgs) => {
|
||||
const user = await requireUser(request);
|
||||
validate(temporaryCanAccessArtCheck(user), "Insufficient permissions");
|
||||
|
||||
const t = await i18next.getFixedT(request);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import * as React from "react";
|
|||
import { ThemeChanger } from "~/components/layout/ThemeChanger";
|
||||
import { SelectedThemeIcon } from "~/components/layout/SelectedThemeIcon";
|
||||
import { useTheme } from "~/modules/theme";
|
||||
import { temporaryCanAccessArtCheck } from "~/features/art";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
|
|
@ -89,30 +88,25 @@ export default function FrontPage() {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{navItems
|
||||
.filter(
|
||||
(navItem) =>
|
||||
temporaryCanAccessArtCheck(user) || navItem.name !== "art"
|
||||
)
|
||||
.map((item) => (
|
||||
<Link
|
||||
to={item.url}
|
||||
className="front__nav-item"
|
||||
key={item.name}
|
||||
prefetch={item.prefetch ? "render" : undefined}
|
||||
onMouseEnter={() => setFilters(item.filters as [string, string])}
|
||||
>
|
||||
<div className="front__nav-image-container">
|
||||
<Image
|
||||
path={navIconUrl(item.name)}
|
||||
height={48}
|
||||
width={48}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div>{t(`common:pages.${item.name}` as any)}</div>
|
||||
</Link>
|
||||
))}
|
||||
{navItems.map((item) => (
|
||||
<Link
|
||||
to={item.url}
|
||||
className="front__nav-item"
|
||||
key={item.name}
|
||||
prefetch={item.prefetch ? "render" : undefined}
|
||||
onMouseEnter={() => setFilters(item.filters as [string, string])}
|
||||
>
|
||||
<div className="front__nav-image-container">
|
||||
<Image
|
||||
path={navIconUrl(item.name)}
|
||||
height={48}
|
||||
width={48}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div>{t(`common:pages.${item.name}` as any)}</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
{user ? (
|
||||
<div className="front__log-out-container">
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { z } from "zod";
|
|||
import { Main } from "~/components/Main";
|
||||
import { SubNav, SubNavLink } from "~/components/SubNav";
|
||||
import { db } from "~/db";
|
||||
import { countArtByUserId, temporaryCanAccessArtCheck } from "~/features/art";
|
||||
import { countArtByUserId } from "~/features/art";
|
||||
import { userTopPlacements } from "~/features/top-search";
|
||||
import { findVods } from "~/features/vods";
|
||||
import { useTranslation } from "~/hooks/useTranslation";
|
||||
|
|
@ -155,12 +155,11 @@ export default function UserPageLayout() {
|
|||
{t("pages.vods")} ({data.vods.length})
|
||||
</SubNavLink>
|
||||
)}
|
||||
{(isOwnPage || data.artCount > 0) &&
|
||||
temporaryCanAccessArtCheck(user) && (
|
||||
<SubNavLink to={userArtPage(data)} end={false}>
|
||||
{t("pages.art")} ({data.artCount})
|
||||
</SubNavLink>
|
||||
)}
|
||||
{(isOwnPage || data.artCount > 0) && (
|
||||
<SubNavLink to={userArtPage(data)} end={false}>
|
||||
{t("pages.art")} ({data.artCount})
|
||||
</SubNavLink>
|
||||
)}
|
||||
</SubNav>
|
||||
<Outlet />
|
||||
</Main>
|
||||
|
|
|
|||
|
|
@ -17,25 +17,22 @@ import {
|
|||
} from "~/features/art";
|
||||
import { useLoaderData, useMatches } from "@remix-run/react";
|
||||
import { useSearchParamState } from "~/hooks/useSearchParamState";
|
||||
import { requireUser, useUser } from "~/modules/auth";
|
||||
import {
|
||||
temporaryCanAccessArtCheck,
|
||||
deleteArt,
|
||||
deleteArtSchema,
|
||||
} from "~/features/art";
|
||||
import { useUser } from "~/modules/auth";
|
||||
import { deleteArt, deleteArtSchema } from "~/features/art";
|
||||
import invariant from "tiny-invariant";
|
||||
import { LinkButton } from "~/components/Button";
|
||||
import { Popover } from "~/components/Popover";
|
||||
import { countUnvalidatedArt } from "~/features/img-upload";
|
||||
import { useTranslation } from "~/hooks/useTranslation";
|
||||
import { newArtPage } from "~/utils/urls";
|
||||
import { requireUserId } from "~/modules/auth/user.server";
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["art"],
|
||||
};
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUserId(request);
|
||||
const data = await parseRequestFormData({
|
||||
request,
|
||||
schema: deleteArtSchema,
|
||||
|
|
@ -53,11 +50,7 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
};
|
||||
|
||||
export const loader = async ({ params, request }: LoaderArgs) => {
|
||||
const loggedInUser = await requireUser(request);
|
||||
validate(
|
||||
temporaryCanAccessArtCheck(loggedInUser),
|
||||
"Insufficient permissions"
|
||||
);
|
||||
const loggedInUser = await requireUserId(request);
|
||||
|
||||
const { identifier } = userParamsSchema.parse(params);
|
||||
const user = notFoundIfFalsy(db.users.findByIdentifier(identifier));
|
||||
|
|
@ -177,7 +170,7 @@ function AddArtButton({ isArtist }: { isArtist?: boolean }) {
|
|||
triggerClassName="tiny"
|
||||
containerClassName="text-center"
|
||||
>
|
||||
{t("art:commissionsOpen")}
|
||||
{t("art:gainPerms")}
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user