sendou.ink/app/features/user-page/actions/u.$identifier.edit.server.ts
2026-01-03 13:47:32 +02:00

71 lines
1.9 KiB
TypeScript

import { type ActionFunction, redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import * as TournamentTeamRepository from "~/features/tournament/TournamentTeamRepository.server";
import { clearTournamentDataCache } from "~/features/tournament-bracket/core/Tournament.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { safeParseRequestFormData } from "~/utils/remix.server";
import { errorIsSqliteUniqueConstraintFailure } from "~/utils/sql";
import { userPage } from "~/utils/urls";
import { userEditActionSchema } from "../user-page-schemas";
export const action: ActionFunction = async ({ request }) => {
const parsedInput = await safeParseRequestFormData({
request,
schema: userEditActionSchema,
});
if (!parsedInput.success) {
return {
errors: parsedInput.errors,
};
}
const { inGameNameText, inGameNameDiscriminator, ...data } = parsedInput.data;
const user = requireUser();
const inGameName =
inGameNameText && inGameNameDiscriminator
? `${inGameNameText}#${inGameNameDiscriminator}`
: null;
const pronouns =
data.subjectPronoun && data.objectPronoun
? JSON.stringify({
subject: data.subjectPronoun,
object: data.objectPronoun,
})
: null;
try {
const editedUser = await UserRepository.updateProfile({
...data,
pronouns,
inGameName,
userId: user.id,
});
// TODO: to transaction
if (inGameName) {
const tournamentIdsAffected =
await TournamentTeamRepository.updateMemberInGameNameForNonStarted({
inGameName,
userId: user.id,
});
for (const tournamentId of tournamentIdsAffected) {
clearTournamentDataCache(tournamentId);
}
}
throw redirect(userPage(editedUser));
} catch (e) {
if (!errorIsSqliteUniqueConstraintFailure(e)) {
throw e;
}
return {
errors: ["forms.errors.invalidCustomUrl.duplicate"],
};
}
};