mirror of
https://github.com/wowlikon/LiB.git
synced 2026-02-04 04:31:09 +00:00
Страница 404, более подробная инофрмация об ошибках, улучшение фронтэнда и логирования, исправление docker-compose
This commit is contained in:
@@ -3,6 +3,7 @@ $(() => {
|
||||
loginForm: "#login-form",
|
||||
registerForm: "#register-form",
|
||||
resetForm: "#reset-password-form",
|
||||
authTabs: "#auth-tabs",
|
||||
loginTab: "#login-tab",
|
||||
registerTab: "#register-tab",
|
||||
forgotBtn: "#forgot-password-btn",
|
||||
@@ -121,6 +122,13 @@ $(() => {
|
||||
};
|
||||
|
||||
const showForm = (formId) => {
|
||||
let newHash = "";
|
||||
if (formId === SELECTORS.loginForm) newHash = "login";
|
||||
else if (formId === SELECTORS.registerForm) newHash = "register";
|
||||
else if (formId === SELECTORS.resetForm) newHash = "reset";
|
||||
if (newHash && window.location.hash !== "#" + newHash) {
|
||||
window.history.pushState(null, null, "#" + newHash);
|
||||
}
|
||||
$(
|
||||
`${SELECTORS.loginForm}, ${SELECTORS.registerForm}, ${SELECTORS.resetForm}`,
|
||||
).addClass("hidden");
|
||||
@@ -142,6 +150,17 @@ $(() => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleHash = () => {
|
||||
const hash = window.location.hash.toLowerCase();
|
||||
if (hash === "#register" || hash === "#signup") {
|
||||
showForm(SELECTORS.registerForm);
|
||||
$(SELECTORS.registerTab).trigger("click");
|
||||
} else if (hash === "#login" || hash === "#signin") {
|
||||
showForm(SELECTORS.loginForm);
|
||||
$(SELECTORS.loginTab).trigger("click");
|
||||
}
|
||||
};
|
||||
|
||||
const resetLoginState = () => {
|
||||
clearPartialToken();
|
||||
stopTotpTimer();
|
||||
@@ -151,6 +170,7 @@ $(() => {
|
||||
username: "",
|
||||
rememberMe: false,
|
||||
};
|
||||
$(SELECTORS.authTabs).removeClass("hide-animated");
|
||||
$(SELECTORS.totpSection).addClass("hidden");
|
||||
$(SELECTORS.totpInput).val("");
|
||||
$(SELECTORS.credentialsSection).removeClass("hidden");
|
||||
@@ -185,6 +205,7 @@ $(() => {
|
||||
const savedToken = sessionStorage.getItem(STORAGE_KEYS.partialToken);
|
||||
const savedUsername = sessionStorage.getItem(STORAGE_KEYS.partialUsername);
|
||||
if (savedToken && savedUsername) {
|
||||
$(SELECTORS.authTabs).addClass("hide-animated");
|
||||
loginState.partialToken = savedToken;
|
||||
loginState.username = savedUsername;
|
||||
loginState.step = "2fa";
|
||||
@@ -279,6 +300,7 @@ $(() => {
|
||||
loginState.partialToken = data.partial_token;
|
||||
loginState.step = "2fa";
|
||||
savePartialToken(data.partial_token, username);
|
||||
$(SELECTORS.authTabs).addClass("hide-animated");
|
||||
$(SELECTORS.credentialsSection).addClass("hidden");
|
||||
$(SELECTORS.totpSection).removeClass("hidden");
|
||||
startTotpTimer();
|
||||
@@ -362,6 +384,19 @@ $(() => {
|
||||
}, 1500);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Debug error object:", error);
|
||||
|
||||
const cleanMsg = (text) => {
|
||||
if (!text) return "";
|
||||
if (text.includes("value is not a valid email address")) {
|
||||
return "Некорректный адрес электронной почты";
|
||||
}
|
||||
|
||||
text = text.replace(/^Value error,\s*/i, "");
|
||||
return text.charAt(0).toUpperCase() + text.slice(1);
|
||||
};
|
||||
|
||||
let msg = "Ошибка регистрации";
|
||||
if (error.detail && error.detail.error === "captcha_required") {
|
||||
Utils.showToast(TEXTS.captchaRequired, "error");
|
||||
const $capElement = $(SELECTORS.capWidget);
|
||||
@@ -372,11 +407,19 @@ $(() => {
|
||||
);
|
||||
return;
|
||||
}
|
||||
let msg = error.message;
|
||||
|
||||
if (error.detail && Array.isArray(error.detail)) {
|
||||
msg = error.detail.map((e) => e.msg).join(". ");
|
||||
msg = error.detail.map((e) => cleanMsg(e.msg)).join(". ");
|
||||
} else if (Array.isArray(error)) {
|
||||
msg = error.map((e) => cleanMsg(e.msg || e.message)).join(". ");
|
||||
} else if (typeof error.detail === "string") {
|
||||
msg = cleanMsg(error.detail);
|
||||
} else if (error.message && !error.message.includes("[object Object]")) {
|
||||
msg = cleanMsg(error.message);
|
||||
}
|
||||
Utils.showToast(msg || "Ошибка регистрации", "error");
|
||||
|
||||
console.log("Resulting msg:", msg);
|
||||
Utils.showToast(msg, "error");
|
||||
} finally {
|
||||
$submitBtn
|
||||
.prop("disabled", false)
|
||||
@@ -544,6 +587,7 @@ $(() => {
|
||||
};
|
||||
|
||||
initLoginState();
|
||||
handleHash();
|
||||
|
||||
const widget = $(SELECTORS.capWidget).get(0);
|
||||
if (widget && widget.shadowRoot) {
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
const NS = "http://www.w3.org/2000/svg";
|
||||
const $svg = $("#canvas");
|
||||
|
||||
const CONFIG = {
|
||||
holeRadius: 60,
|
||||
maxRadius: 220,
|
||||
tilt: 0.4,
|
||||
|
||||
ringsCount: 7,
|
||||
ringSpeed: 0.002,
|
||||
ringStroke: 5,
|
||||
|
||||
particlesCount: 40,
|
||||
particleSpeedBase: 0.02,
|
||||
particleFallSpeed: 0.2,
|
||||
};
|
||||
|
||||
function create(tag, attrs) {
|
||||
const el = document.createElementNS(NS, tag);
|
||||
for (let k in attrs) el.setAttribute(k, attrs[k]);
|
||||
return el;
|
||||
}
|
||||
|
||||
const $layerBack = $(create("g", { id: "layer-back" }));
|
||||
const $layerHole = $(create("g", { id: "layer-hole" }));
|
||||
const $layerFront = $(create("g", { id: "layer-front" }));
|
||||
|
||||
$svg.append($layerBack, $layerHole, $layerFront);
|
||||
|
||||
const holeHalo = create("circle", {
|
||||
cx: 0,
|
||||
cy: 0,
|
||||
r: CONFIG.holeRadius + 4,
|
||||
fill: "#ffffff",
|
||||
stroke: "none",
|
||||
});
|
||||
const holeBody = create("circle", {
|
||||
cx: 0,
|
||||
cy: 0,
|
||||
r: CONFIG.holeRadius,
|
||||
fill: "#000000",
|
||||
});
|
||||
$layerHole.append(holeHalo, holeBody);
|
||||
|
||||
class Ring {
|
||||
constructor(offset) {
|
||||
this.progress = offset;
|
||||
|
||||
const style = {
|
||||
fill: "none",
|
||||
stroke: "#000",
|
||||
"stroke-linecap": "round",
|
||||
"stroke-width": CONFIG.ringStroke,
|
||||
};
|
||||
|
||||
this.elBack = create("path", style);
|
||||
this.elFront = create("path", style);
|
||||
|
||||
$layerBack.append(this.elBack);
|
||||
$layerFront.append(this.elFront);
|
||||
}
|
||||
|
||||
update() {
|
||||
this.progress += CONFIG.ringSpeed;
|
||||
if (this.progress >= 1) this.progress -= 1;
|
||||
|
||||
const t = this.progress;
|
||||
|
||||
const currentR =
|
||||
CONFIG.maxRadius - t * (CONFIG.maxRadius - CONFIG.holeRadius);
|
||||
const currentRy = currentR * CONFIG.tilt;
|
||||
|
||||
const distFromHole = currentR - CONFIG.holeRadius;
|
||||
const distFromEdge = CONFIG.maxRadius - currentR;
|
||||
|
||||
const fadeHole = Math.min(1, distFromHole / 40);
|
||||
const fadeEdge = Math.min(1, distFromEdge / 40);
|
||||
|
||||
const opacity = fadeHole * fadeEdge;
|
||||
|
||||
if (opacity <= 0.01) {
|
||||
this.elBack.setAttribute("opacity", 0);
|
||||
this.elFront.setAttribute("opacity", 0);
|
||||
} else {
|
||||
const dBack = `M ${-currentR} 0 A ${currentR} ${currentRy} 0 0 1 ${currentR} 0`;
|
||||
const dFront = `M ${-currentR} 0 A ${currentR} ${currentRy} 0 0 0 ${currentR} 0`;
|
||||
|
||||
this.elBack.setAttribute("d", dBack);
|
||||
this.elFront.setAttribute("d", dFront);
|
||||
|
||||
this.elBack.setAttribute("opacity", opacity);
|
||||
this.elFront.setAttribute("opacity", opacity);
|
||||
|
||||
const sw =
|
||||
CONFIG.ringStroke *
|
||||
(0.6 + 0.4 * (distFromHole / (CONFIG.maxRadius - CONFIG.holeRadius)));
|
||||
this.elBack.setAttribute("stroke-width", sw);
|
||||
this.elFront.setAttribute("stroke-width", sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Particle {
|
||||
constructor() {
|
||||
this.el = create("circle", { fill: "#000" });
|
||||
this.reset(true);
|
||||
$layerFront.append(this.el);
|
||||
this.inFront = true;
|
||||
}
|
||||
|
||||
reset(randomStart = false) {
|
||||
this.angle = Math.random() * Math.PI * 2;
|
||||
this.r = randomStart
|
||||
? CONFIG.holeRadius +
|
||||
Math.random() * (CONFIG.maxRadius - CONFIG.holeRadius)
|
||||
: CONFIG.maxRadius;
|
||||
|
||||
this.speed = CONFIG.particleSpeedBase + Math.random() * 0.02;
|
||||
this.size = 1.5 + Math.random() * 2.5;
|
||||
}
|
||||
|
||||
update() {
|
||||
const acceleration = CONFIG.maxRadius / this.r;
|
||||
this.angle += this.speed * acceleration;
|
||||
this.r -= CONFIG.particleFallSpeed * (acceleration * 0.8);
|
||||
|
||||
const x = Math.cos(this.angle) * this.r;
|
||||
const y = Math.sin(this.angle) * this.r * CONFIG.tilt;
|
||||
|
||||
const isNowFront = Math.sin(this.angle) > 0;
|
||||
|
||||
if (this.inFront !== isNowFront) {
|
||||
this.inFront = isNowFront;
|
||||
if (this.inFront) {
|
||||
$layerFront.append(this.el);
|
||||
} else {
|
||||
$layerBack.append(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
const distFromHole = this.r - CONFIG.holeRadius;
|
||||
const distFromEdge = CONFIG.maxRadius - this.r;
|
||||
|
||||
const fadeHole = Math.min(1, distFromHole / 30);
|
||||
const fadeEdge = Math.min(1, distFromEdge / 30);
|
||||
const opacity = fadeHole * fadeEdge;
|
||||
|
||||
this.el.setAttribute("cx", x);
|
||||
this.el.setAttribute("cy", y);
|
||||
this.el.setAttribute("r", this.size * Math.min(1, this.r / 100));
|
||||
this.el.setAttribute("opacity", opacity);
|
||||
|
||||
if (this.r <= CONFIG.holeRadius) {
|
||||
this.reset(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rings = [];
|
||||
for (let i = 0; i < CONFIG.ringsCount; i++) {
|
||||
rings.push(new Ring(i / CONFIG.ringsCount));
|
||||
}
|
||||
|
||||
const particles = [];
|
||||
for (let i = 0; i < CONFIG.particlesCount; i++) {
|
||||
particles.push(new Particle());
|
||||
}
|
||||
|
||||
function animate() {
|
||||
rings.forEach((r) => r.update());
|
||||
particles.forEach((p) => p.update());
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
animate();
|
||||
Reference in New Issue
Block a user