feat: add admin telegram profile links and avatar preview

This commit is contained in:
3252a8
2026-05-18 23:46:46 +03:00
parent 707f569f62
commit 1d9f069f45
8 changed files with 373 additions and 9 deletions
@@ -319,6 +319,28 @@ export function createUsersStore({ api, onToast, at }) {
}
}
async function sendTelegramProfileLink() {
let s;
state.update((st) => {
s = st;
return st;
});
if (!s.openedUser) return;
state.update((st) => ({ ...st, userActionBusy: true }));
try {
const res = await api(`/admin/users/${s.openedUser.user_id}/telegram-profile-link`, {
method: "POST",
});
if (res?.ok) {
onToast(at("user_tg_profile_link_sent", {}, "Ссылка отправлена в Telegram"));
} else {
onToast(res?.error || at("user_tg_profile_link_failed", {}, "Не удалось отправить ссылку"));
}
} finally {
state.update((st) => ({ ...st, userActionBusy: false }));
}
}
async function extendUser() {
let s;
state.update((st) => {
@@ -510,6 +532,7 @@ export function createUsersStore({ api, onToast, at }) {
sendUserMessage,
requestSendUserMessage,
previewUserMessage,
sendTelegramProfileLink,
extendUser,
resetTrialUser,
deleteUser,
+44
View File
@@ -25,6 +25,50 @@ export function userAvatarUrl(user) {
return value && !value.startsWith("/api/account/avatar") ? value : "";
}
export function userTelegramProfileLink(user) {
const username = String(user?.username || "")
.trim()
.replace(/^@+/, "");
if (username) return `https://t.me/${encodeURIComponent(username)}`;
const telegramId = Number(user?.telegram_id);
if (Number.isFinite(telegramId) && telegramId > 0) {
return `tg://user?id=${encodeURIComponent(String(Math.trunc(telegramId)))}`;
}
return "";
}
export function userTelegramProfileLinkKind(user) {
return String(user?.username || "").trim()
? "username"
: userTelegramProfileLink(user)
? "id"
: "";
}
export function openTelegramProfileLink(link) {
if (!link || typeof window === "undefined") return false;
const tg = window.Telegram?.WebApp;
if (/^https:\/\/(?:t|telegram)\.me\//i.test(link) && typeof tg?.openTelegramLink === "function") {
try {
tg.openTelegramLink(link);
return true;
} catch {
// Fall through to the normal browser/deep-link handling below.
}
}
if (/^https?:\/\//i.test(link)) {
window.open(link, "_blank", "noopener,noreferrer");
return true;
}
window.location.href = link;
return true;
}
export function createGravatarCache(onResolved = () => {}) {
const cache = new Map();
const pending = new Map();