mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
Team tags (#2623)
This commit is contained in:
parent
24008775aa
commit
9dbe19e0b8
|
|
@ -45,6 +45,8 @@ export interface Team {
|
|||
inviteCode: string;
|
||||
name: string;
|
||||
bsky: string | null;
|
||||
/** Team's tag, typically used in-game in front of users' names to indicate they are a member of the team. */
|
||||
tag: string | null;
|
||||
}
|
||||
|
||||
export interface TeamMember {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ export function findAllUndisbanded() {
|
|||
.select(({ eb }) => [
|
||||
"Team.customUrl",
|
||||
"Team.name",
|
||||
"Team.tag",
|
||||
concatUserSubmittedImagePrefix(eb.ref("UserSubmittedImage.url")).as(
|
||||
"avatarUrl",
|
||||
),
|
||||
|
|
@ -75,6 +76,7 @@ export function findByCustomUrl(
|
|||
"Team.name",
|
||||
"Team.bsky",
|
||||
"Team.bio",
|
||||
"Team.tag",
|
||||
"Team.customUrl",
|
||||
"Team.css",
|
||||
concatUserSubmittedImagePrefix(eb.ref("AvatarImage.url")).as("avatarUrl"),
|
||||
|
|
@ -277,10 +279,11 @@ export async function update({
|
|||
customUrl,
|
||||
bio,
|
||||
bsky,
|
||||
tag,
|
||||
css,
|
||||
}: Pick<
|
||||
Insertable<Tables["Team"]>,
|
||||
"id" | "name" | "customUrl" | "bio" | "bsky"
|
||||
"id" | "name" | "customUrl" | "bio" | "bsky" | "tag"
|
||||
> & { css: string | null }) {
|
||||
return db
|
||||
.updateTable("AllTeam")
|
||||
|
|
@ -289,6 +292,7 @@ export async function update({
|
|||
customUrl,
|
||||
bio,
|
||||
bsky,
|
||||
tag,
|
||||
css,
|
||||
})
|
||||
.where("id", "=", id)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ const DEFAULT_FIELDS = {
|
|||
name: "Team 1",
|
||||
bio: "",
|
||||
bsky: "",
|
||||
tag: "",
|
||||
} as const;
|
||||
|
||||
describe("team page editing", () => {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ export default function EditTeamPage() {
|
|||
<CustomizedColorsInput initialColors={css} />
|
||||
) : null}
|
||||
<NameInput />
|
||||
<TagInput />
|
||||
<BlueskyInput />
|
||||
<BioTextarea />
|
||||
<SubmitButton
|
||||
|
|
@ -174,6 +175,26 @@ function NameInput() {
|
|||
);
|
||||
}
|
||||
|
||||
function TagInput() {
|
||||
const { t } = useTranslation(["team"]);
|
||||
const { team } = useLoaderData<typeof loader>();
|
||||
const [value, setValue] = React.useState(team.tag ?? "");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Label htmlFor="tag">{t("team:forms.fields.tag")}</Label>
|
||||
<input
|
||||
id="tag"
|
||||
name="tag"
|
||||
maxLength={TEAM.TAG_MAX_LENGTH}
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
/>
|
||||
<FormMessage type="info">{t("team:forms.info.tag")}</FormMessage>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function BlueskyInput() {
|
||||
const { t } = useTranslation(["team"]);
|
||||
const { team } = useLoaderData<typeof loader>();
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ function TeamBanner() {
|
|||
})}
|
||||
</div>
|
||||
<div className="team__banner__name">
|
||||
{team.tag ? (
|
||||
<div className="team__banner__tag team__banner__tag__desktop">
|
||||
{team.tag}
|
||||
</div>
|
||||
) : null}
|
||||
{team.name} <BskyLink />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -124,6 +129,11 @@ function MobileTeamNameCountry() {
|
|||
{team.name}
|
||||
<BskyLink />
|
||||
</div>
|
||||
{team.tag ? (
|
||||
<div className="team__banner__tag team__banner__tag__mobile">
|
||||
{team.tag}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,12 +54,13 @@ export default function TeamSearchPage() {
|
|||
const [inputValue, setInputValue] = React.useState("");
|
||||
const data = useLoaderData<typeof loader>();
|
||||
|
||||
const filteredTeams = data.teams.filter((team) => {
|
||||
if (!inputValue) return true;
|
||||
const filteredTeams = () => {
|
||||
if (!inputValue) return data.teams;
|
||||
|
||||
const lowerCaseInput = inputValue.toLowerCase();
|
||||
|
||||
const matchingTeams = data.teams.filter((team) => {
|
||||
if (team.name.toLowerCase().includes(lowerCaseInput)) return true;
|
||||
if (team.tag && team.tag.toLowerCase() === lowerCaseInput) return true;
|
||||
if (
|
||||
team.members.some((m) =>
|
||||
m.username.toLowerCase().includes(lowerCaseInput),
|
||||
|
|
@ -71,6 +72,16 @@ export default function TeamSearchPage() {
|
|||
return false;
|
||||
});
|
||||
|
||||
return matchingTeams.sort((a, b) => {
|
||||
const aTagExactMatch = a.tag && a.tag.toLowerCase() === lowerCaseInput;
|
||||
const bTagExactMatch = b.tag && b.tag.toLowerCase() === lowerCaseInput;
|
||||
|
||||
if (aTagExactMatch && !bTagExactMatch) return -1;
|
||||
if (!aTagExactMatch && bTagExactMatch) return 1;
|
||||
return 0;
|
||||
});
|
||||
};
|
||||
|
||||
const {
|
||||
itemsToDisplay,
|
||||
everythingVisible,
|
||||
|
|
@ -80,7 +91,7 @@ export default function TeamSearchPage() {
|
|||
previousPage,
|
||||
setPage,
|
||||
} = usePagination({
|
||||
items: filteredTeams,
|
||||
items: filteredTeams(),
|
||||
pageSize: TEAMS_PER_PAGE,
|
||||
});
|
||||
|
||||
|
|
@ -125,6 +136,9 @@ export default function TeamSearchPage() {
|
|||
data-testid={`team-${i}`}
|
||||
>
|
||||
{team.name}
|
||||
{team.tag ? (
|
||||
<span className="team-search__team__tag">{team.tag}</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="team-search__team__members">
|
||||
{team.members.length === 1
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ export const TEAM = {
|
|||
NAME_MIN_LENGTH: 2,
|
||||
BIO_MAX_LENGTH: 2000,
|
||||
BSKY_MAX_LENGTH: 50,
|
||||
TAG_MAX_LENGTH: 6,
|
||||
MAX_MEMBER_COUNT: 10,
|
||||
MAX_TEAM_COUNT_NON_PATRON: 2,
|
||||
MAX_TEAM_COUNT_PATRON: 5,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ export const editTeamSchema = z.union([
|
|||
falsyToNull,
|
||||
z.string().max(TEAM.BSKY_MAX_LENGTH).nullable(),
|
||||
),
|
||||
tag: z.preprocess(
|
||||
falsyToNull,
|
||||
z.string().max(TEAM.TAG_MAX_LENGTH).nullable(),
|
||||
),
|
||||
css: customCssVarObject,
|
||||
}),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,15 @@
|
|||
color: var(--text-lighter);
|
||||
}
|
||||
|
||||
.team-search__team__tag {
|
||||
font-size: var(--fonts-xs);
|
||||
color: var(--theme);
|
||||
padding: var(--s-0-5) var(--s-1);
|
||||
border-radius: var(--rounded-xs);
|
||||
margin-left: var(--s-2);
|
||||
font-weight: var(--bold);
|
||||
}
|
||||
|
||||
.team-search__team__avatar-placeholder {
|
||||
height: 64px;
|
||||
min-width: 64px;
|
||||
|
|
@ -78,6 +87,7 @@
|
|||
display: none;
|
||||
align-items: center;
|
||||
gap: var(--s-3);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.team__bsky-link {
|
||||
|
|
@ -134,6 +144,27 @@
|
|||
gap: var(--s-2);
|
||||
}
|
||||
|
||||
.team__banner__tag {
|
||||
font-size: var(--fonts-sm);
|
||||
background-color: var(--theme-transparent);
|
||||
color: var(--theme);
|
||||
padding: var(--s-1) var(--s-1-5);
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
.team__banner__tag__desktop {
|
||||
position: absolute;
|
||||
bottom: 41px;
|
||||
right: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.team__banner__tag__mobile {
|
||||
font-size: var(--fonts-xs);
|
||||
padding: var(--s-0-5) var(--s-1);
|
||||
margin-block: var(--s-1);
|
||||
}
|
||||
|
||||
.team__banner__avatar img {
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
|
@ -301,6 +332,9 @@
|
|||
.team__banner__name {
|
||||
display: flex;
|
||||
}
|
||||
.team__banner__tag__desktop {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.team__banner__avatar > div {
|
||||
width: 10rem;
|
||||
|
|
|
|||
BIN
db-test.sqlite3
BIN
db-test.sqlite3
Binary file not shown.
|
|
@ -50,6 +50,25 @@ test.describe("Team search page", () => {
|
|||
|
||||
await expect(page).toHaveURL(/chimera/);
|
||||
});
|
||||
|
||||
test("filters teams by tag & displays tag", async ({ page }) => {
|
||||
await seed(page);
|
||||
await impersonate(page, ADMIN_ID);
|
||||
await navigate({ page, url: teamPage("alliance-rogue") });
|
||||
|
||||
await page.getByTestId("edit-team-button").click();
|
||||
await page.getByLabel("Tag").fill("AR");
|
||||
await page.getByTestId("edit-team-submit-button").click();
|
||||
|
||||
await navigate({ page, url: TEAM_SEARCH_PAGE });
|
||||
|
||||
const searchInput = page.getByTestId("team-search-input");
|
||||
await searchInput.fill("ar");
|
||||
|
||||
const firstTeamName = page.getByTestId("team-0");
|
||||
await expect(firstTeamName).toContainText("Alliance Rogue");
|
||||
await expect(firstTeamName).toContainText("AR");
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Team page", () => {
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Upload billeder",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Profilbillede",
|
||||
"forms.fields.uploadImages.banner": "Holdbanner",
|
||||
"forms.info.name": "Note: Hvis du ændrer dit holds navn, så kan andre hold overtage det tidligere holdnavn og URL-adresse.",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Holdnavnet er taget af et andet hold",
|
||||
"roster.teamFull": "Holdet kan ikke få flere medlemmer",
|
||||
"roster.inviteLink.header": "Del invitationslinket for at tilføje medlemmer",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Bilder hochladen",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Profilbild",
|
||||
"forms.fields.uploadImages.banner": "Teambild-Banner",
|
||||
"forms.info.name": "Hinweis: Wenn du den Namen deines Teams änderst, können andere Teams den Namen und und die URL für sich beanspruchen.",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Es gibt bereits ein Team mit diesem Namen",
|
||||
"roster.teamFull": "Team ist voll",
|
||||
"roster.inviteLink.header": "Teile den Einladungslink, um Mitglieder hinzuzufügen",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "Cheerleader",
|
||||
"forms.fields.teamBsky": "Team Bluesky",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "Tag",
|
||||
"forms.fields.uploadImages": "Upload images",
|
||||
"forms.fields.removeImages": "Remove images",
|
||||
"forms.fields.uploadImages.pfp": "Profile Picture",
|
||||
"forms.fields.uploadImages.banner": "Team Picture Banner",
|
||||
"forms.info.name": "Note that if you change your team's name then someone else can claim the name and URL for their team",
|
||||
"forms.info.tag": "Typically used before in-game name to indicate membership of a team (e.g. [TAG] PlayerName)",
|
||||
"forms.errors.duplicateName": "There is already a team with this name",
|
||||
"roster.teamFull": "Team is full",
|
||||
"roster.inviteLink.header": "Share invite link to add members",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Subir imágenes",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Imagen de perfil",
|
||||
"forms.fields.uploadImages.banner": "Banner del equipo",
|
||||
"forms.info.name": "Nota que si cambias el nombre de tu equipo, el nombre y la URL estarán libres para que otro equipo los tome",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Ya existe un equipo con ese nombre",
|
||||
"roster.teamFull": "El equipo esta lleno",
|
||||
"roster.inviteLink.header": "Comparte el link de invitación para agregar más miembros",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Subir imágenes",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Imagen de perfil",
|
||||
"forms.fields.uploadImages.banner": "Banner del equipo",
|
||||
"forms.info.name": "Nota que si cambias el nombre de tu equipo, el nombre y la URL estarán libres para que otro equipo los tome",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Ya existe un equipo con ese nombre",
|
||||
"roster.teamFull": "El equipo esta lleno",
|
||||
"roster.inviteLink.header": "Comparte el link de invitación para agregar más miembros",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Soumettre images",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Emblème",
|
||||
"forms.fields.uploadImages.banner": "Bannière d'équipe",
|
||||
"forms.info.name": "Veuillez noter que si vous changer le nom de l'équipe, quelqu'un d'autre pourra s'emparer de l'ancien nom et URL",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Il y a déjà une équipe avec ce nom",
|
||||
"roster.teamFull": "L'équipe est complète",
|
||||
"roster.inviteLink.header": "Partager le lien d'invitation pour ajouter des membres",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "Cheerleader",
|
||||
"forms.fields.teamBsky": "Team Bluesky",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Soumettre images",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Emblème",
|
||||
"forms.fields.uploadImages.banner": "Bannière d'équipe",
|
||||
"forms.info.name": "Veuillez noter que si vous changer le nom de l'équipe, quelqu'un d'autre pourra s'emparer de l'ancien nom et URL",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Il y a déjà une équipe avec ce nom",
|
||||
"roster.teamFull": "L'équipe est complète",
|
||||
"roster.inviteLink.header": "Partager le lien d'invitation pour ajouter des membres",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "ביו",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "העלאת תמונות",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "תמונת פרופיל",
|
||||
"forms.fields.uploadImages.banner": "תמונת באנר של הצוות",
|
||||
"forms.info.name": "שימו לב שאם תשנו את שם הצוות שלכם, מישהו אחר יוכל לקחת בעלות על השם ועל כתובת האתר עבור הצוות שלו",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "יש כבר צוות בשם הזה",
|
||||
"roster.teamFull": "הצוות מלא",
|
||||
"roster.inviteLink.header": "שיתוף קישור הזמנה להוספת חברי צוות",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "Cheerleader",
|
||||
"forms.fields.teamBsky": "Bluesky del team",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Carica immagini",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Foto profilo",
|
||||
"forms.fields.uploadImages.banner": "Foto banner del team",
|
||||
"forms.info.name": "Nota che se cambi il nome del team, qualcun altro può assumere nome e URL per il proprio team",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Esiste già un team con questo nome",
|
||||
"roster.teamFull": "Il team è completo",
|
||||
"roster.inviteLink.header": "Condividi link di invito per aggiungere membri",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "引き立て役(チアリーダー)",
|
||||
"forms.fields.teamBsky": "チームの Bluesky",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "画像をアップロード",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "プロファイル画像",
|
||||
"forms.fields.uploadImages.banner": "チーム画像バナー",
|
||||
"forms.info.name": "注意: チーム名を変更した場合、他のプレイヤーが変更前の名前と URL を別のチームのために使用することができるようになります。",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "そのチーム名はすでに使用されています",
|
||||
"roster.teamFull": "チームは満員です",
|
||||
"roster.inviteLink.header": "招待リンクを共有する",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "",
|
||||
"forms.fields.uploadImages.banner": "",
|
||||
"forms.info.name": "",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "",
|
||||
"roster.teamFull": "",
|
||||
"roster.inviteLink.header": "",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "",
|
||||
"forms.fields.uploadImages.banner": "",
|
||||
"forms.info.name": "",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "",
|
||||
"roster.teamFull": "",
|
||||
"roster.inviteLink.header": "",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Opis",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Wstaw zdjęcia",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Zdjęcie profilowe",
|
||||
"forms.fields.uploadImages.banner": "Grafika drużyny",
|
||||
"forms.info.name": "Uwaga: Jeśli zmienisz imię drużyny, ktoś inny może użyć twoje stare imię i URL",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Istnieje już drużyna o tym imieniu",
|
||||
"roster.teamFull": "Drużyna jest pełna",
|
||||
"roster.inviteLink.header": "Udostępnij link by dodać członków",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "Bio",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Fazer upload de imagens",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Imagem do perfil",
|
||||
"forms.fields.uploadImages.banner": "Capa do perfil",
|
||||
"forms.info.name": "Lembre-se que se você mudar o nome do seu time, alguém pode resgatar o nome e o URL para o time dele(a)",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Já existe um time com esse nome",
|
||||
"roster.teamFull": "O time está cheio",
|
||||
"roster.inviteLink.header": "Compartilhe o link de convite para adicionar membros",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "Чирлидер",
|
||||
"forms.fields.teamBsky": "Bluesky команды",
|
||||
"forms.fields.bio": "Описание",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "Загрузить изображения",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "Аватар команды",
|
||||
"forms.fields.uploadImages.banner": "Баннер команды",
|
||||
"forms.info.name": "Обратите внимание, что если вы измените название команды, то кто-то другой может забрать себе URL и название для своей команды",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "Уже существует команда с таким названием",
|
||||
"roster.teamFull": "Команда заполнена",
|
||||
"roster.inviteLink.header": "Поделитесь ссылкой на приглашение, чтобы добавить участников",
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
"roles.CHEERLEADER": "",
|
||||
"forms.fields.teamBsky": "",
|
||||
"forms.fields.bio": "简介",
|
||||
"forms.fields.tag": "",
|
||||
"forms.fields.uploadImages": "上传图片",
|
||||
"forms.fields.removeImages": "",
|
||||
"forms.fields.uploadImages.pfp": "头像",
|
||||
"forms.fields.uploadImages.banner": "队伍横幅",
|
||||
"forms.info.name": "请注意,如果您更改了队名,那么其他人便可以使用之前的队名和URL了。",
|
||||
"forms.info.tag": "",
|
||||
"forms.errors.duplicateName": "该队名已被使用",
|
||||
"roster.teamFull": "成员已满",
|
||||
"roster.inviteLink.header": "分享邀请链接来添加成员",
|
||||
|
|
|
|||
5
migrations/106-team-tag.js
Normal file
5
migrations/106-team-tag.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export function up(db) {
|
||||
db.transaction(() => {
|
||||
db.prepare(/* sql */ `alter table "AllTeam" add "tag" text`).run();
|
||||
})();
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user