Commit 36a0cad4 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix retroactive wizard: phone_mobile NOT NULL, datetime format, client-side validation

- phone_mobile column is NOT NULL; pass empty string instead of null
- financial_year '2020/2021' was used directly in created_at datetime; extract first year
- Add client-side step validation with red border highlights instead of alert() popups
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 56cb4395
......@@ -52,7 +52,7 @@ final class RetroactiveMembershipService
'id_type' => $nationalId ? 'national_id' : 'passport',
'date_of_birth' => $dateOfBirth,
'gender' => $gender,
'phone_mobile' => self::emptyToNull($data['phone_mobile'] ?? null),
'phone_mobile' => trim($data['phone_mobile'] ?? '') ?: '',
'phone_home' => self::emptyToNull($data['phone_home'] ?? null),
'email' => self::emptyToNull($data['email'] ?? null),
'branch_id' => (int) ($data['branch_id'] ?? 1),
......@@ -598,7 +598,7 @@ final class RetroactiveMembershipService
'status' => $status,
'payment_id' => $paymentId,
'paid_at' => ($status === 'paid') ? (self::emptyToNull($sub['paid_date'] ?? null) ?? date('Y-m-d H:i:s')) : null,
'created_at' => ($sub['financial_year'] ?? date('Y')) . '-01-01 09:00:00',
'created_at' => (explode('/', $sub['financial_year'] ?? date('Y'))[0]) . '-01-01 09:00:00',
'updated_at' => date('Y-m-d H:i:s'),
'created_by' => $empId,
]);
......
......@@ -520,11 +520,67 @@ function updateStepUI() {
if (currentStep === 2) updateTimelinePreview();
}
function nextStep() {
if (currentStep === 1 && !document.querySelector('[name=full_name_ar]').value.trim()) {
alert('الاسم بالعربية مطلوب');
return;
function markInvalid(el, msg) {
el.style.border = '2px solid #EF4444';
el.style.background = '#FEF2F2';
let hint = el.nextElementSibling;
if (!hint || !hint.classList.contains('val-hint')) {
hint = document.createElement('div');
hint.className = 'val-hint';
hint.style.cssText = 'font-size:11px;color:#DC2626;margin-top:3px;font-weight:600;';
el.parentNode.insertBefore(hint, el.nextSibling);
}
hint.textContent = msg;
}
function clearInvalid(el) {
el.style.border = '';
el.style.background = '';
const hint = el.nextElementSibling;
if (hint && hint.classList.contains('val-hint')) hint.remove();
}
function validateStep(step) {
const panel = document.getElementById('panel-' + step);
if (!panel) return true;
let valid = true;
panel.querySelectorAll('.val-hint').forEach(h => h.remove());
panel.querySelectorAll('[style*="border: 2px solid"],.form-input,.form-select').forEach(el => { el.style.border = ''; el.style.background = ''; });
const rules = {
1: [
{name: 'full_name_ar', msg: 'الاسم بالعربية مطلوب'},
{name: 'branch_id', msg: 'الفرع مطلوب'},
],
2: [
{name: 'form_date', msg: 'تاريخ الاستمارة مطلوب'},
{name: 'join_date', msg: 'تاريخ الانضمام مطلوب'},
],
3: [
{name: 'membership_value', msg: 'قيمة العضوية مطلوبة', min: 1},
],
};
const stepRules = rules[step] || [];
stepRules.forEach(function(rule) {
const el = panel.querySelector('[name="' + rule.name + '"]');
if (!el) return;
const val = el.value.trim();
if (!val || (rule.min && parseFloat(val) < rule.min)) {
markInvalid(el, rule.msg);
valid = false;
}
});
if (!valid) {
const firstBad = panel.querySelector('[style*="border: 2px solid"]');
if (firstBad) firstBad.focus();
}
return valid;
}
function nextStep() {
if (!validateStep(currentStep)) return;
if (currentStep < totalSteps) { currentStep++; updateStepUI(); window.scrollTo(0, 0); }
}
function prevStep() {
......@@ -1020,6 +1076,26 @@ function updateFinalSummary() {
document.getElementById('finalSummary').innerHTML = html;
}
// Form submit validation
document.getElementById('retroForm').addEventListener('submit', function(e) {
for (let s = 1; s <= 3; s++) {
if (!validateStep(s)) {
e.preventDefault();
currentStep = s;
updateStepUI();
window.scrollTo(0, 0);
return;
}
}
});
// Clear highlights on input
document.getElementById('retroForm').addEventListener('input', function(e) {
if (e.target.style.border && e.target.style.border.includes('solid')) {
clearInvalid(e.target);
}
});
// Init
updateStepUI();
</script>
......@@ -1028,6 +1104,8 @@ updateStepUI();
.wizard-panel .card { transition: all 0.2s; }
.wizard-panel .card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.btn-preset:hover { background: #EFF6FF !important; border-color: #2563EB !important; }
.val-hint { animation: valShake 0.3s ease; }
@keyframes valShake { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-4px)} 75%{transform:translateX(4px)} }
</style>
<?php $__template->endSection(); ?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment