mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Implement the register screen and make auth work
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { API_BASE_URL } from "../core/config";
|
import { API_BASE_URL } from "../core/config";
|
||||||
import { showLogin } from "../navigation";
|
// import { showLogin } from "../navigation";
|
||||||
import type { Headers, User, WebSocketMessage } from "../core/types";
|
import type { Headers, User, WebSocketMessage } from "../core/types";
|
||||||
import { clearAlerts } from "./auth";
|
import { clearAlerts } from "./auth";
|
||||||
import { request } from "../websocket";
|
import { request } from "../websocket";
|
||||||
@@ -65,7 +65,7 @@ export function getAuthHeaders(json: boolean = true): Headers {
|
|||||||
export async function checkAuthStatus(): Promise<void> {
|
export async function checkAuthStatus(): Promise<void> {
|
||||||
// For JWT, we don't have a persistent token on page load
|
// For JWT, we don't have a persistent token on page load
|
||||||
// So we'll just show the login form
|
// So we'll just show the login form
|
||||||
showLogin();
|
// showLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +83,6 @@ export async function logout(): Promise<void> {
|
|||||||
|
|
||||||
currentUser = null;
|
currentUser = null;
|
||||||
authToken = null;
|
authToken = null;
|
||||||
showLogin();
|
// showLogin();
|
||||||
clearAlerts();
|
clearAlerts();
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,6 @@
|
|||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ErrorResponse, RegisterRequest } from "../core/types";
|
|
||||||
import { API_BASE_URL } from "../core/config";
|
|
||||||
import { showLogin } from "../navigation";
|
|
||||||
import { id } from "../utils/utils";
|
import { id } from "../utils/utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,94 +14,4 @@ import { id } from "../utils/utils";
|
|||||||
export function clearAlerts(): void {
|
export function clearAlerts(): void {
|
||||||
id('login-alerts').innerHTML = '';
|
id('login-alerts').innerHTML = '';
|
||||||
id('register-alerts').innerHTML = '';
|
id('register-alerts').innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows an alert message in the specified container
|
|
||||||
* @param {string} containerId - ID of the container to show the alert in
|
|
||||||
* @param {string} message - Alert message to display
|
|
||||||
* @param {'success' | 'danger'} type - Type of alert (success or danger)
|
|
||||||
*/
|
|
||||||
export function showAlert(containerId: string, message: string, type: "success" | "danger" = 'danger'): void {
|
|
||||||
const container = id(containerId);
|
|
||||||
const alertDiv = document.createElement('div');
|
|
||||||
alertDiv.className = `alert alert-${type}`;
|
|
||||||
alertDiv.textContent = message;
|
|
||||||
container.appendChild(alertDiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles registration form submission
|
|
||||||
* @param {Event} e - Form submission event
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
async function handleRegister(e: Event): Promise<void> {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const usernameElement = id<HTMLInputElement>('register-username');
|
|
||||||
const passwordElement = id<HTMLInputElement>('register-password');
|
|
||||||
const confirmPasswordElement = id<HTMLInputElement>('register-confirm-password');
|
|
||||||
|
|
||||||
const username = usernameElement.value.trim();
|
|
||||||
const password = passwordElement.value.trim();
|
|
||||||
const confirmPassword = confirmPasswordElement.value.trim();
|
|
||||||
|
|
||||||
if (!username || !password || !confirmPassword) {
|
|
||||||
showAlert('register-alerts', 'Пожалуйста, заполните все поля', 'danger');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
showAlert('register-alerts', 'Пароли не совпадают', 'danger');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (username.length < 3 || username.length > 20) {
|
|
||||||
showAlert('register-alerts', 'Имя пользователя должно быть от 3 до 20 символов', 'danger');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.length < 5 || password.length > 50) {
|
|
||||||
showAlert('register-alerts', 'Пароль должен быть от 5 до 50 символов', 'danger');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const request: RegisterRequest = {
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
confirm_password: confirmPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(`${API_BASE_URL}/register`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(request)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
// Registration successful
|
|
||||||
showAlert('register-alerts', 'Регистрация прошла успешно! Теперь вы можете войти.', 'success');
|
|
||||||
setTimeout(() => {
|
|
||||||
showLogin();
|
|
||||||
}, 2000);
|
|
||||||
} else {
|
|
||||||
const data: ErrorResponse = await response.json();
|
|
||||||
showAlert('register-alerts', data.message || 'Ошибка при регистрации', 'danger');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
showAlert('register-alerts', 'Ошибка соединения с сервером', 'danger');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes authentication functionality
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function init(): void {
|
|
||||||
id('register-form-element').addEventListener('submit', handleRegister);
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
@@ -8,8 +8,8 @@ export interface Alert {
|
|||||||
export function AlertsContainer({ alerts }: { alerts: Alert[]}) {
|
export function AlertsContainer({ alerts }: { alerts: Alert[]}) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{alerts.map(alert => {
|
{alerts.slice(-3).map((alert, i) => {
|
||||||
return <div className={`alert alert-${alert.type}`}>{alert.message}</div>
|
return <div className={`alert alert-${alert.type}`} key={i}>{alert.message}</div>
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
import { useImmer } from "use-immer";
|
import { useImmer } from "use-immer";
|
||||||
import { showChat, showRegister } from "../../navigation";
|
|
||||||
import { AlertsContainer, type Alert, type AlertType } from "../components/Alerts";
|
import { AlertsContainer, type Alert, type AlertType } from "../components/Alerts";
|
||||||
import { AuthContainer, AuthHeader } from "../components/Auth";
|
import { AuthContainer, AuthHeader } from "../components/Auth";
|
||||||
import type { ErrorResponse, LoginRequest, LoginResponse } from "../../core/types";
|
import type { ErrorResponse, LoginRequest, LoginResponse } from "../../core/types";
|
||||||
import { setUser } from "../../auth/api";
|
import { setUser } from "../../auth/api";
|
||||||
import { ensureKeysOnLogin } from "../../auth/crypto";
|
import { ensureKeysOnLogin } from "../../auth/crypto";
|
||||||
import { API_BASE_URL } from "../../core/config";
|
import { API_BASE_URL } from "../../core/config";
|
||||||
import { initializeProfile } from "../../userPanel/profile/profile";
|
// import { initializeProfile } from "../../userPanel/profile/profile";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import type { TextField } from "mdui/components/text-field";
|
import type { TextField } from "mdui/components/text-field";
|
||||||
|
import { useAppState } from "../state";
|
||||||
|
|
||||||
export default function LoginScreen() {
|
export default function LoginScreen() {
|
||||||
const [alerts, updateAlerts] = useImmer<Alert[]>([]);
|
const [alerts, updateAlerts] = useImmer<Alert[]>([]);
|
||||||
|
const setCurrentPage = useAppState(state => state.setCurrentPage);
|
||||||
|
|
||||||
function showAlert(type: AlertType, message: string) {
|
function showAlert(type: AlertType, message: string) {
|
||||||
updateAlerts((alerts) => alerts.push({type: type, message: message}));
|
updateAlerts((alerts) => { alerts.push({type: type, message: message}) });
|
||||||
}
|
}
|
||||||
|
|
||||||
const usernameElement = useRef<TextField>(null);
|
const usernameElement = useRef<TextField>(null);
|
||||||
@@ -61,8 +62,8 @@ export default function LoginScreen() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Key setup failed:", e);
|
console.error("Key setup failed:", e);
|
||||||
}
|
}
|
||||||
showChat();
|
setCurrentPage("chat");
|
||||||
initializeProfile(); // Initialize profile after login
|
// initializeProfile(); // Initialize profile after login
|
||||||
} else {
|
} else {
|
||||||
const data: ErrorResponse = await response.json();
|
const data: ErrorResponse = await response.json();
|
||||||
showAlert("danger", data.message || "Неверное имя пользователя или пароль");
|
showAlert("danger", data.message || "Неверное имя пользователя или пароль");
|
||||||
@@ -103,7 +104,7 @@ export default function LoginScreen() {
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="link"
|
className="link"
|
||||||
onClick={showRegister}>
|
onClick={() => setCurrentPage("register")}>
|
||||||
Зарегистрируйтесь
|
Зарегистрируйтесь
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useImmer } from "use-immer";
|
import { useImmer } from "use-immer";
|
||||||
import { showLogin } from "../../navigation";
|
// import { showLogin } from "../../navigation";
|
||||||
import { AuthContainer, AuthHeader } from "../components/Auth";
|
import { AuthContainer, AuthHeader } from "../components/Auth";
|
||||||
import { AlertsContainer, type Alert, type AlertType } from "../components/Alerts";
|
import { AlertsContainer, type Alert, type AlertType } from "../components/Alerts";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
@@ -7,12 +7,14 @@ import { TextField } from "mdui/components/text-field";
|
|||||||
import type { ErrorResponse, RegisterRequest } from "../../core/types";
|
import type { ErrorResponse, RegisterRequest } from "../../core/types";
|
||||||
import { API_BASE_URL } from "../../core/config";
|
import { API_BASE_URL } from "../../core/config";
|
||||||
import { delay } from "../../utils/utils";
|
import { delay } from "../../utils/utils";
|
||||||
|
import { useAppState } from "../state";
|
||||||
|
|
||||||
export default function RegisterScreen() {
|
export default function RegisterScreen() {
|
||||||
const [alerts, updateAlerts] = useImmer<Alert[]>([]);
|
const [alerts, updateAlerts] = useImmer<Alert[]>([]);
|
||||||
|
const setCurrentPage = useAppState(state => state.setCurrentPage);
|
||||||
|
|
||||||
function showAlert(type: AlertType, message: string) {
|
function showAlert(type: AlertType, message: string) {
|
||||||
updateAlerts((alerts) => alerts.push({type: type, message: message}));
|
updateAlerts((alerts) => { alerts.push({type: type, message: message}) });
|
||||||
}
|
}
|
||||||
|
|
||||||
const usernameElement = useRef<TextField>(null);
|
const usernameElement = useRef<TextField>(null);
|
||||||
@@ -71,7 +73,7 @@ export default function RegisterScreen() {
|
|||||||
// Registration successful
|
// Registration successful
|
||||||
showAlert("success", "Регистрация прошла успешно! Теперь вы можете войти.");
|
showAlert("success", "Регистрация прошла успешно! Теперь вы можете войти.");
|
||||||
await delay(2000);
|
await delay(2000);
|
||||||
showLogin();
|
setCurrentPage("login");
|
||||||
} else {
|
} else {
|
||||||
const data: ErrorResponse = await response.json();
|
const data: ErrorResponse = await response.json();
|
||||||
showAlert("danger", data.message || "Ошибка при регистрации");
|
showAlert("danger", data.message || "Ошибка при регистрации");
|
||||||
@@ -127,7 +129,7 @@ export default function RegisterScreen() {
|
|||||||
href="#"
|
href="#"
|
||||||
id="login-link"
|
id="login-link"
|
||||||
className="link"
|
className="link"
|
||||||
onClick={showLogin}>
|
onClick={() => setCurrentPage("login")}>
|
||||||
Войдите
|
Войдите
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { handleWebSocketMessage } from "./chat/chat";
|
|
||||||
import { API_WS_BASE_URL } from "./core/config";
|
import { API_WS_BASE_URL } from "./core/config";
|
||||||
import type { WebSocketMessage } from "./core/types";
|
import type { WebSocketMessage } from "./core/types";
|
||||||
import { delay } from "./utils/utils";
|
import { delay } from "./utils/utils";
|
||||||
@@ -71,6 +70,6 @@ async function onError() {
|
|||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
websocket.addEventListener("message", (e) => {
|
websocket.addEventListener("message", (e) => {
|
||||||
handleWebSocketMessage(JSON.parse(e.data));
|
// handleWebSocketMessage(JSON.parse(e.data));
|
||||||
});
|
});
|
||||||
websocket.addEventListener("error", onError);
|
websocket.addEventListener("error", onError);
|
||||||
Reference in New Issue
Block a user