From a3fc7f7ceb999a2a001b51e15029b9495758965c Mon Sep 17 00:00:00 2001 From: Sean Jiang Date: Mon, 15 Sep 2025 18:58:33 -0400 Subject: [PATCH] fixed --- public/src/client/register.js | 72 ++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/public/src/client/register.js b/public/src/client/register.js index 62dbc41..e83990c 100644 --- a/public/src/client/register.js +++ b/public/src/client/register.js @@ -1,6 +1,5 @@ 'use strict'; - define('forum/register', [ 'translator', 'slugify', 'api', 'bootbox', 'forum/login', 'zxcvbn', 'jquery-form', ], function (translator, slugify, api, bootbox, Login, zxcvbn) { @@ -8,6 +7,46 @@ define('forum/register', [ let validationError = false; const successIcon = ''; + // --- Suggestion helpers (English-only for this recitation task) --- + const SUG_SUFFIX = 'suffix'; + function suggestUsername(base) { + // Suggestion is based on the slugified base attempt + const s = slugify(base || ''); + return s ? (s + SUG_SUFFIX) : ''; + } + function showUsernameTakenWithSuggestion(element, attempted) { + const suggestion = suggestUsername(attempted); + // Build a small inline UI with a clickable suggestion + translator.translate('[[error:username-taken]]', function (msg) { + const html = ` + ${msg} + ${suggestion ? ` — Try: + ` : ''} + `; + element.html(html); + element.parent() + .removeClass('register-success') + .addClass('register-danger'); + element.show(); + + // Wire the click to apply suggestion & re-validate + const btn = document.getElementById('apply-username-suggestion'); + if (btn) { + btn.addEventListener('click', function () { + const $username = $('#username'); + $username.val(suggestion); + // Update the "mention you as" preview + $('#yourUsername').text(suggestion || 'username'); + // Trigger re-validation + validateUsername($username.val()); + }); + } + }); + validationError = true; + } + Register.init = function () { const username = $('#username'); const password = $('#password'); @@ -119,24 +158,29 @@ define('forum/register', [ if (username.length < ajaxify.data.minimumUsernameLength || userslug.length < ajaxify.data.minimumUsernameLength) { showError(username_notify, '[[error:username-too-short]]'); + return callback(); } else if (username.length > ajaxify.data.maximumUsernameLength) { showError(username_notify, '[[error:username-too-long]]'); + return callback(); } else if (!utils.isUserNameValid(username) || !userslug) { showError(username_notify, '[[error:invalid-username]]'); - } else { - Promise.allSettled([ - api.head(`/users/bySlug/${username}`, {}), - api.head(`/groups/${username}`, {}), - ]).then((results) => { - if (results.every(obj => obj.status === 'rejected')) { - showSuccess(username_notify, successIcon); - } else { - showError(username_notify, '[[error:username-taken]]'); - } - - callback(); - }); + return callback(); } + + // IMPORTANT: check existence by slug, not raw username + Promise.allSettled([ + api.head(`/users/bySlug/${userslug}`), + api.head(`/groups/${userslug}`), + ]).then((results) => { + // If both HEADs reject (404), it's available + if (results.every(obj => obj.status === 'rejected')) { + showSuccess(username_notify, successIcon); + } else { + // Taken: show suggestion inline (English only per task) + showUsernameTakenWithSuggestion(username_notify, username); + } + callback(); + }); } function validatePassword(password, password_confirm) {