ভর্তি ফর্ম ব্যবস্থাপনা
মোট আবেদন
অপেক্ষমাণ
অনুমোদিত
বাতিল
লোড হচ্ছে...
আবেদনের বিস্তারিত
আবেদন বাতিল করুন
`); w.document.close(); } /* ─── TEMP demo fill ─────────────────────────────────── */ function fillDemo(){ document.getElementById('wfName').value = 'রাফি মোহাম্মদ'; document.getElementById('wfDob').value = '2015-02-07'; document.getElementById('wfGender').value = 'male'; const cls = classList[0]; if(cls) document.getElementById('wfClass').value = cls.id; document.getElementById('wfDept').value = 'নূরানী'; document.getElementById('wfNotunPuraton').value = 'নতুন'; document.getElementById('wfFatherName').value = 'মুফাচ্ছির আহমদ'; document.getElementById('wfFatherPhone').value = '01746204901'; document.getElementById('wfMotherName').value = 'রাহেলা বেগম'; document.getElementById('wfMotherPhone').value = ''; document.getElementById('wfGuardianName').value = 'আমসুদ্দিন'; document.getElementById('wfRelation').value = 'ভাই'; document.getElementById('wfGuardianPhone').value = '01746204901'; document.getElementById('wfVillage').value = 'দত্তপাড়া'; document.getElementById('wfPost').value = 'বড়বক্স'; document.getElementById('wfUpazila').value = 'বানিয়াচং'; document.getElementById('wfDistrict').value = 'হবিগঞ্জ'; document.getElementById('wfPermVillage').value = 'দত্তপাড়া'; document.getElementById('wfPermPost').value = 'বড়বক্স'; document.getElementById('wfPermUpazila').value = 'বানিয়াচং'; document.getElementById('wfPermDistrict').value = 'হবিগঞ্জ'; document.getElementById('wfPrevInst').value = ''; document.getElementById('wfPrevClass').value = 'ক্লাস-২'; toast('🧪 Demo data fill হয়েছে','success'); } /* ─── smart student search ───────────────────────────── */ let _searchTimer = null; function onStudentSearch(q){ clearTimeout(_searchTimer); const dd = document.getElementById('searchDropdown'); if(!q || q.trim().length < 1){ dd.style.display='none'; return; } _searchTimer = setTimeout(()=>doStudentSearch(q.trim()), 280); } async function doStudentSearch(q){ const dd = document.getElementById('searchDropdown'); dd.innerHTML = `
খুঁজছি...
`; dd.style.display = 'block'; const { data, error } = await sb.from('students') .select('id,name,student_id,roll_number,date_of_birth,gender,class_id,department,student_type,village,post_office,upazila,district,previous_institution,previous_class,guardians(relation,name,whatsapp_number)') .or(`name.ilike.%${q}%,student_id.ilike.%${q}%`) .limit(8); if(error || !data?.length){ dd.innerHTML = `
কোনো শিক্ষার্থী পাওয়া যায়নি
`; return; } dd.innerHTML = data.map(s => { const cls = classList.find(c=>c.id===s.class_id); return `
${(s.name||'?').slice(0,2)}
${s.name||''}
ID: ${s.student_id||'—'}  ·  ${cls?.name||'শ্রেণী অজানা'}
Auto-fill →
`; }).join('') + `
${data.length} জন পাওয়া গেছে
`; // store data for fillFromStudent window._searchResults = data; // close on outside click document.addEventListener('click', function closeDD(e){ if(!document.getElementById('studentSearch').contains(e.target) && !dd.contains(e.target)){ dd.style.display='none'; document.removeEventListener('click', closeDD); } }); } function fillFromStudent(id){ const s = (window._searchResults||[]).find(x=>x.id===id); if(!s) return; document.getElementById('studentSearch').value = s.name || ''; document.getElementById('searchDropdown').style.display = 'none'; // basic info if(s.name) document.getElementById('wfName').value = s.name; if(s.date_of_birth) document.getElementById('wfDob').value = s.date_of_birth; if(s.gender) document.getElementById('wfGender').value = s.gender; if(s.class_id){ document.getElementById('wfClass').value = s.class_id; } if(s.department) document.getElementById('wfDept').value = s.department; // address if(s.village) document.getElementById('wfVillage').value = s.village; if(s.post_office) document.getElementById('wfPost').value = s.post_office; if(s.upazila) document.getElementById('wfUpazila').value = s.upazila; if(s.district) document.getElementById('wfDistrict').value = s.district; // previous institution — পুরাতন student হলে তার আগের class এখন prev হয় if(s.previous_institution) document.getElementById('wfPrevInst').value = s.previous_institution; const prevCls = classList.find(c=>c.id===s.class_id); if(prevCls) document.getElementById('wfPrevClass').value = prevCls.name; // নতুন/পুরাতন → পুরাতন document.getElementById('wfNotunPuraton').value = 'পুরাতন'; // guardians const guardians = s.guardians || []; const father = guardians.find(g=>g.relation==='father'); const mother = guardians.find(g=>g.relation==='mother'); const guardian = guardians.find(g=>g.relation!=='father'&&g.relation!=='mother'); if(father){ document.getElementById('wfFatherName').value = father.name || ''; document.getElementById('wfFatherPhone').value = toBnEn(father.whatsapp_number||''); } if(mother){ document.getElementById('wfMotherName').value = mother.name || ''; document.getElementById('wfMotherPhone').value = toBnEn(mother.whatsapp_number||''); } if(guardian){ document.getElementById('wfGuardianName').value = guardian.name || ''; document.getElementById('wfRelation').value = guardian.relation || ''; } // highlight filled fields briefly const filled = ['wfName','wfDob','wfGender','wfClass','wfDept','wfVillage','wfPost','wfUpazila','wfDistrict','wfFatherName','wfFatherPhone','wfMotherName','wfMotherPhone']; filled.forEach(id=>{ const el = document.getElementById(id); if(!el||!el.value) return; el.style.transition='background .3s'; el.style.background='#e8f5e9'; setTimeout(()=>{ el.style.background=''; }, 1800); }); toast('✅ '+s.name+' এর তথ্য auto-fill হয়েছে — প্রয়োজনে সম্পাদনা করুন','success'); } /* ─── auto-generate form no & dakhila no ────────────── */ async function loadNextNumbers(academicYear){ const { data } = await sb.from('applications') .select('form_no, dakhila_no') .eq('academic_year', academicYear) .order('created_at', {ascending: false}); const rows = data || []; // find max form_no let maxForm = 0; rows.forEach(r => { const n = parseInt(r.form_no); if(!isNaN(n) && n > maxForm) maxForm = n; }); // find max dakhila_no let maxDakhila = 0; rows.forEach(r => { const n = parseInt(r.dakhila_no); if(!isNaN(n) && n > maxDakhila) maxDakhila = n; }); const formEl = document.getElementById('wfFormNo'); const dakhilaEl = document.getElementById('wfDakhilaNo'); formEl.value = String(maxForm + 1).padStart(2, '0'); dakhilaEl.value = String(maxDakhila + 1).padStart(2, '0'); // editable — teacher can override formEl.readOnly = false; dakhilaEl.readOnly = false; formEl.style.background = ''; formEl.style.color = ''; dakhilaEl.style.background = ''; dakhilaEl.style.color = ''; } /* ─── same address copy ──────────────────────────────── */ function copySameAddress(){ document.getElementById('wfPermVillage').value = document.getElementById('wfVillage').value; document.getElementById('wfPermPost').value = document.getElementById('wfPost').value; document.getElementById('wfPermUpazila').value = document.getElementById('wfUpazila').value; document.getElementById('wfPermDistrict').value = document.getElementById('wfDistrict').value; } /* ─── scan ────────────────────────────────────────────── */ function triggerScanUpload(){ document.getElementById('scanFileInput').click(); } async function handleScanFile(input){ if(!input.files[0]) return; toast('স্ক্যান হচ্ছে... একটু অপেক্ষা করুন'); const fd = new FormData(); fd.append('image', input.files[0]); try{ const res = await fetch('/api/scan-form', {method:'POST', body:fd}); const json = await res.json(); if(json.error){ toast('স্ক্যান ব্যর্থ: '+json.error,'error'); return; } const d = json.data || json; if(d.student_name) document.getElementById('wfName').value = d.student_name; if(d.date_of_birth) document.getElementById('wfDob').value = d.date_of_birth; if(d.gender){ const gv = d.gender==='female'?'female':'male'; document.getElementById('wfGender').value=gv; } if(d.father_name) document.getElementById('wfFatherName').value = d.father_name; if(d.father_mobile) document.getElementById('wfFatherPhone').value = toBnEn(d.father_mobile); if(d.mother_name) document.getElementById('wfMotherName').value = d.mother_name; if(d.mother_mobile) document.getElementById('wfMotherPhone').value = toBnEn(d.mother_mobile); if(d.village) document.getElementById('wfVillage').value = d.village; if(d.post_office) document.getElementById('wfPost').value = d.post_office; if(d.upazila) document.getElementById('wfUpazila').value = d.upazila; if(d.district) document.getElementById('wfDistrict').value = d.district; if(d.previous_institution) document.getElementById('wfPrevInst').value = d.previous_institution; toast('✅ স্ক্যান সফল! তথ্য পূরণ হয়েছে — যাচাই করুন','success'); }catch(e){ toast('Error: '+e.message,'error'); } input.value=''; } /* ─── walk-in submit ─────────────────────────────────── */ async function submitWalkin(mode){ const name = document.getElementById('wfName').value.trim(); const classId = document.getElementById('wfClass').value; if(!name){ toast('শিক্ষার্থীর নাম দিন','error'); return; } if(!classId){ toast('শ্রেণী নির্বাচন করুন','error'); return; } const payload = { academic_year: document.getElementById('wfAcademicYear').value.trim() || null, student_name: name, dob: document.getElementById('wfDob').value || null, gender: document.getElementById('wfGender').value, class_id: classId, department: document.getElementById('wfDept').value.trim() || null, student_type: document.getElementById('wfNotunPuraton').value, father_name: document.getElementById('wfFatherName').value.trim() || null, father_phone: document.getElementById('wfFatherPhone').value.trim() || null, mother_name: document.getElementById('wfMotherName').value.trim() || null, mother_phone: document.getElementById('wfMotherPhone').value.trim() || null, guardian_name: document.getElementById('wfGuardianName').value.trim() || null, guardian_relation: document.getElementById('wfRelation').value.trim() || null, guardian_phone: document.getElementById('wfGuardianPhone').value.trim() || null, village: document.getElementById('wfVillage').value.trim() || null, post_office: document.getElementById('wfPost').value.trim() || null, upazila: document.getElementById('wfUpazila').value.trim() || null, district: document.getElementById('wfDistrict').value.trim() || null, perm_village: document.getElementById('wfPermVillage').value.trim() || null, perm_post: document.getElementById('wfPermPost').value.trim() || null, perm_upazila: document.getElementById('wfPermUpazila').value.trim() || null, perm_district: document.getElementById('wfPermDistrict').value.trim() || null, prev_institution: document.getElementById('wfPrevInst').value.trim() || null, prev_class: document.getElementById('wfPrevClass').value.trim() || null, source: 'walkin', status: mode==='direct' ? 'approved' : 'pending' }; payload.form_no = document.getElementById('wfFormNo').value.trim() || null; payload.dakhila_no = document.getElementById('wfDakhilaNo').value.trim() || null; const { data: app, error } = await sb.from('applications').insert(payload).select().single(); if(error){ toast('সংরক্ষণ ব্যর্থ: '+error.message,'error'); return; } if(mode==='direct'){ await approveApp(app.id); clearWalkinForm(); switchTab('list'); } else { toast('✅ আবেদন সংরক্ষিত হয়েছে','success'); clearWalkinForm(); await loadApps(); switchTab('list'); } } function clearWalkinForm(){ ['wfName','wfDob','wfDept','wfAcademicYear', 'wfFatherName','wfFatherPhone','wfMotherName','wfMotherPhone', 'wfGuardianName','wfRelation','wfGuardianPhone', 'wfVillage','wfPost','wfUpazila','wfDistrict', 'wfPermVillage','wfPermPost','wfPermUpazila','wfPermDistrict', 'wfPrevInst','wfPrevClass'].forEach(id=>{ const el=document.getElementById(id); if(el) el.value=''; }); document.getElementById('wfGender').value='male'; document.getElementById('wfNotunPuraton').value='নতুন'; document.getElementById('wfClass').value=''; // form_no will be auto-set on next submit document.getElementById('wfFormNo').value = 'স্বয়ংক্রিয়'; document.getElementById('wfDakhilaNo').value = 'অনুমোদনে'; } /* ─── share tab ──────────────────────────────────────── */ function setupShare(){ const url = window.location.origin + '/apply.html'; document.getElementById('shareUrl').textContent = url; } function copyLink(){ const url = document.getElementById('shareUrl').textContent; navigator.clipboard.writeText(url).then(()=>toast('লিংক কপি হয়েছে ✅')).catch(()=>toast('কপি ব্যর্থ','error')); } function shareWhatsApp(){ const url = document.getElementById('shareUrl').textContent; const instName = document.getElementById('instNameSidebar').textContent || 'আমাদের প্রতিষ্ঠান'; const msg = `আস-সালামু আলাইকুম!\n${instName}-এ ভর্তির আবেদন করুন এই লিংকে:\n${url}`; window.open('https://wa.me/?text='+encodeURIComponent(msg)); } /* ─── init ───────────────────────────────────────────── */ async function init(){ const { data:{ session } } = await sb.auth.getSession(); if(!session){ window.location.href='login.html'; return; } const { data: inst } = await sb.from('institutions').select('name,principal_name,academic_year_label,academic_year_en,academic_year_ar,address,upazila,district').eq('email', session.user.email).maybeSingle(); if(inst){ document.getElementById('instNameSidebar').textContent = inst.name || ''; const nm = inst.principal_name || ''; document.getElementById('userName').textContent = nm; if(nm) document.getElementById('userAvatar').textContent = nm.slice(0,2); // auto-fill academic year if(inst.academic_year_label){ const ayEl = document.getElementById('wfAcademicYear'); ayEl.value = inst.academic_year_label; ayEl.readOnly = true; ayEl.style.background = 'var(--surface)'; ayEl.style.color = 'var(--text-2)'; ayEl.title = 'Settings থেকে স্বয়ংক্রিয়ভাবে নেওয়া হয়েছে'; await loadNextNumbers(inst.academic_year_label); } window._instData = inst; } if(window.innerWidth<=768) document.querySelector('.bottom-nav').style.display='flex'; await Promise.all([loadClasses(), loadApps()]); setupShare(); } function doLogout(){ sb.auth.signOut().then(()=>{ window.location.href='login.html'; }); } init();
সব মেনু