Files
SHiNE-server/shine-UI/js/pages/profiles-view.js
T

147 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { renderHeader } from '../components/header.js';
import {
closeAllSavedProfiles,
closeSavedProfile,
getSavedProfiles,
prepareAddProfileLogin,
state,
switchToSavedProfile,
} from '../state.js';
export const pageMeta = { id: 'profiles-view', title: 'Профили' };
function reloadTo(path) {
const clean = String(path || '/profile').trim() || '/profile';
window.location.assign(clean.startsWith('/') ? clean : `/${clean}`);
}
export function render({ navigate }) {
const screen = document.createElement('section');
screen.className = 'stack profiles-screen';
screen.append(renderHeader({
title: 'Профили',
leftAction: { label: '←', onClick: () => navigate('profile-view') },
}));
const intro = document.createElement('div');
intro.className = 'meta-muted profiles-summary';
const list = document.createElement('div');
list.className = 'stack profiles-list';
const status = document.createElement('div');
status.className = 'status-line';
status.hidden = true;
const actions = document.createElement('div');
actions.className = 'stack profiles-actions';
const addButton = document.createElement('button');
addButton.type = 'button';
addButton.className = 'secondary-btn';
addButton.textContent = 'Добавить профиль';
addButton.addEventListener('click', () => {
prepareAddProfileLogin();
navigate('login-view');
});
const closeAllButton = document.createElement('button');
closeAllButton.type = 'button';
closeAllButton.className = 'secondary-btn profiles-close-all';
closeAllButton.textContent = 'Закрыть все профили';
closeAllButton.addEventListener('click', async () => {
const profiles = getSavedProfiles();
if (!profiles.length) return;
const confirmed = window.confirm('Закрыть все профили на этом устройстве? После этого откроется экран входа.');
if (!confirmed) return;
closeAllButton.disabled = true;
status.hidden = false;
status.textContent = 'Закрываем профили…';
try {
await closeAllSavedProfiles();
reloadTo('/start');
} catch (error) {
status.className = 'status-line is-unavailable';
status.textContent = `Не удалось закрыть профили: ${error?.message || 'unknown'}`;
closeAllButton.disabled = false;
}
});
actions.append(addButton, closeAllButton);
screen.append(intro, list, status, actions);
const renderList = () => {
const profiles = getSavedProfiles();
const active = profiles.find((item) => item.isActive);
intro.textContent = profiles.length
? `Профилей на устройстве: ${profiles.length}. Активен: ${active?.login || state.session.login || '—'}`
: 'На устройстве нет сохранённых профилей.';
closeAllButton.disabled = profiles.length === 0;
list.innerHTML = '';
profiles.forEach((profile) => {
const row = document.createElement('div');
row.className = `card profiles-row${profile.isActive ? ' is-active' : ''}`;
const select = document.createElement('button');
select.type = 'button';
select.className = 'profiles-select';
select.innerHTML = `<span class="profiles-login">${profile.login}</span>${profile.isActive ? '<span class="badge">Активный</span>' : ''}`;
select.disabled = profile.isActive;
select.addEventListener('click', async () => {
if (profile.isActive) return;
const confirmed = window.confirm(`Переключиться на профиль «${profile.login}»?`);
if (!confirmed) return;
status.hidden = false;
status.className = 'status-line';
status.textContent = `Подключаем профиль ${profile.login}…`;
try {
await switchToSavedProfile(profile.login);
reloadTo('/profile');
} catch (error) {
status.className = 'status-line is-unavailable';
status.textContent = `Не удалось переключить профиль: ${error?.message || 'unknown'}`;
}
});
const close = document.createElement('button');
close.type = 'button';
close.className = 'profiles-close';
close.setAttribute('aria-label', `Закрыть профиль ${profile.login}`);
close.textContent = '×';
close.addEventListener('click', async () => {
const others = profiles.filter((item) => item.login.toLowerCase() !== profile.login.toLowerCase());
const message = profile.isActive
? (others.length
? `Закрыть текущий профиль «${profile.login}»? После закрытия приложение переключится на следующий сохранённый профиль.`
: `Закрыть текущий профиль «${profile.login}»? После закрытия откроется экран входа.`)
: `Закрыть профиль «${profile.login}» на этом устройстве?`;
if (!window.confirm(message)) return;
status.hidden = false;
status.className = 'status-line';
status.textContent = `Закрываем профиль ${profile.login}…`;
try {
const result = await closeSavedProfile(profile.login);
if (profile.isActive) {
reloadTo(result.nextProfile ? '/profile' : '/start');
return;
}
status.hidden = true;
renderList();
} catch (error) {
status.className = 'status-line is-unavailable';
status.textContent = `Не удалось закрыть профиль: ${error?.message || 'unknown'}`;
}
});
row.append(select, close);
list.append(row);
});
};
renderList();
return screen;
}