| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <?php
- /**
- * components/newClientModal.php
- *
- * Modal dialog for adding new clients.
- * Replaces modX [[!newClientDetails]] snippet.
- */
- // Start session if not already started
- if (session_status() === PHP_SESSION_NONE) {
- session_start();
- }
- // Include CSRF library
- require_once __DIR__ . '/../lib/csrf.php';
- ?>
- <script type="text/javascript">
- $(function(){
- $('#email').click(function(){
- $('#newClient').modal('show');
- return false;
- });
- // Also allow clicking on the "add new client" option in the dropdown
- $('#selectUsers').on('change', function() {
- if ($(this).val() === 'new') {
- $('#newClient').modal('show');
- $(this).val(''); // Reset dropdown
- return false;
- }
- });
- });
- </script>
- <!-- Modal -->
- <div class="modal fade" id="newClient" tabindex="-1" role="dialog" aria-labelledby="newClientLabel" aria-hidden="true">
- <div class="modal-dialog modal-lg">
- <div class="modal-content">
- <div class="modal-header">
- <h5 class="modal-title" id="newClientLabel">Add New Client</h5>
- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
- </div>
- <div class="modal-body">
- <form method="post" action="/controllers/newClientSubmit.php" id="newClientDetails" novalidate>
- <input type="hidden" name="csrf_token" value="<?php echo generateCsrfToken(); ?>">
- <input type="hidden" name="mod_user" id="mod_user" value="<?php echo htmlspecialchars($_SESSION['user_id'] ?? '', ENT_QUOTES, 'UTF-8'); ?>" required>
- <input type="hidden" name="modx_user_attributes" id="modx_user_attributes" value="<?php echo htmlspecialchars($_SESSION['user_id'] ?? '', ENT_QUOTES, 'UTF-8'); ?>" required>
- <div class="row">
- <div class="col-md-6">
- <div class="mb-3">
- <label for="Nname" class="form-label">Client Name <span class="text-danger">*</span></label>
- <input type="text" class="form-control form-control-sm" name="Nname" placeholder="Client Name" id="Nname" required maxlength="100">
- <div class="invalid-feedback">Please provide a client name.</div>
- </div>
- </div>
- <div class="col-md-6">
- <div class="mb-3">
- <label for="Ncompany" class="form-label">Company Name</label>
- <input type="text" class="form-control form-control-sm" name="Ncompany" placeholder="Company Name" id="Ncompany" maxlength="100">
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-md-6">
- <div class="mb-3">
- <label for="Nemail" class="form-label">Email Address <span class="text-danger">*</span></label>
- <input type="email" class="form-control form-control-sm" name="Nemail" placeholder="Email Address" id="Nemail" required maxlength="255">
- <div class="invalid-feedback">Please provide a valid email address.</div>
- </div>
- </div>
- <div class="col-md-6">
- <div class="mb-3">
- <label for="Nmobile" class="form-label">Mobile Number</label>
- <input type="tel" class="form-control form-control-sm" name="Nmobile" placeholder="Mobile Number" id="Nmobile" maxlength="20">
- </div>
- </div>
- </div>
- <hr>
- <div class="mb-3">
- <label for="Naddress" class="form-label">Address <span class="text-danger">*</span></label>
- <input type="text" class="form-control form-control-sm" name="Naddress" placeholder="Street Address" id="Naddress" required maxlength="255">
- <div class="invalid-feedback">Please provide an address.</div>
- </div>
- <div class="mb-3">
- <label for="Nstate" class="form-label">Town / State / Postcode <span class="text-danger">*</span></label>
- <input type="text" class="form-control form-control-sm" name="Nstate" placeholder="Town, State, Postcode" id="Nstate" required maxlength="255">
- <div class="invalid-feedback">Please provide town, state, and postcode.</div>
- <div class="form-text">Format: Town, State, Postcode (e.g., Sydney, NSW, 2000)</div>
- </div>
- </form>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
- <button form="newClientDetails" type="submit" name="NCsubmit" value="NCsubmit" class="btn btn-primary">
- <i class="fas fa-save"></i> Save Client
- </button>
- </div>
- </div>
- </div>
- </div>
- <script>
- // Bootstrap 5 form validation
- (function () {
- 'use strict'
- var forms = document.querySelectorAll('#newClientDetails')
- Array.prototype.slice.call(forms)
- .forEach(function (form) {
- form.addEventListener('submit', function (event) {
- if (!form.checkValidity()) {
- event.preventDefault()
- event.stopPropagation()
- } else {
- // Prevent default form submission and handle via AJAX
- event.preventDefault();
- submitNewClientForm(form);
- }
- form.classList.add('was-validated')
- }, false)
- })
- })()
- // AJAX form submission
- function submitNewClientForm(form) {
- const formData = new FormData(form);
- const submitBtn = form.querySelector('button[type="submit"]');
- const originalText = submitBtn.innerHTML;
- // Disable button and show loading state
- submitBtn.disabled = true;
- submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Saving...';
- fetch(form.action, {
- method: 'POST',
- body: formData
- })
- .then(response => response.json())
- .then(data => {
- if (data.success) {
- // Success - add client to dropdown and close modal
- if (window.addClientToDropdown) {
- window.addClientToDropdown(data.client);
- }
- // Close modal
- const modal = bootstrap.Modal.getInstance(document.getElementById('newClient'));
- modal.hide();
- // Show success message
- showAlert('Client added successfully!', 'success');
- } else {
- // Error - show message
- showAlert(data.message || 'Error adding client', 'danger');
- }
- })
- .catch(error => {
- console.error('Error:', error);
- showAlert('Network error occurred. Please try again.', 'danger');
- })
- .finally(() => {
- // Re-enable button
- submitBtn.disabled = false;
- submitBtn.innerHTML = originalText;
- });
- }
- // Utility function to show alerts
- function showAlert(message, type) {
- // Remove existing alerts
- const existingAlerts = document.querySelectorAll('.alert');
- existingAlerts.forEach(alert => alert.remove());
- // Create new alert
- const alertDiv = document.createElement('div');
- alertDiv.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
- alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
- alertDiv.innerHTML = `
- ${message}
- <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
- `;
- document.body.appendChild(alertDiv);
- // Auto-remove after 5 seconds
- setTimeout(() => {
- if (alertDiv.parentNode) {
- alertDiv.remove();
- }
- }, 5000);
- }
- // Clear form when modal is hidden
- document.getElementById('newClient').addEventListener('hidden.bs.modal', function () {
- document.getElementById('newClientDetails').reset();
- document.getElementById('newClientDetails').classList.remove('was-validated');
- });
- </script>
|