Files
desk-moloni/modules/desk_moloni/views/admin/config.php
Emanuel Almeida 8c4f68576f chore: add spec-kit and standardize signatures
- Added GitHub spec-kit for development workflow
- Standardized file signatures to Descomplicar® format
- Updated development configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-12 01:27:37 +01:00

424 lines
21 KiB
PHP

/**
* Descomplicar® Crescimento Digital
* https://descomplicar.pt
*/
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
<div class="row">
<div class="col-md-12">
<div class="panel_s">
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<h4 class="no-margin">
<i class="fa fa-cog" aria-hidden="true"></i>
<?php echo _l('desk_moloni_configuration'); ?>
</h4>
</div>
<div class="col-md-6 text-right">
<?php if (has_permission('desk_moloni', '', 'edit')) { ?>
<button type="button" class="btn btn-info" id="test-connection">
<i class="fa fa-plug"></i> <?php echo _l('desk_moloni_test_connection'); ?>
</button>
<?php } ?>
<a href="<?php echo admin_url('modules/desk_moloni'); ?>" class="btn btn-default">
<i class="fa fa-arrow-left"></i> <?php echo _l('back_to_dashboard'); ?>
</a>
</div>
</div>
<hr class="hr-panel-separator" />
<!-- OAuth Configuration Section -->
<div class="row">
<div class="col-md-12">
<div class="panel_s">
<div class="panel-body">
<h4><i class="fa fa-key"></i> <?php echo _l('desk_moloni_oauth_configuration'); ?></h4>
<div class="row">
<div class="col-md-6">
<div id="oauth-status-card" class="alert <?php echo $oauth_status['configured'] ? 'alert-success' : 'alert-warning'; ?>">
<div class="row">
<div class="col-md-2">
<i class="fa <?php echo $oauth_status['configured'] ? 'fa-check-circle' : 'fa-exclamation-triangle'; ?> fa-3x"></i>
</div>
<div class="col-md-10">
<h5><?php echo $oauth_status['configured'] ? _l('desk_moloni_oauth_configured') : _l('desk_moloni_oauth_not_configured'); ?></h5>
<p><?php echo $oauth_status['message']; ?></p>
<?php if ($oauth_status['configured'] && !empty($oauth_status['expires_at'])) { ?>
<small><?php echo _l('desk_moloni_token_expires'); ?>: <?php echo date('Y-m-d H:i:s', strtotime($oauth_status['expires_at'])); ?></small>
<?php } ?>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<?php if (!$oauth_status['configured']) { ?>
<a href="<?php echo admin_url('modules/desk_moloni/oauth_setup'); ?>" class="btn btn-primary btn-lg btn-block">
<i class="fa fa-magic"></i> <?php echo _l('desk_moloni_setup_oauth'); ?>
</a>
<?php } else { ?>
<div class="btn-group-vertical btn-block">
<a href="<?php echo admin_url('modules/desk_moloni/oauth_setup'); ?>" class="btn btn-default">
<i class="fa fa-edit"></i> <?php echo _l('desk_moloni_update_oauth'); ?>
</a>
<button type="button" class="btn btn-warning" id="refresh-token">
<i class="fa fa-refresh"></i> <?php echo _l('desk_moloni_refresh_token'); ?>
</button>
</div>
<?php } ?>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Main Configuration Form -->
<?php echo form_open(admin_url('modules/desk_moloni/config'), array('id' => 'desk-moloni-config-form')); ?>
<!-- General Settings -->
<div class="row">
<div class="col-md-12">
<div class="panel_s">
<div class="panel-body">
<h4><i class="fa fa-sliders"></i> <?php echo _l('desk_moloni_general_settings'); ?></h4>
<div class="row">
<div class="col-md-6">
<?php
$selected = isset($config['moloni_company_id']) ? $config['moloni_company_id'] : '';
echo render_select('moloni_company_id', $companies, array('id', 'name'), 'desk_moloni_company', $selected, array('data-none-selected-text' => _l('desk_moloni_select_company')));
?>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="sync_enabled" id="sync_enabled" value="1" <?php echo (isset($config['sync_enabled']) && $config['sync_enabled'] === '1') ? 'checked' : ''; ?>>
<label for="sync_enabled"><?php echo _l('desk_moloni_enable_sync'); ?></label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Auto-Sync Settings -->
<div class="row">
<div class="col-md-12">
<div class="panel_s">
<div class="panel-body">
<h4><i class="fa fa-refresh"></i> <?php echo _l('desk_moloni_auto_sync_settings'); ?></h4>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="auto_sync_clients" id="auto_sync_clients" value="1" <?php echo (isset($config['auto_sync_clients']) && $config['auto_sync_clients'] === '1') ? 'checked' : ''; ?>>
<label for="auto_sync_clients">
<i class="fa fa-users"></i> <?php echo _l('desk_moloni_auto_sync_clients'); ?>
</label>
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="auto_sync_products" id="auto_sync_products" value="1" <?php echo (isset($config['auto_sync_products']) && $config['auto_sync_products'] === '1') ? 'checked' : ''; ?>>
<label for="auto_sync_products">
<i class="fa fa-cube"></i> <?php echo _l('desk_moloni_auto_sync_products'); ?>
</label>
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="auto_sync_invoices" id="auto_sync_invoices" value="1" <?php echo (isset($config['auto_sync_invoices']) && $config['auto_sync_invoices'] === '1') ? 'checked' : ''; ?>>
<label for="auto_sync_invoices">
<i class="fa fa-file-text"></i> <?php echo _l('desk_moloni_auto_sync_invoices'); ?>
</label>
</div>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="auto_sync_estimates" id="auto_sync_estimates" value="1" <?php echo (isset($config['auto_sync_estimates']) && $config['auto_sync_estimates'] === '1') ? 'checked' : ''; ?>>
<label for="auto_sync_estimates">
<i class="fa fa-file-o"></i> <?php echo _l('desk_moloni_auto_sync_estimates'); ?>
</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="queue_processing_enabled" id="queue_processing_enabled" value="1" <?php echo (isset($config['queue_processing_enabled']) && $config['queue_processing_enabled'] === '1') ? 'checked' : ''; ?>>
<label for="queue_processing_enabled">
<i class="fa fa-cogs"></i> <?php echo _l('desk_moloni_enable_queue_processing'); ?>
</label>
</div>
<small class="help-block"><?php echo _l('desk_moloni_queue_processing_help'); ?></small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Advanced Settings -->
<div class="row">
<div class="col-md-12">
<div class="panel_s">
<div class="panel-body">
<h4><i class="fa fa-cogs"></i> <?php echo _l('desk_moloni_advanced_settings'); ?></h4>
<div class="row">
<div class="col-md-4">
<?php
$retry_attempts = isset($config['max_retry_attempts']) ? $config['max_retry_attempts'] : '3';
echo render_input('max_retry_attempts', 'desk_moloni_max_retry_attempts', $retry_attempts, 'number', array('min' => '1', 'max' => '10'));
?>
</div>
<div class="col-md-4">
<?php
$sync_interval = isset($config['sync_interval']) ? $config['sync_interval'] : '300';
echo render_input('sync_interval', 'desk_moloni_sync_interval_seconds', $sync_interval, 'number', array('min' => '60', 'max' => '3600'));
?>
</div>
<div class="col-md-4">
<?php
$batch_size = isset($config['batch_size']) ? $config['batch_size'] : '50';
echo render_input('batch_size', 'desk_moloni_batch_size', $batch_size, 'number', array('min' => '1', 'max' => '200'));
?>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="checkbox checkbox-primary">
<input type="checkbox" name="debug_mode" id="debug_mode" value="1" <?php echo (isset($config['debug_mode']) && $config['debug_mode'] === '1') ? 'checked' : ''; ?>>
<label for="debug_mode">
<i class="fa fa-bug"></i> <?php echo _l('desk_moloni_enable_debug_mode'); ?>
</label>
</div>
<small class="help-block"><?php echo _l('desk_moloni_debug_mode_help'); ?></small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Save Button -->
<div class="row">
<div class="col-md-12">
<?php if (has_permission('desk_moloni', '', 'edit')) { ?>
<button type="submit" class="btn btn-primary pull-right">
<i class="fa fa-save"></i> <?php echo _l('save_settings'); ?>
</button>
<?php } ?>
<div class="clearfix"></div>
</div>
</div>
<?php echo form_close(); ?>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Test connection functionality
$('#test-connection').on('click', function() {
var btn = $(this);
var originalText = btn.html();
btn.prop('disabled', true)
.html('<i class="fa fa-spinner fa-spin"></i> <?php echo _l("desk_moloni_testing_connection"); ?>');
$.ajax({
url: admin_url + 'modules/desk_moloni/test_connection',
type: 'POST',
dataType: 'json',
success: function(response) {
if (response.success) {
alert_float('success', response.message);
} else {
alert_float('danger', response.message);
}
},
error: function(xhr, status, error) {
alert_float('danger', '<?php echo _l("desk_moloni_connection_test_failed"); ?>');
},
complete: function() {
btn.prop('disabled', false).html(originalText);
}
});
});
// Refresh token functionality
$('#refresh-token').on('click', function() {
var btn = $(this);
var originalText = btn.html();
if (!confirm('<?php echo _l("desk_moloni_refresh_token_confirm"); ?>')) {
return;
}
btn.prop('disabled', true)
.html('<i class="fa fa-spinner fa-spin"></i> <?php echo _l("desk_moloni_refreshing_token"); ?>');
$.ajax({
url: admin_url + 'modules/desk_moloni/refresh_oauth_token',
type: 'POST',
dataType: 'json',
success: function(response) {
if (response.success) {
alert_float('success', response.message);
setTimeout(function() {
window.location.reload();
}, 1500);
} else {
alert_float('danger', response.message);
}
},
error: function(xhr, status, error) {
alert_float('danger', '<?php echo _l("desk_moloni_token_refresh_failed"); ?>');
},
complete: function() {
btn.prop('disabled', false).html(originalText);
}
});
});
// Form validation
$('#desk-moloni-config-form').on('submit', function(e) {
var syncEnabled = $('#sync_enabled').is(':checked');
var oauthConfigured = <?php echo $oauth_status['configured'] ? 'true' : 'false'; ?>;
if (syncEnabled && !oauthConfigured) {
e.preventDefault();
alert_float('warning', '<?php echo _l("desk_moloni_oauth_required_for_sync"); ?>');
return false;
}
// Show loading state
var submitBtn = $(this).find('button[type="submit"]');
var originalText = submitBtn.html();
submitBtn.prop('disabled', true)
.html('<i class="fa fa-spinner fa-spin"></i> <?php echo _l("saving"); ?>');
// Re-enable button after form submission
setTimeout(function() {
submitBtn.prop('disabled', false).html(originalText);
}, 3000);
});
// Enable/disable auto-sync options based on main sync toggle
$('#sync_enabled').on('change', function() {
var autoSyncCheckboxes = $('input[name^="auto_sync_"]');
if ($(this).is(':checked')) {
autoSyncCheckboxes.prop('disabled', false);
} else {
autoSyncCheckboxes.prop('checked', false).prop('disabled', true);
}
}).trigger('change');
// Show/hide advanced settings
var advancedVisible = false;
$('#show-advanced-settings').on('click', function(e) {
e.preventDefault();
var advancedPanel = $('#advanced-settings-panel');
if (advancedVisible) {
advancedPanel.slideUp();
$(this).html('<i class="fa fa-plus"></i> <?php echo _l("desk_moloni_show_advanced_settings"); ?>');
advancedVisible = false;
} else {
advancedPanel.slideDown();
$(this).html('<i class="fa fa-minus"></i> <?php echo _l("desk_moloni_hide_advanced_settings"); ?>');
advancedVisible = true;
}
});
// Input validation
$('input[type="number"]').on('input', function() {
var value = parseInt($(this).val());
var min = parseInt($(this).attr('min'));
var max = parseInt($(this).attr('max'));
if (value < min) {
$(this).val(min);
} else if (value > max) {
$(this).val(max);
}
});
});
</script>
<style>
.alert {
border-radius: 8px;
}
.alert .fa {
margin-right: 0;
}
.checkbox label {
padding-left: 0;
}
.checkbox input[type="checkbox"] {
margin-right: 8px;
position: relative;
top: 1px;
}
.panel_s {
margin-bottom: 20px;
}
.form-group .help-block {
margin-top: 5px;
font-size: 11px;
color: #737373;
}
#oauth-status-card {
border: none;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
#oauth-status-card h5 {
margin-top: 0;
font-weight: bold;
}
#oauth-status-card .fa {
margin-right: 0;
}
.btn-group-vertical .btn {
margin-bottom: 5px;
}
.btn-group-vertical .btn:last-child {
margin-bottom: 0;
}
</style>