cleanup semicolon from js
This commit is contained in:
@@ -1,80 +1,80 @@
|
||||
import { i18n, t } from '../i18n.js';
|
||||
import { router } from '../router.js';
|
||||
import { auth } from '../services/auth.js';
|
||||
import { i18n, t } from '../i18n.js'
|
||||
import { router } from '../router.js'
|
||||
import { auth } from '../services/auth.js'
|
||||
|
||||
class AppHeader extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.langDropdownOpen = false;
|
||||
this.handleOutsideClick = this.handleOutsideClick.bind(this);
|
||||
this.handleKeydown = this.handleKeydown.bind(this);
|
||||
super()
|
||||
this.langDropdownOpen = false
|
||||
this.handleOutsideClick = this.handleOutsideClick.bind(this)
|
||||
this.handleKeydown = this.handleKeydown.bind(this)
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this.setupEventListeners();
|
||||
document.addEventListener('click', this.handleOutsideClick);
|
||||
document.addEventListener('keydown', this.handleKeydown);
|
||||
this.render()
|
||||
this.setupEventListeners()
|
||||
document.addEventListener('click', this.handleOutsideClick)
|
||||
document.addEventListener('keydown', this.handleKeydown)
|
||||
|
||||
// Subscribe to auth changes (only once!)
|
||||
this.authUnsubscribe = auth.subscribe(() => {
|
||||
this.render();
|
||||
this.setupEventListeners();
|
||||
});
|
||||
this.render()
|
||||
this.setupEventListeners()
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
document.removeEventListener('click', this.handleOutsideClick);
|
||||
document.removeEventListener('keydown', this.handleKeydown);
|
||||
if (this.authUnsubscribe) this.authUnsubscribe();
|
||||
document.removeEventListener('click', this.handleOutsideClick)
|
||||
document.removeEventListener('keydown', this.handleKeydown)
|
||||
if (this.authUnsubscribe) this.authUnsubscribe()
|
||||
}
|
||||
|
||||
handleOutsideClick() {
|
||||
if (this.langDropdownOpen) {
|
||||
this.closeDropdown();
|
||||
this.closeDropdown()
|
||||
}
|
||||
}
|
||||
|
||||
handleKeydown(e) {
|
||||
if (!this.langDropdownOpen) return;
|
||||
if (!this.langDropdownOpen) return
|
||||
|
||||
const items = Array.from(this.querySelectorAll('.dropdown-item'));
|
||||
const currentIndex = items.findIndex(item => item === document.activeElement);
|
||||
const items = Array.from(this.querySelectorAll('.dropdown-item'))
|
||||
const currentIndex = items.findIndex(item => item === document.activeElement)
|
||||
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
e.preventDefault();
|
||||
this.closeDropdown();
|
||||
this.querySelector('#lang-toggle')?.focus();
|
||||
break;
|
||||
e.preventDefault()
|
||||
this.closeDropdown()
|
||||
this.querySelector('#lang-toggle')?.focus()
|
||||
break
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;
|
||||
items[nextIndex]?.focus();
|
||||
break;
|
||||
e.preventDefault()
|
||||
const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0
|
||||
items[nextIndex]?.focus()
|
||||
break
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;
|
||||
items[prevIndex]?.focus();
|
||||
break;
|
||||
e.preventDefault()
|
||||
const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1
|
||||
items[prevIndex]?.focus()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
closeDropdown() {
|
||||
this.langDropdownOpen = false;
|
||||
const langDropdown = this.querySelector('#lang-dropdown');
|
||||
const langToggle = this.querySelector('#lang-toggle');
|
||||
langDropdown?.classList.remove('open');
|
||||
langToggle?.setAttribute('aria-expanded', 'false');
|
||||
this.langDropdownOpen = false
|
||||
const langDropdown = this.querySelector('#lang-dropdown')
|
||||
const langToggle = this.querySelector('#lang-toggle')
|
||||
langDropdown?.classList.remove('open')
|
||||
langToggle?.setAttribute('aria-expanded', 'false')
|
||||
}
|
||||
|
||||
openDropdown() {
|
||||
this.langDropdownOpen = true;
|
||||
const langDropdown = this.querySelector('#lang-dropdown');
|
||||
const langToggle = this.querySelector('#lang-toggle');
|
||||
langDropdown?.classList.add('open');
|
||||
langToggle?.setAttribute('aria-expanded', 'true');
|
||||
this.querySelector('.dropdown-item.active')?.focus();
|
||||
this.langDropdownOpen = true
|
||||
const langDropdown = this.querySelector('#lang-dropdown')
|
||||
const langToggle = this.querySelector('#lang-toggle')
|
||||
langDropdown?.classList.add('open')
|
||||
langToggle?.setAttribute('aria-expanded', 'true')
|
||||
this.querySelector('.dropdown-item.active')?.focus()
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -162,88 +162,88 @@ class AppHeader extends HTMLElement {
|
||||
`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
const themeToggle = this.querySelector('#theme-toggle');
|
||||
themeToggle.addEventListener('click', () => this.toggleTheme());
|
||||
const themeToggle = this.querySelector('#theme-toggle')
|
||||
themeToggle.addEventListener('click', () => this.toggleTheme())
|
||||
|
||||
const langDropdown = this.querySelector('#lang-dropdown');
|
||||
const langToggle = this.querySelector('#lang-toggle');
|
||||
const langDropdown = this.querySelector('#lang-dropdown')
|
||||
const langToggle = this.querySelector('#lang-toggle')
|
||||
|
||||
langToggle.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
e.stopPropagation()
|
||||
if (this.langDropdownOpen) {
|
||||
this.closeDropdown();
|
||||
this.closeDropdown()
|
||||
} else {
|
||||
this.openDropdown();
|
||||
this.openDropdown()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
langDropdown.querySelectorAll('[data-locale]').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
await i18n.setLocale(btn.dataset.locale);
|
||||
this.closeDropdown();
|
||||
this.render();
|
||||
this.setupEventListeners();
|
||||
});
|
||||
});
|
||||
await i18n.setLocale(btn.dataset.locale)
|
||||
this.closeDropdown()
|
||||
this.render()
|
||||
this.setupEventListeners()
|
||||
})
|
||||
})
|
||||
|
||||
// Login button
|
||||
const loginBtn = this.querySelector('#login-btn');
|
||||
const loginBtn = this.querySelector('#login-btn')
|
||||
loginBtn?.addEventListener('click', () => {
|
||||
const authModal = document.querySelector('auth-modal');
|
||||
const authModal = document.querySelector('auth-modal')
|
||||
if (authModal) {
|
||||
authModal.show('login');
|
||||
authModal.show('login')
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Profile button
|
||||
const profileBtn = this.querySelector('#profile-btn');
|
||||
const profileBtn = this.querySelector('#profile-btn')
|
||||
profileBtn?.addEventListener('click', () => {
|
||||
router.navigate('/profile');
|
||||
});
|
||||
router.navigate('/profile')
|
||||
})
|
||||
|
||||
this.updateThemeIcon();
|
||||
this.updateThemeIcon()
|
||||
}
|
||||
|
||||
toggleTheme() {
|
||||
const currentTheme = document.documentElement.dataset.theme;
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const currentTheme = document.documentElement.dataset.theme
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
|
||||
let newTheme;
|
||||
let newTheme
|
||||
if (!currentTheme) {
|
||||
newTheme = prefersDark ? 'light' : 'dark';
|
||||
newTheme = prefersDark ? 'light' : 'dark'
|
||||
} else if (currentTheme === 'dark') {
|
||||
newTheme = 'light';
|
||||
newTheme = 'light'
|
||||
} else {
|
||||
newTheme = 'dark';
|
||||
newTheme = 'dark'
|
||||
}
|
||||
|
||||
document.documentElement.dataset.theme = newTheme;
|
||||
localStorage.setItem('theme', newTheme);
|
||||
this.updateThemeIcon();
|
||||
document.documentElement.dataset.theme = newTheme
|
||||
localStorage.setItem('theme', newTheme)
|
||||
this.updateThemeIcon()
|
||||
}
|
||||
|
||||
updateThemeIcon() {
|
||||
const theme = document.documentElement.dataset.theme;
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const isDark = theme === 'dark' || (!theme && prefersDark);
|
||||
const theme = document.documentElement.dataset.theme
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const isDark = theme === 'dark' || (!theme && prefersDark)
|
||||
|
||||
const sunIcon = this.querySelector('.icon-sun');
|
||||
const moonIcon = this.querySelector('.icon-moon');
|
||||
const sunIcon = this.querySelector('.icon-sun')
|
||||
const moonIcon = this.querySelector('.icon-moon')
|
||||
|
||||
if (sunIcon && moonIcon) {
|
||||
sunIcon.style.display = isDark ? 'block' : 'none';
|
||||
moonIcon.style.display = isDark ? 'none' : 'block';
|
||||
sunIcon.style.display = isDark ? 'block' : 'none'
|
||||
moonIcon.style.display = isDark ? 'none' : 'block'
|
||||
}
|
||||
}
|
||||
|
||||
updateTranslations() {
|
||||
i18n.updateDOM();
|
||||
this.querySelector('#current-lang').textContent = i18n.getLocale().toUpperCase();
|
||||
i18n.updateDOM()
|
||||
this.querySelector('#current-lang').textContent = i18n.getLocale().toUpperCase()
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('app-header', AppHeader);
|
||||
customElements.define('app-header', AppHeader)
|
||||
|
||||
Reference in New Issue
Block a user