diff --git a/app/features/calendar/actions/calendar.new.server.ts b/app/features/calendar/actions/calendar.new.server.ts
index dcc32868f..c3f05edf0 100644
--- a/app/features/calendar/actions/calendar.new.server.ts
+++ b/app/features/calendar/actions/calendar.new.server.ts
@@ -44,6 +44,7 @@ export const action: ActionFunction = async ({ request }) => {
const isEditing = Boolean(data.eventToEditId);
const isAddingTournament = data.toToolsEnabled;
+ const isTournamentAdder = user.roles.includes("TOURNAMENT_ADDER");
const organizationId = data.organizationId
? Number(data.organizationId)
: null;
@@ -52,7 +53,7 @@ export const action: ActionFunction = async ({ request }) => {
await validateOrganization({
userId: user.id,
organizationId,
- isTournamentAdder: user.roles.includes("TOURNAMENT_ADDER"),
+ isTournamentAdder,
});
} else if (!isEditing) {
requireRole(
@@ -141,7 +142,10 @@ export const action: ActionFunction = async ({ request }) => {
"Tournament has already started",
);
- errorToastIfFalsy(tournament.isAdmin(user), "Not authorized");
+ errorToastIfFalsy(
+ tournament.canEditEventInfo(user, { isTournamentAdder }),
+ "Not authorized",
+ );
// once published, a tournament can't be flipped back to draft
if (!tournament.isDraft) {
diff --git a/app/features/tournament-admin/routes/to.$id.admin.tsx b/app/features/tournament-admin/routes/to.$id.admin.tsx
index 6fc336aeb..11f9934e9 100644
--- a/app/features/tournament-admin/routes/to.$id.admin.tsx
+++ b/app/features/tournament-admin/routes/to.$id.admin.tsx
@@ -23,6 +23,7 @@ import { Redirect } from "~/components/Redirect";
import { DANGEROUS_CAN_ACCESS_DEV_CONTROLS } from "~/features/admin/core/dev-controls";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
+import { useHasRole } from "~/modules/permissions/hooks";
import {
calendarEventPage,
tournamentAdminPage,
@@ -42,6 +43,7 @@ export default function TournamentAdminLayout() {
const tournament = useTournament();
const outletContext = useOutletContext();
const user = useUser();
+ const isTournamentAdder = useHasRole("TOURNAMENT_ADDER");
const location = useLocation();
const showReopen = Boolean(
@@ -73,7 +75,8 @@ export default function TournamentAdminLayout() {
return (
- {tournament.isAdmin(user) && !tournament.hasStarted ? (
+ {tournament.canEditEventInfo(user, { isTournamentAdder }) &&
+ !tournament.hasStarted ? (
member.userId === user.id && member.role === "ADMIN",
+ );
+
+ return Boolean(
+ isOrganizationAdmin &&
+ (isTournamentAdder || this.ctx.organization?.isEstablished),
+ );
+ }
+
/** Checks if the given user is an organizer of the tournament. */
isOrganizer(user: OptionalIdObject) {
if (!user) return false;
diff --git a/app/features/tournament-bracket/core/tests/mocks-li.ts b/app/features/tournament-bracket/core/tests/mocks-li.ts
index 5c2f5dc27..9d25cc332 100644
--- a/app/features/tournament-bracket/core/tests/mocks-li.ts
+++ b/app/features/tournament-bracket/core/tests/mocks-li.ts
@@ -6923,6 +6923,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({
id: 3,
name: "Inkling Performance Labs",
slug: "inkling-performance-labs",
+ isEstablished: 1,
logoUrl: "fZrToLQrkqV3UZkdgwp0Q-1722263644749.webp",
series: [],
members: [
diff --git a/app/features/tournament-bracket/core/tests/mocks-sos.ts b/app/features/tournament-bracket/core/tests/mocks-sos.ts
index d638f3c0f..794d8b3f8 100644
--- a/app/features/tournament-bracket/core/tests/mocks-sos.ts
+++ b/app/features/tournament-bracket/core/tests/mocks-sos.ts
@@ -2026,6 +2026,7 @@ export const SWIM_OR_SINK_167 = (
id: 3,
name: "Inkling Performance Labs",
slug: "inkling-performance-labs",
+ isEstablished: 1,
logoUrl: "fZrToLQrkqV3UZkdgwp0Q-1722263644749.webp",
series: [],
members: [
diff --git a/app/features/tournament/TournamentRepository.server.ts b/app/features/tournament/TournamentRepository.server.ts
index e05e664e1..de27605bf 100644
--- a/app/features/tournament/TournamentRepository.server.ts
+++ b/app/features/tournament/TournamentRepository.server.ts
@@ -85,6 +85,7 @@ export async function findById(id: number) {
"TournamentOrganization.id",
"TournamentOrganization.name",
"TournamentOrganization.slug",
+ "TournamentOrganization.isEstablished",
concatUserSubmittedImagePrefix(
innerEb.ref("UserSubmittedImage.url"),
).as("logoUrl"),
diff --git a/app/features/tournament/tournament-utils.test.ts b/app/features/tournament/tournament-utils.test.ts
index bd3a83c88..0a9f2da7d 100644
--- a/app/features/tournament/tournament-utils.test.ts
+++ b/app/features/tournament/tournament-utils.test.ts
@@ -782,6 +782,7 @@ describe("tournamentNameParts", () => {
id: 1,
name: "Sendou's Tournaments",
slug: "sendou",
+ isEstablished: 1,
logoUrl: null,
members: [],
series: [{ name: "In The Zone" }],