diff --git a/.gitignore b/.gitignore index 304f809..6d8036d 100644 --- a/.gitignore +++ b/.gitignore @@ -49,4 +49,6 @@ node_modules/ /playwright/.auth/ # eslint -.eslintcache \ No newline at end of file +.eslintcache +.pytest_cache/ +__pycache__/ diff --git a/package-lock.json b/package-lock.json index 3944405..232a843 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "granda-front", - "version": "0.3.16", + "version": "0.3.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "granda-front", - "version": "0.3.16", + "version": "0.3.17", "dependencies": { "@radix-ui/react-dropdown-menu": "^2.1.6", "@radix-ui/react-select": "^2.2.6", diff --git a/package.json b/package.json index 0fdcebf..c767d80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "granda-front", - "version": "0.3.16", + "version": "0.3.17", "private": true, "scripts": { "dev": "next dev --turbopack", diff --git a/scripts/i18ndiffer/.python-version b/scripts/i18ndiffer/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/scripts/i18ndiffer/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/scripts/i18ndiffer/README.md b/scripts/i18ndiffer/README.md new file mode 100644 index 0000000..c2f41e3 --- /dev/null +++ b/scripts/i18ndiffer/README.md @@ -0,0 +1,6 @@ +This utility can be used to add missing lines to i18n files while preserving their line-by-line structure. + +Usage: +```bash +diff -y [file1] [file2] | uv run src/main.py [file1] [file2] +``` diff --git a/scripts/i18ndiffer/pyproject.toml b/scripts/i18ndiffer/pyproject.toml new file mode 100644 index 0000000..40e4acf --- /dev/null +++ b/scripts/i18ndiffer/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "i18ndiffer" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "pytest>=9.0.3", +] diff --git a/scripts/i18ndiffer/src/__init__.py b/scripts/i18ndiffer/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/i18ndiffer/src/main.py b/scripts/i18ndiffer/src/main.py new file mode 100644 index 0000000..c169e2c --- /dev/null +++ b/scripts/i18ndiffer/src/main.py @@ -0,0 +1,47 @@ +import re +import sys + + +def main(): + path1, path2 = sys.argv[1], sys.argv[2] + diff_file: str = sys.stdin.read() + diff_lines = diff_file.split("\n") + lines1, lines2 = read_lines_from_files(path1, path2) + file1, file2 = insert_missing_lines(lines1, lines2, diff_lines) + + with open(path1, "w") as f: + f.writelines(file1) + with open(path2, "w") as f: + f.writelines(file2) + + +def insert_missing_lines(lines1: list[str], lines2: list[str], diff_lines: list[str]): + for i in range(len(diff_lines)): + if diff_lines[i].endswith("<"): + lines2.insert(i, prepare_placeholder_from(lines1[i])) + elif diff_lines[i].lstrip().startswith(">"): + lines1.insert(i, prepare_placeholder_from(lines2[i])) + + return lines1, lines2 + + +def read_lines_from_files(path1, path2): + lines1 = [] + lines2 = [] + + with open(path1, "r") as f1: + lines1 = f1.readlines() + f1.close() + with open(path2, "r") as f2: + lines2 = f2.readlines() + f2.close() + return lines1, lines2 + + +def prepare_placeholder_from(line: str) -> str: + capture_key_without_value_pattern = r'(\s*".+":\s*")(.+".*)' + return re.sub(capture_key_without_value_pattern, r"\1[CHANGE ME!] \2", line) + + +if __name__ == "__main__": + main() diff --git a/scripts/i18ndiffer/test/__init__.py b/scripts/i18ndiffer/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/i18ndiffer/test/test_diffing.py b/scripts/i18ndiffer/test/test_diffing.py new file mode 100644 index 0000000..85ef95e --- /dev/null +++ b/scripts/i18ndiffer/test/test_diffing.py @@ -0,0 +1,98 @@ +import re + +from src.main import insert_missing_lines, prepare_placeholder_from + + +def test_preparing_placeholders_basic(): + assert ( + prepare_placeholder_from(' "msg_handle_empty": "Handle must not be empty.",') + == ' "msg_handle_empty": "[CHANGE ME!] Handle must not be empty.",' + ) + + +def test_preparing_placeholders_with_curly_braces(): + assert ( + prepare_placeholder_from(' "error_message": "Details: {message}"') + == ' "error_message": "[CHANGE ME!] Details: {message}"' + ) + + +def test_instert_lines_right_to_left(): + diff_file = [ + ' "debate_details": { "debate_details": {', + ' "unconfigured_debate": "Debata bez tezy" | "unconfigured_debate": "Debate without a motion",', + ' > "proceed_to_debate": "Proceed to Debate!",', + ' > "marshal_panel": "Marshal Panel"', + " > },", + ' > "create_tournament": {', + ' > "title": "Create Tournament",', + ' > "full_name": "Full name",', + ] + + file1 = [ + ' "debate_details": {', + ' "unconfigured_debate": "Debata bez tezy"', + " }", + "}", + ] + file2 = [ + ' "debate_details": {', + ' "unconfigured_debate": "Debate without a motion",', + ' "proceed_to_debate": "Proceed to Debate!",', + ' "marshal_panel": "Marshal Panel"', + " },", + ' "create_tournament": {', + ' "title": "Create Tournament",', + ' "full_name": "Full name",', + ' "short_name": "Short name",', + ' "close": "Close",', + ' "full_name_placeholder": "(Required)"', + " },", + ] + + file1, file2 = insert_missing_lines(file1, file2, diff_file) + + empty_value_pattern = r'(\s*".+":\s*"".*)' + + value_to_change_pattern = r'(\s*".+":\s*"\[CHANGE ME!\].+".*)' + for line in file1: + if not re.findall(r"debate|{|}", line): + assert re.match(value_to_change_pattern, line) + + +def test_insert_lines_left_to_right(): + diff_file = [ + ' "metadata": { "metadata": {', + ' "title": "granda: Debate Tournament Planner", | "title": "granda: Zaplanuj swój turniej debat",', + ' "description": "Computer aided debate tournament organizi | "description": "Komputerowo wspomagane planowanie turniej', + " }, <", + ' "generic": { <', + ' "error": "Error", <', + ' "error_loading_content": "An error occurred while loading <', + ' "error_message": "Details: {message}" <', + " }, },", + ] + file1 = [ + ' "metadata": {', + ' "title": "granda: Debate Tournament Planner",', + ' "description": "Computer aided debate tournament organizing experience enrichment."', + " },", + ' "generic": {', + ' "error": "Error",', + ' "error_loading_content": "An error occurred while loading the content.",', + ' "error_message": "Details: {message}"', + " },", + ] + file2 = [ + ' "metadata": {', + ' "title": "granda: Zaplanuj swój turniej debat",', + ' "description": "Komputerowo wspomagane planowanie turniejów debat."', + " },", + ] + + file1, file2 = insert_missing_lines(file1, file2, diff_file) + + value_to_change_pattern = r'(\s*".+":\s*"\[CHANGE ME!\].+".*)' + for line in file2: + if line.__contains__("error"): + assert re.match(value_to_change_pattern, line) diff --git a/scripts/i18ndiffer/uv.lock b/scripts/i18ndiffer/uv.lock new file mode 100644 index 0000000..cb6098e --- /dev/null +++ b/scripts/i18ndiffer/uv.lock @@ -0,0 +1,75 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "i18ndiffer" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [{ name = "pytest", specifier = ">=9.0.3" }] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, +] diff --git a/src/app/[locale]/t/[path]/debates/[debate_id]/page.tsx b/src/app/[locale]/t/[path]/debates/[debate_id]/page.tsx index 419b4a8..c85e2c3 100644 --- a/src/app/[locale]/t/[path]/debates/[debate_id]/page.tsx +++ b/src/app/[locale]/t/[path]/debates/[debate_id]/page.tsx @@ -118,41 +118,29 @@ export default async function DebateDetailsPage({

- {" "} - {motion}{" "} + {motion}

ret
-
-
- {" "} - {/*{phaseName} | {roundName}{" "}*/} -
-
+
- -
- {" "} - Information about assigned Marshal will be presented here.{" "} -
+ +
{t("time_and_place_info.placeholder_text")}
+
+ + +
{t("teams_info.placeholder_text")}
- -
- {" "} - Information about assigned Judges will be presented here.{" "} -
+ +
{t("marshal_info.placeholder_text")}
- -
- {" "} - Information about time and place of the debate will be presented - here.{" "} -
+ +
{t("judges_info.placeholder_text")}
diff --git a/src/components/tournament/MarshalPanel.tsx b/src/components/tournament/MarshalPanel.tsx index e80c2f0..41e5674 100644 --- a/src/components/tournament/MarshalPanel.tsx +++ b/src/components/tournament/MarshalPanel.tsx @@ -15,7 +15,6 @@ export function MarshalPanel({ motion }: MarshalPanelProps) { return ( = ({ tournamentId, debateId, }) => { - const [isJudge, setIsJudge] = useState(null); + const [canSubmitVerdict, setCanSubmitVerdict] = useState( + null, + ); const [verdicts, setVerdicts] = useState([]); const [selectedVote, setSelectedVote] = useState(null); const [submitting, setSubmitting] = useState(false); @@ -50,9 +52,9 @@ const VerdictPanel: React.FC = ({ return null; } - if (counts.proposition > counts.opposition) return "Proposition"; - if (counts.opposition > counts.proposition) return "Opposition"; - return "Tie"; + if (counts.proposition > counts.opposition) return "proposition"; + if (counts.opposition > counts.proposition) return "opposition"; + return "no_verdict"; }, [verdicts]); useEffect(() => { @@ -74,7 +76,7 @@ const VerdictPanel: React.FC = ({ }), ]) .then(([permissionData, verdictsData]) => { - setIsJudge(Boolean(permissionData)); + setCanSubmitVerdict(Boolean(permissionData)); const loadedVerdicts: VerdictRecord[] = Array.isArray(verdictsData) ? verdictsData : []; @@ -184,9 +186,37 @@ const VerdictPanel: React.FC = ({ ); } + const VerdictInformation = () => { + return ( +
+
+ <> + + {t.rich(`majority.${majorityVerdict ?? "no_verdict"}`, { + highlight: (chunks) => ( + + {chunks} + + ), + })} + + +
+
+ ); + }; + return ( - - {isJudge ? ( + + {canSubmitVerdict ? (
- -
-
- {majorityVerdict === "Proposition" ? ( - <> - - {t("majority.proposition.prefix")} - - - - {t("majority.proposition.highlight")} - - - - {t("majority.proposition.suffix")} - - - ) : majorityVerdict === "Opposition" ? ( - <> - - {t("majority.opposition.prefix")} - - - - {t("majority.opposition.highlight")} - - - - {t("majority.opposition.suffix")} - - - ) : ( - <> - - {t("majority.no_verdict.prefix")} - - - - {t("majority.no_verdict.highlight")} - - - - {t("majority.no_verdict.suffix")} - - - )} -
-
+
) : ( -
+ )}
); diff --git a/src/i18n/translations/en.json b/src/i18n/translations/en.json index ca00678..22a6f1c 100644 --- a/src/i18n/translations/en.json +++ b/src/i18n/translations/en.json @@ -96,8 +96,6 @@ "advancing_teams": "Advancing teams", "submit": "Plan tournament", "submitting": "Planning...", - "placeholder_title": "Tournament ladder", - "placeholder_description": "Tournament ladder placeholder.", "no_phases_error": "Failed to load tournament phases.", "validation_positive_integer": "This value must be a positive integer.", "validation_power_of_two": "Advancing teams must be a power of 2.", @@ -111,7 +109,7 @@ "total_teams_hint": "The total number of teams taking part in the tournament.", "advancing_teams_hint": "Defines how many teams advance from the group phase to the finals phase. Must be a power of 2.", "hint_title": "Tournament Ladder", - "hint_content": "Each box represents a debate. You can click on a specific box to see the debate details. The ladder shows the structure and flow of the tournament, including the rounds and how debates are organised." + "hint_content": "Each box represents a debate. You can click on a specific box to see the debate details. The ladder visualizes the flow of the tournament." }, "debates": { "title": "Debates" @@ -128,7 +126,23 @@ "debate_details": { "unconfigured_debate": "Debate without a motion", "proceed_to_debate": "Proceed to Debate!", - "marshal_panel": "Marshal Panel" + "marshal_panel": "Marshal Panel", + "marshal_info": { + "title": "Marshal", + "placeholder_text": "Information about assigned Marshal will be presented here." + }, + "judges_info": { + "title": "Judges", + "placeholder_text": "Information about assigned Judges will be presented here." + }, + "time_and_place_info": { + "title": "Time and place", + "placeholder_text": "Information about time and place of the debate will be presented here" + }, + "teams_info": { + "title": "Teams", + "placeholder_text": "Information about competing teams will be presented here" + } }, "create_tournament": { "title": "Create Tournament", @@ -138,6 +152,7 @@ "full_name_placeholder": "(Required)" }, "verdict_panel": { + "title": "Verdict", "proposition": "Proposition", "opposition": "Opposition", "submit": "Submit", @@ -151,21 +166,9 @@ "load_verdicts_error": "Unable to load verdict information", "panel_error_title": "Verdict panel got an error, oops:", "majority": { - "proposition": { - "prefix": "The", - "highlight": "Proposition", - "suffix": "is the winning team!" - }, - "opposition": { - "prefix": "The", - "highlight": "Opposition", - "suffix": "is the winning team!" - }, - "no_verdict": { - "prefix": "There is", - "highlight": "no verdict", - "suffix": "yet." - } + "proposition": "The Proposition is the winning team!", + "opposition": "The Opposition is the winning team!", + "no_verdict": "There is no verdict available yet." } } } diff --git a/src/i18n/translations/pl.json b/src/i18n/translations/pl.json index 6be9052..9b9faeb 100644 --- a/src/i18n/translations/pl.json +++ b/src/i18n/translations/pl.json @@ -65,30 +65,110 @@ "footer_text": "Komputerowe wspomaganie debat dostarcza ." }, "overview": { - "title": "Panel główny" + "title": "Panel główny", + "welcome": "Witaj w turnieju {tournamentName}!", + "get_started": "Aby rozpocząć, przejdź do Drabinki Turniejowej, aby zaplanować przebieg turnieju.", + "leaderboard_placeholder": "Wyniki drużyn (już wkrótce!)", + "leaderboard_desc": "Tutaj znajdzie się tabela z wynikami drużyn biorących udział w turnieju.", + "debates_placeholder": "Nadchodzące debaty (już wkrótce!)", + "debates_desc": "Tutaj znajdą się informacje o najbliższych zaplanowanych debatach.", + "event_log_placeholder": "Dziennik zdarzeń (już wkrótce!)", + "event_log_desc": "Tutaj zapisywane będą działania wykonywane przez użytkowników biorących udział w turnieju.", + "rules_placeholder": "Zasady turnieju (już wkrótce!)", + "rules_desc": "Tutaj pojawią się skrócone zasady turnieju." }, "metadata": { "title": "granda: Zaplanuj swój turniej debat", "description": "Komputerowo wspomagane planowanie turniejów debat." }, + "generic": { + "error": "Błąd", + "error_loading_content": "Wystąpił błąd.", + "error_message": "Szczegóły: {message}" + }, "ladder": { "title": "Drabinka turniejowa", "planning_title": "Planowanie turnieju", "planning_description": "Ustaw podstawowe parametry, aby wygenerować drabinkę turniejową.", "group_phase_rounds": "Liczba rund fazy grupowej", "groups_count": "Liczba grup", + "total_teams": "Łączna liczba drużyn", "advancing_teams": "Liczba awansujących drużyn", "submit": "Zaplanuj turniej", "submitting": "Planowanie...", - "placeholder_title": "Drabinka turniejowa", - "placeholder_description": "Placeholder drabinki turniejowej.", "no_phases_error": "Nie udało się pobrać faz turnieju.", - "validation_positive_integer": "Ta wartość musi być dodatnią liczbą całkowitą.", + "validation_positive_integer": "Parametry muszą być dodatnimi liczbami całkowitymi.", "validation_power_of_two": "Liczba awansujących drużyn musi być potęgą 2.", + "validation_groups_and_teams": "Liczba grup nie może być mniejsza niż łączna liczba drużyn.", "request_failed": "Nie udało się zaplanować turnieju.", - "success": "Planowanie turnieju zakończone powodzeniem." + "success": "Planowanie turnieju zakończone powodzeniem.", + "unconfigured_debate": "Nieskonfigurowana debata", + "advancing_teams_placeholder": "2, 4, 8, 16…", + "group_rounds_hint": "Określa, ile rund nastąpi po sobie w fazie grupowej.", + "groups_count_hint": "Podczas każdej rundy w każdej grupie odbywa się osobna debata. Ta liczba określa, ile debat odbędzie się jednocześnie. Musi być mniejsza niż łączna liczba drużyn.", + "total_teams_hint": "Łączna liczba drużyn biorących udział w turnieju.", + "advancing_teams_hint": "Liczba drużyn, które awansują do fazy pucharowej. Musi być potęgą 2.", + "hint_title": "Drabinka turniejowa", + "hint_content": "Każdy kafelek reprezentuje debatę. Możesz kliknąć na kafelek, by zobaczyć szczegóły debaty. Drabinka przedstawia przebieg turnieju." + }, + "debates": { + "title": "Debaty" + }, + "round_config": { + "title": "Konfiguracja rundy {name}", + "motion_title": "Teza", + "motion_description": "O czym będzie ta debata?", + "motion_placeholder": "(Wymagane)", + "infoslide_title": "Infoslajd", + "infoslide_description": "Dodatkowe informacje na temat tezy", + "apply": "Zastosuj" }, "debate_details": { - "unconfigured_debate": "Debata bez tezy" + "unconfigured_debate": "Debata bez tezy", + "proceed_to_debate": "Przejdź do debaty!", + "marshal_panel": "Panel marszałka", + "marshal_info": { + "title": "Marszałek", + "placeholder_text": "Informacja o marszałku przypisanym do debaty pojawi się tutaj." + }, + "judges_info": { + "title": "Sędziowie", + "placeholder_text": "Informacje o panelu sędziowskim przypisanym do tej debaty pojawią się tutaj." + }, + "time_and_place_info": { + "title": "Czas i miejsce", + "placeholder_text": "Informacje o czasie oraz miejscu debaty pojawią się tutaj." + }, + "teams_info": { + "title": "Teams", + "placeholder_text": "Informacje o drużynach biorących udział w debacie pojawią się tutaj." + } + }, + "create_tournament": { + "title": "Utwórz turniej", + "full_name": "Pełna nazwa", + "short_name": "Skrócona nazwa", + "close": "Zamknij", + "full_name_placeholder": "(Wymagane)" + }, + "verdict_panel": { + "title": "Werdykt", + "proposition": "Propozycja", + "opposition": "Opozycja", + "submit": "Wyślij", + "select_verdict_error": "Wybierz stronę przed wysłaniem werdyktu.", + "submit_error": "Nie udało się wysłać werdyktu", + "failed_submit": "Nie udało się utworzyć werdyktu", + "failed_update": "Nie udało się zaktualizować werdyktu", + "no_existing_verdict": "Aktualizowany werdykt nie istnieje", + "failed_load_permissions": "Nie udało się wczytać uprawnień", + "failed_load_verdicts": "Nie udało się wczytać werdyktów", + "load_verdicts_error": "Nie udało się wczytać informacji o werdykcie", + "panel_error_title": "Błąd w panelu werdyktu", + "majority": { + "proposition": "Wygrała drużyna Propozycji!", + "opposition": "Wygrała drużyna Opozycji!", + "no_verdict": "Jeszcze nie opublikowano werdyktu" + } } } diff --git a/test/e2e/tournament-ladder-rendering.test.ts b/test/e2e/tournament-ladder-rendering.test.ts index 732c6db..e40f47d 100644 --- a/test/e2e/tournament-ladder-rendering.test.ts +++ b/test/e2e/tournament-ladder-rendering.test.ts @@ -60,7 +60,7 @@ testInTournamentAsAdmin( page.getByText("You can click on a specific box"), ).toBeVisible(); await expect( - page.getByText("The ladder shows the structure and flow"), + page.getByText("The ladder visualizes the flow of the tournament"), ).toBeVisible(); // WHEN diff --git a/test/e2e/verdictPanel.test.ts b/test/e2e/verdictPanel.test.ts index d2bf75b..71fd262 100644 --- a/test/e2e/verdictPanel.test.ts +++ b/test/e2e/verdictPanel.test.ts @@ -7,6 +7,9 @@ import { createUserAndCastVote, } from "./e2eUtils"; +const PROPOSITION_WINNING_TEXT = "The Proposition is the"; +const OPPOSITION_WINNING_TEXT = "The Opposition is the"; + test.describe("verdict panel", () => { testInTournamentAsAdmin( "judge permission renders verdict submission options", @@ -49,8 +52,9 @@ test.describe("verdict panel", () => { .first() .click(); - await expect(page.getByText("Verdict panel")).toBeVisible(); + await expect(page.getByText("Verdict", { exact: true })).toBeVisible(); await expect(page.getByText("Opposition")).not.toBeVisible(); + await expect(page.getByText("no verdict")).toBeVisible(); }, ); @@ -86,8 +90,7 @@ test.describe("verdict panel", () => { .click(); await page.waitForURL(/debates/); - const winningText = page.getByText("ThePropositionis the winning"); - await expect(winningText).toBeVisible(); + await expect(page.getByText(PROPOSITION_WINNING_TEXT)).toBeVisible(); }, ); @@ -120,8 +123,7 @@ test.describe("verdict panel", () => { await page.getByRole("button", { name: "Proposition" }).click(); await page.getByRole("button", { name: "Submit" }).click(); - const winningText = page.getByText("ThePropositionis the winning"); - await expect(winningText).toBeVisible(); + await expect(page.getByText(PROPOSITION_WINNING_TEXT)).toBeVisible(); }, ); @@ -154,14 +156,12 @@ test.describe("verdict panel", () => { await page.getByRole("button", { name: "Proposition" }).click(); await page.getByRole("button", { name: "Submit" }).click(); - const winningText = page.getByText("ThePropositionis the winning"); - await expect(winningText).toBeVisible(); + await expect(page.getByText(PROPOSITION_WINNING_TEXT)).toBeVisible(); await page.getByRole("button", { name: "Opposition" }).click(); await page.getByRole("button", { name: "Submit" }).click(); - const otherWinningText = page.getByText("TheOppositionis the winning"); - await expect(otherWinningText).toBeVisible(); + await expect(page.getByText(OPPOSITION_WINNING_TEXT)).toBeVisible(); }, ); });