refactor: split CSS and JS into modular files (SRP)

This commit is contained in:
2025-12-26 13:55:02 +01:00
parent 94cf36bff3
commit 2e5731b5d6
47 changed files with 8882 additions and 2298 deletions

View File

@@ -0,0 +1,294 @@
/**
* AniWorld - Main Config Module
*
* Handles main configuration (directory, connection) and config management
* (backup, export, validate, reset).
*
* Dependencies: constants.js, api-client.js, ui-utils.js
*/
var AniWorld = window.AniWorld || {};
AniWorld.MainConfig = (function() {
'use strict';
const API = AniWorld.Constants.API;
/**
* Save main configuration
*/
async function save() {
try {
const animeDirectory = document.getElementById('anime-directory-input').value.trim();
if (!animeDirectory) {
AniWorld.UI.showToast('Please enter an anime directory path', 'error');
return;
}
const response = await AniWorld.ApiClient.post(API.CONFIG_DIRECTORY, {
directory: animeDirectory
});
if (!response) return;
const data = await response.json();
if (data.success) {
AniWorld.UI.showToast('Main configuration saved successfully', 'success');
await refreshStatus();
} else {
AniWorld.UI.showToast('Failed to save configuration: ' + data.error, 'error');
}
} catch (error) {
console.error('Error saving main config:', error);
AniWorld.UI.showToast('Failed to save main configuration', 'error');
}
}
/**
* Reset main configuration
*/
function reset() {
if (confirm('Are you sure you want to reset the main configuration? This will clear the anime directory.')) {
document.getElementById('anime-directory-input').value = '';
document.getElementById('series-count-input').value = '0';
AniWorld.UI.showToast('Main configuration reset', 'info');
}
}
/**
* Test network connection
*/
async function testConnection() {
try {
AniWorld.UI.showToast('Testing connection...', 'info');
const response = await AniWorld.ApiClient.get(API.DIAGNOSTICS_NETWORK);
if (!response) return;
const data = await response.json();
if (data.status === 'success') {
const networkStatus = data.data;
const connectionDiv = document.getElementById('connection-status-display');
const statusIndicator = connectionDiv.querySelector('.status-indicator');
const statusText = connectionDiv.querySelector('.status-text');
if (networkStatus.aniworld_reachable) {
statusIndicator.className = 'status-indicator connected';
statusText.textContent = 'Connected';
AniWorld.UI.showToast('Connection test successful', 'success');
} else {
statusIndicator.className = 'status-indicator disconnected';
statusText.textContent = 'Disconnected';
AniWorld.UI.showToast('Connection test failed', 'error');
}
} else {
AniWorld.UI.showToast('Connection test failed', 'error');
}
} catch (error) {
console.error('Error testing connection:', error);
AniWorld.UI.showToast('Connection test failed', 'error');
}
}
/**
* Browse for directory
*/
function browseDirectory() {
const currentPath = document.getElementById('anime-directory-input').value;
const newPath = prompt('Enter the anime directory path:', currentPath);
if (newPath !== null && newPath.trim() !== '') {
document.getElementById('anime-directory-input').value = newPath.trim();
}
}
/**
* Refresh status display
*/
async function refreshStatus() {
try {
const response = await AniWorld.ApiClient.get(API.ANIME_STATUS);
if (!response) return;
const data = await response.json();
document.getElementById('anime-directory-input').value = data.directory || '';
document.getElementById('series-count-input').value = data.series_count || '0';
} catch (error) {
console.error('Error refreshing status:', error);
}
}
/**
* Create configuration backup
*/
async function createBackup() {
const backupName = prompt('Enter backup name (optional):');
try {
const response = await AniWorld.ApiClient.request(API.CONFIG_BACKUP, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: backupName || '' })
});
if (!response) return;
const data = await response.json();
if (data.success) {
AniWorld.UI.showToast('Backup created: ' + data.filename, 'success');
} else {
AniWorld.UI.showToast('Failed to create backup: ' + data.error, 'error');
}
} catch (error) {
console.error('Error creating backup:', error);
AniWorld.UI.showToast('Failed to create backup', 'error');
}
}
/**
* View configuration backups
*/
async function viewBackups() {
try {
const response = await AniWorld.ApiClient.get(API.CONFIG_BACKUPS);
if (!response) return;
const data = await response.json();
if (data.success) {
showBackupsModal(data.backups);
} else {
AniWorld.UI.showToast('Failed to load backups: ' + data.error, 'error');
}
} catch (error) {
console.error('Error loading backups:', error);
AniWorld.UI.showToast('Failed to load backups', 'error');
}
}
/**
* Show backups modal
*/
function showBackupsModal(backups) {
// Implementation for showing backups modal
console.log('Backups:', backups);
AniWorld.UI.showToast('Found ' + backups.length + ' backup(s)', 'info');
}
/**
* Export configuration
*/
function exportConfig() {
AniWorld.UI.showToast('Export configuration feature coming soon', 'info');
}
/**
* Validate configuration
*/
async function validateConfig() {
try {
const response = await AniWorld.ApiClient.request(API.CONFIG_VALIDATE, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
if (!response) return;
const data = await response.json();
if (data.success) {
showValidationResults(data.validation);
} else {
AniWorld.UI.showToast('Validation failed: ' + data.error, 'error');
}
} catch (error) {
console.error('Error validating config:', error);
AniWorld.UI.showToast('Failed to validate configuration', 'error');
}
}
/**
* Show validation results
*/
function showValidationResults(validation) {
const container = document.getElementById('validation-results');
container.innerHTML = '';
container.classList.remove('hidden');
if (validation.valid) {
const success = document.createElement('div');
success.className = 'validation-success';
success.innerHTML = '<i class="fas fa-check-circle"></i> Configuration is valid!';
container.appendChild(success);
} else {
const header = document.createElement('div');
header.innerHTML = '<strong>Validation Issues Found:</strong>';
container.appendChild(header);
}
// Show errors
validation.errors.forEach(function(error) {
const errorDiv = document.createElement('div');
errorDiv.className = 'validation-error';
errorDiv.innerHTML = '<i class="fas fa-times-circle"></i> Error: ' + error;
container.appendChild(errorDiv);
});
// Show warnings
validation.warnings.forEach(function(warning) {
const warningDiv = document.createElement('div');
warningDiv.className = 'validation-warning';
warningDiv.innerHTML = '<i class="fas fa-exclamation-triangle"></i> Warning: ' + warning;
container.appendChild(warningDiv);
});
}
/**
* Reset all configuration to defaults
*/
async function resetAllConfig() {
if (!confirm('Are you sure you want to reset all configuration to defaults? This cannot be undone (except by restoring a backup).')) {
return;
}
try {
const response = await AniWorld.ApiClient.request(API.CONFIG_RESET, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ preserve_security: true })
});
if (!response) return;
const data = await response.json();
if (data.success) {
AniWorld.UI.showToast('Configuration reset to defaults', 'success');
// Notify caller to reload config modal
return true;
} else {
AniWorld.UI.showToast('Failed to reset config: ' + data.error, 'error');
return false;
}
} catch (error) {
console.error('Error resetting config:', error);
AniWorld.UI.showToast('Failed to reset configuration', 'error');
return false;
}
}
// Public API
return {
save: save,
reset: reset,
testConnection: testConnection,
browseDirectory: browseDirectory,
refreshStatus: refreshStatus,
createBackup: createBackup,
viewBackups: viewBackups,
exportConfig: exportConfig,
validateConfig: validateConfig,
resetAllConfig: resetAllConfig
};
})();