Add password validation with i18n support and GitHub button improvements
- Add password field to UserUpdate schema for password change on edit - Implement password validation in update_user endpoint - Add i18n translations for password validation errors (ru/en) - Update SecurityService.validate_password to support language parameter - Add GitHub icon and repository name 'pvemanager' to header button - Fix internal server error when updating user password - Clean up hardcoded translations in frontend
This commit is contained in:
@@ -610,6 +610,16 @@ body.update-in-progress .layout {
|
||||
</button>
|
||||
<h2>{{ page_title or title or t('nav_dashboard') }}</h2>
|
||||
<div class="header-actions">
|
||||
<!-- GitHub Stars Button -->
|
||||
<a href="https://github.com/markmorado/pvemanager" target="_blank" rel="noopener noreferrer" class="github-btn" title="Star us on GitHub">
|
||||
<i class="fa-brands fa-github"></i>
|
||||
<span class="github-text">pvemanager</span>
|
||||
<svg class="github-star-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z"/>
|
||||
</svg>
|
||||
<span class="github-stars" id="githubStars">...</span>
|
||||
</a>
|
||||
|
||||
<!-- Theme Toggle Button -->
|
||||
<button id="themeToggle" class="theme-toggle" title="{{ t('theme') }}">
|
||||
<svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
@@ -851,6 +861,36 @@ body.update-in-progress .layout {
|
||||
}
|
||||
});
|
||||
|
||||
// Load GitHub stars count
|
||||
async function loadGitHubStars() {
|
||||
try {
|
||||
const response = await fetch('https://api.github.com/repos/markmorado/pvemanager', {
|
||||
headers: {
|
||||
'Accept': 'application/vnd.github.v3+json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
const starsElement = document.getElementById('githubStars');
|
||||
if (starsElement) {
|
||||
// Format number with K for thousands
|
||||
const stars = data.stargazers_count;
|
||||
const formatted = stars >= 1000
|
||||
? (stars / 1000).toFixed(1) + 'K'
|
||||
: stars.toString();
|
||||
starsElement.textContent = formatted;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load GitHub stars:', error);
|
||||
const starsElement = document.getElementById('githubStars');
|
||||
if (starsElement) {
|
||||
starsElement.textContent = '★';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load unread notification count
|
||||
async function loadNotificationCount() {
|
||||
try {
|
||||
@@ -1268,6 +1308,9 @@ body.update-in-progress .layout {
|
||||
|
||||
// Refresh count every 30 seconds
|
||||
setInterval(loadNotificationCount, 30000);
|
||||
|
||||
// Load GitHub stars count
|
||||
loadGitHubStars();
|
||||
}
|
||||
|
||||
// Add click handlers for sidebar menu items to update page title
|
||||
|
||||
Reference in New Issue
Block a user