diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index fc3353578..36fb5b105 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -9,6 +9,8 @@ - `npm run typecheck` runs TypeScript type checking - `npm run biome:fix` runs Biome code formatter and linter +- `npm run test:unit` runs all unit tests +- `npm run i18n:sync` syncs translation jsons with English and should always be run after adding new text to an English translation file ## Typescript @@ -46,7 +48,12 @@ - down migrations are not needed, only up migrations - every database id is of type number -## Playwright +## E2E testing +- library used for E2E testing is Playwright - `page.goto` is forbidden, use the `navigate` function to do a page navigation - to submit a form you use the `submit` function + +## Unit testing + +- library used for unit testing is Vitest diff --git a/app/features/notifications/notifications-types.ts b/app/features/notifications/notifications-types.ts index e76a0ebcd..a722c9a0c 100644 --- a/app/features/notifications/notifications-types.ts +++ b/app/features/notifications/notifications-types.ts @@ -62,7 +62,8 @@ export type Notification = > | NotificationItem<"SEASON_STARTED", { seasonNth: number }> | NotificationItem<"SCRIM_NEW_REQUEST", { fromUsername: string }> - | NotificationItem<"SCRIM_SCHEDULED", { id: number; at: number }>; + | NotificationItem<"SCRIM_SCHEDULED", { id: number; at: number }> + | NotificationItem<"SCRIM_CANCELED", { id: number; at: number }>; type NotificationItem< T extends string, diff --git a/app/features/notifications/notifications-utils.ts b/app/features/notifications/notifications-utils.ts index 33b1830c3..790c767d6 100644 --- a/app/features/notifications/notifications-utils.ts +++ b/app/features/notifications/notifications-utils.ts @@ -35,6 +35,7 @@ export const notificationNavIcon = (type: Notification["type"]) => { return "medal"; case "SCRIM_NEW_REQUEST": case "SCRIM_SCHEDULED": + case "SCRIM_CANCELED": return "scrims"; default: assertUnreachable(type); @@ -78,6 +79,7 @@ export const notificationLink = (notification: Notification) => { case "SCRIM_NEW_REQUEST": { return scrimsPage(); } + case "SCRIM_CANCELED": case "SCRIM_SCHEDULED": { return scrimPage(notification.meta.id); } @@ -91,7 +93,10 @@ export const mapMetaForTranslation = ( notification: Notification, language: string, ) => { - if (notification.type === "SCRIM_SCHEDULED") { + if ( + notification.type === "SCRIM_SCHEDULED" || + notification.type === "SCRIM_CANCELED" + ) { return { ...notification.meta, timeString: notification.meta.at // TODO: after two weeks this check can be removed (all notifications will have `at`) diff --git a/app/features/scrims/actions/scrims.$id.server.ts b/app/features/scrims/actions/scrims.$id.server.ts index 8b0cef28e..ad5f8575c 100644 --- a/app/features/scrims/actions/scrims.$id.server.ts +++ b/app/features/scrims/actions/scrims.$id.server.ts @@ -1,4 +1,5 @@ import type { ActionFunctionArgs } from "@remix-run/node"; +import { notify } from "~/features/notifications/core/notify.server"; import { requirePermission } from "~/modules/permissions/guards.server"; import { notFoundIfFalsy, @@ -6,10 +7,14 @@ import { parseRequestPayload, } from "~/utils/remix.server"; import { idObject } from "~/utils/zod"; -import { databaseTimestampToDate } from "../../../utils/dates"; +import { + databaseTimestampToDate, + databaseTimestampToJavascriptTimestamp, +} from "../../../utils/dates"; import { errorToast } from "../../../utils/remix.server"; import { requireUser } from "../../auth/core/user.server"; import * as ScrimPostRepository from "../ScrimPostRepository.server"; +import * as Scrim from "../core/Scrim"; import { cancelScrimSchema } from "../scrims-schemas"; export const action = async ({ request, params }: ActionFunctionArgs) => { @@ -33,5 +38,17 @@ export const action = async ({ request, params }: ActionFunctionArgs) => { reason: data.reason, }); + notify({ + userIds: Scrim.participantIdsListFromAccepted(post), + defaultSeenUserIds: [user.id], + notification: { + type: "SCRIM_CANCELED", + meta: { + id: post.id, + at: databaseTimestampToJavascriptTimestamp(post.at), + }, + }, + }); + return null; }; diff --git a/app/features/scrims/core/Scrim.test.ts b/app/features/scrims/core/Scrim.test.ts new file mode 100644 index 000000000..0e28315d3 --- /dev/null +++ b/app/features/scrims/core/Scrim.test.ts @@ -0,0 +1,78 @@ +import { describe, expect, it } from "vitest"; +import type { ScrimPost } from "../scrims-types"; +import { participantIdsListFromAccepted } from "./Scrim"; + +type MockUser = { id: number }; +type MockRequest = { isAccepted: boolean; users: MockUser[] }; + +function createPost(users: MockUser[], requests: MockRequest[]): ScrimPost { + return { + id: 1, + users, + requests, + createdAt: "", + updatedAt: "", + title: "", + description: "", + status: "open", + authorId: 0, + } as unknown as ScrimPost; +} + +describe("participantIdsListFromAccepted", () => { + it("returns only post users if no accepted request", () => { + const post = createPost( + [{ id: 10 }, { id: 20 }], + [ + { + isAccepted: false, + users: [{ id: 30 }], + }, + ], + ); + + const result = participantIdsListFromAccepted(post); + expect(result).toEqual([10, 20]); + }); + + it("returns post users and accepted request users", () => { + const post = createPost( + [{ id: 10 }, { id: 20 }], + [ + { + isAccepted: false, + users: [{ id: 30 }], + }, + { + isAccepted: true, + users: [{ id: 40 }, { id: 50 }], + }, + ], + ); + + const result = participantIdsListFromAccepted(post); + expect(result).toEqual([10, 20, 40, 50]); + }); + + it("returns post users if accepted request has no users", () => { + const post = createPost( + [{ id: 10 }], + [ + { + isAccepted: true, + users: [], + }, + ], + ); + + const result = participantIdsListFromAccepted(post); + expect(result).toEqual([10]); + }); + + it("returns empty array if no users and no accepted request", () => { + const post = createPost([], []); + + const result = participantIdsListFromAccepted(post); + expect(result).toEqual([]); + }); +}); diff --git a/app/features/scrims/core/Scrim.ts b/app/features/scrims/core/Scrim.ts index a10537e2c..1b96fd94c 100644 --- a/app/features/scrims/core/Scrim.ts +++ b/app/features/scrims/core/Scrim.ts @@ -1,3 +1,4 @@ +import { logger } from "~/utils/logger"; import type { ScrimPost } from "../scrims-types"; /** Returns true if the original poster has accepted any of the requests. */ @@ -17,3 +18,20 @@ export function isParticipating(post: ScrimPost, userId: number) { export function resolvePoolCode(postId: number) { return `SC${postId % 10}`; } + +/** + * Returns an array of participant IDs from the given post object that is accepted (scrim page exists). + */ +export function participantIdsListFromAccepted(post: ScrimPost) { + const acceptedRequest = post.requests.find((r) => r.isAccepted); + + if (!acceptedRequest) { + logger.warn( + `Scrim post ${post.id} has no accepted request, returning only post users.`, + ); + } + + return post.users + .map((u) => u.id) + .concat(acceptedRequest?.users.map((u) => u.id) ?? []); +} diff --git a/app/features/scrims/loaders/scrims.$id.server.ts b/app/features/scrims/loaders/scrims.$id.server.ts index 4a5eeb3f1..748caf66d 100644 --- a/app/features/scrims/loaders/scrims.$id.server.ts +++ b/app/features/scrims/loaders/scrims.$id.server.ts @@ -26,9 +26,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { return { post, chatUsers: await UserRepository.findChatUsersByUserIds( - post.users - .map((u) => u.id) - .concat(post.requests.at(0)?.users.map((u) => u.id) ?? []), + Scrim.participantIdsListFromAccepted(post), ), }; }; diff --git a/locales/da/common.json b/locales/da/common.json index 41c3506ec..94220bf12 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "logindforsøg afbrudt", "auth.errors.failed": "Loginforsøg fejlet", "auth.errors.discordPermissions": "Før at du kan oprette en profil på sendou.ink, skal sendou.ink have adgang til din Discordprofils navn, brugerbillede og sociale forbindelser (de sociale medier, som du har tilknyttet din discordprofil).", diff --git a/locales/da/scrims.json b/locales/da/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/da/scrims.json +++ b/locales/da/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/de/common.json b/locales/de/common.json index 76fb728e5..336deed5a 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Einloggen abgebrochen", "auth.errors.failed": "Einloggen fehlgeschlagen", "auth.errors.discordPermissions": "Für dein sendou.ink-Profil benötigt die Seite Zugriff auf den Namen, Avatar und verbundene Social-Media-Accounts in deinem Discord-Profil.", diff --git a/locales/de/scrims.json b/locales/de/scrims.json index 8d9ab146e..4dcb95300 100644 --- a/locales/de/scrims.json +++ b/locales/de/scrims.json @@ -13,6 +13,7 @@ "pickup": "Pickup von {{username}}", "status.booked": "Gebucht", "status.pending": "Ausstehend", + "status.canceled": "", "actions.request": "Anfragen", "deleteModal.title": "Scrim post löschen?", "deleteModal.prevented": "Der Post muss von Ersteller ({{username}}) gelöscht werden.", diff --git a/locales/en/common.json b/locales/en/common.json index 2fea2a2b3..6984e90cb 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "{{fromUsername}} requested a scrim", "notifications.title.SCRIM_SCHEDULED": "Scrim Scheduled", "notifications.text.SCRIM_SCHEDULED": "New scrim scheduled at {{timeString}}", + "notifications.title.SCRIM_CANCELED": "Scrim Canceled", + "notifications.text.SCRIM_CANCELED": "The scrim at {{timeString}} was canceled", "auth.errors.aborted": "Login Aborted", "auth.errors.failed": "Login Failed", "auth.errors.discordPermissions": "For your sendou.ink profile, the site needs access to your Discord profile's name, avatar and social connections.", diff --git a/locales/es-ES/common.json b/locales/es-ES/common.json index d347ddc2b..97987d7ac 100644 --- a/locales/es-ES/common.json +++ b/locales/es-ES/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Ingreso cancelado", "auth.errors.failed": "Ingreso fallido", "auth.errors.discordPermissions": "Para tu perfil en sendou.ink, el sitio requiere aceso a tu nombre en Discord, avatar, y redes sociales.", diff --git a/locales/es-ES/scrims.json b/locales/es-ES/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/es-ES/scrims.json +++ b/locales/es-ES/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/es-US/common.json b/locales/es-US/common.json index fce949d83..363a6c677 100644 --- a/locales/es-US/common.json +++ b/locales/es-US/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Ingreso cancelado", "auth.errors.failed": "Ingreso fallido", "auth.errors.discordPermissions": "Para tu perfil en sendou.ink, el sitio requiere aceso a tu nombre en Discord, avatar, y redes sociales.", diff --git a/locales/es-US/scrims.json b/locales/es-US/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/es-US/scrims.json +++ b/locales/es-US/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/fr-CA/common.json b/locales/fr-CA/common.json index b6be25305..72054cb88 100644 --- a/locales/fr-CA/common.json +++ b/locales/fr-CA/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Connexion abandonnée", "auth.errors.failed": "Connexion échouée", "auth.errors.discordPermissions": "Pour mettre en place votre profil, sendou.ink a besoin de votre nom de profil Discord, de votre avatar et de vos réseaux connectés.", diff --git a/locales/fr-CA/scrims.json b/locales/fr-CA/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/fr-CA/scrims.json +++ b/locales/fr-CA/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/fr-EU/common.json b/locales/fr-EU/common.json index dd46fd606..c0ed5b033 100644 --- a/locales/fr-EU/common.json +++ b/locales/fr-EU/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "{{fromUsername}} vous demande de scrim", "notifications.title.SCRIM_SCHEDULED": "Scrim Programmé", "notifications.text.SCRIM_SCHEDULED": "Nouveau scrim programmé à {{timeString}}", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Connexion abandonnée", "auth.errors.failed": "Connexion échouée", "auth.errors.discordPermissions": "Pour mettre en place votre profil, sendou.ink a besoin de votre nom de profil Discord, de votre avatar et de vos réseaux connectés.", diff --git a/locales/fr-EU/scrims.json b/locales/fr-EU/scrims.json index e55765849..193f28843 100644 --- a/locales/fr-EU/scrims.json +++ b/locales/fr-EU/scrims.json @@ -13,6 +13,7 @@ "pickup": "Pickup de {{username}}", "status.booked": "Réservé", "status.pending": "En attente", + "status.canceled": "", "actions.request": "Demande", "deleteModal.title": "Supprimer le post?", "deleteModal.prevented": "Le post doit être supprimée par le propriétaire ({{username}})", diff --git a/locales/he/common.json b/locales/he/common.json index 5c172b5ad..f4fbc3f72 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "הכניסה בוטלה", "auth.errors.failed": "הכניסה נכשלה", "auth.errors.discordPermissions": "עבור פרופיל sendou.ink שלך, האתר זקוק לגישה לשם, הפרופיל והקשרים החברתיים של פרופיל ה-Discord שלך.", diff --git a/locales/he/scrims.json b/locales/he/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/he/scrims.json +++ b/locales/he/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/it/common.json b/locales/it/common.json index 476aa4bbb..a535f9978 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Accesso cancellato", "auth.errors.failed": "Accesso fallito", "auth.errors.discordPermissions": "Per il tuo profilo di sendou.ink, il sito ha bisogno di accesso al nome utente, avatar e connessioni social del tuo profilo Discord.", diff --git a/locales/it/scrims.json b/locales/it/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/it/scrims.json +++ b/locales/it/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/ja/common.json b/locales/ja/common.json index 1b491c640..ce83a9b23 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "ログインを中断しました", "auth.errors.failed": "ログインに失敗しました", "auth.errors.discordPermissions": "sendou.ink は、Discord のプロファイル名、アバター、SNS連携をサイトのプロファイルに使用します。", diff --git a/locales/ja/scrims.json b/locales/ja/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/ja/scrims.json +++ b/locales/ja/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/ko/common.json b/locales/ko/common.json index c3e1565b6..336275b6e 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "로그인 중단됨", "auth.errors.failed": "로그인 실패", "auth.errors.discordPermissions": "sendou.ink 프로필을 위해 디스코드 프로필의 이름, 아바타와 연락처에 대한 접근이 필요합니다.", diff --git a/locales/ko/scrims.json b/locales/ko/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/ko/scrims.json +++ b/locales/ko/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/nl/common.json b/locales/nl/common.json index 55af941f8..ba3906c58 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "", "auth.errors.failed": "", "auth.errors.discordPermissions": "", diff --git a/locales/nl/scrims.json b/locales/nl/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/nl/scrims.json +++ b/locales/nl/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/pl/common.json b/locales/pl/common.json index bef430900..5960c8af0 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Logowanie przerwane", "auth.errors.failed": "Logowanie nieudane", "auth.errors.discordPermissions": "Do twojego profilu sendou.ink, ta strona potrzebuje dostęp do twojej nazwy, avataru i połączeń konta Discord.", diff --git a/locales/pl/scrims.json b/locales/pl/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/pl/scrims.json +++ b/locales/pl/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/pt-BR/common.json b/locales/pt-BR/common.json index 6412fec59..a0f8b6faa 100644 --- a/locales/pt-BR/common.json +++ b/locales/pt-BR/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Login Abortado", "auth.errors.failed": "Login Falhou", "auth.errors.discordPermissions": "Para o seu perfil do sendou.ink, o site precisa de acesso ao nome do perfil do seu Discord, incluindo também o avatar e conexões sociais.", diff --git a/locales/pt-BR/scrims.json b/locales/pt-BR/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/pt-BR/scrims.json +++ b/locales/pt-BR/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/ru/common.json b/locales/ru/common.json index 046838ca7..d058dee71 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "{{fromUsername}} запросил скрим", "notifications.title.SCRIM_SCHEDULED": "Скрим Запланирован", "notifications.text.SCRIM_SCHEDULED": "Новый скрим запланирован на {{timeString}}", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "Вход отменён", "auth.errors.failed": "Ошибка входа", "auth.errors.discordPermissions": "Для вашего профиля на sendou.ink странице нужен доступ к вашему имени, аватару и привязанным аккаунтам соц. сетей в Discord.", diff --git a/locales/ru/scrims.json b/locales/ru/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/ru/scrims.json +++ b/locales/ru/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "", diff --git a/locales/zh/common.json b/locales/zh/common.json index d845a2aae..a91e858cb 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -75,6 +75,8 @@ "notifications.text.SCRIM_NEW_REQUEST": "", "notifications.title.SCRIM_SCHEDULED": "", "notifications.text.SCRIM_SCHEDULED": "", + "notifications.title.SCRIM_CANCELED": "", + "notifications.text.SCRIM_CANCELED": "", "auth.errors.aborted": "登录中止", "auth.errors.failed": "登录失败", "auth.errors.discordPermissions": "为了完善您的sendou.ink个人资料,网站需要获取您的Discord名字、头像和社交链接。", diff --git a/locales/zh/scrims.json b/locales/zh/scrims.json index 28634532d..aab3bf8ec 100644 --- a/locales/zh/scrims.json +++ b/locales/zh/scrims.json @@ -13,6 +13,7 @@ "pickup": "", "status.booked": "", "status.pending": "", + "status.canceled": "", "actions.request": "", "deleteModal.title": "", "deleteModal.prevented": "",