/* Local UI prototype. No requests, storage, upload or database writes. Keep opaque notice IDs in links. Production must check ownership server-side. */ (() => { 'use strict'; const version=document.documentElement.dataset.staticVersion; const notices=window.chaharsuPaymentNotices || []; const byId=id=>notices.find(notice=>notice.id===id); const query=selector=>document.querySelector(selector); const money=notice=>new Intl.NumberFormat('fa-IR').format(Number(notice.amount))+' '+notice.currency; const fields=notice=>[ ['مبلغ واریز',money(notice),notice.amount,true], ['نام بانک',notice.bank,notice.bank,false], ['صاحب حساب',notice.holder,notice.holder,false], ['شماره حساب',notice.account,notice.account,true], ['شماره شبا',notice.iban,notice.iban,true], ['شماره کارت',notice.card || 'اعلام نشده',notice.card,true], ['شناسهٔ واریز',notice.deposit || 'اعلام نشده',notice.deposit,true], ['شماره فاکتور',notice.invoice || 'اعلام نشده',notice.invoice,true], ['توضیحات کارشناس',notice.description || 'توضیحی ثبت نشده',notice.description,false] ]; const link=(page,id)=>page+'?v='+version+(id?'¬ice='+encodeURIComponent(id):''); function copyTextFor(notice){ return ['اطلاعات نمایشی چهارسو — شماره‌ها ساختگی و غیرقابل پرداخت‌اند.',notice.title, 'شمارهٔ اعلامیه: '+notice.id,'تاریخ اعلام: '+notice.issued,'اعلام‌کننده: '+notice.author, ...fields(notice).map(([label,value])=>label+': '+value)].join('\n'); } let feedbackTimer; function feedback(message){ clearTimeout(feedbackTimer);query('#copy-feedback').textContent=message; feedbackTimer=setTimeout(()=>{query('#copy-feedback').textContent='';},6500); } function fallbackCopy(text){ const area=document.createElement('textarea');area.value=text;area.setAttribute('aria-label','متن کپی'); area.style.cssText='position:fixed;top:0;left:0;width:1px;height:1px;opacity:0'; document.body.append(area);area.select();let copied=false; try{copied=document.execCommand('copy');}catch(error){copied=false;}finally{area.remove();} return copied; } async function copyValue(text,label){ const previousFocus=document.activeElement; let copied=false; try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(text);copied=true;}}catch(error){copied=false;} if(!copied)copied=fallbackCopy(text); previousFocus?.focus({preventScroll:true}); if(copied){feedback(label+' کپی شد. اکنون می‌توانید آن را جای‌گذاری کنید.');return;} feedback('کپی خودکار ممکن نشد؛ متن آمادهٔ انتخاب است.'); const dialog=query('#manual-copy');query('#manual-copy-text').value=text; dialog.showModal();query('#manual-copy-text').focus();query('#manual-copy-text').select(); } function appendField(container,field,copyable=true){ const [label,value,raw,ltr]=field; const row=document.createElement('div');row.className='payment-field'; const term=document.createElement('dt');term.textContent=label; const definition=document.createElement('dd');definition.textContent=value; if(ltr){definition.dir='ltr';definition.className='numeric-value';} row.append(term,definition); if(copyable && raw){ const button=document.createElement('button');button.type='button';button.className='copy-field'; button.textContent='کپی';button.setAttribute('aria-label','کپی '+label); button.addEventListener('click',()=>copyValue(raw,label));row.append(button); }else{row.classList.add('no-copy');} container.append(row); } function makeNotice(notice){ const article=query('#notice-template').content.firstElementChild.cloneNode(true); const button=article.querySelector('.notice-toggle');const detail=article.querySelector('.notice-detail'); article.id=notice.id;button.id='toggle-'+notice.id;detail.id='details-'+notice.id; button.setAttribute('aria-controls',detail.id);detail.setAttribute('aria-labelledby',button.id); article.querySelector('.notice-title').textContent=notice.title; article.querySelector('.notice-amount').textContent=money(notice); article.querySelector('.notice-meta').textContent='فاکتور '+notice.invoice+' · '+notice.issued; const state=article.querySelector('.payment-state'); state.textContent=notice.receiptReceived?'فیش در حال بررسی':'در انتظار فیش'; state.classList.toggle('received',notice.receiptReceived); article.querySelector('.notice-author').textContent='اعلام‌شده توسط '+notice.author; article.querySelector('.notice-date').textContent='اعلامیهٔ '+notice.id; article.querySelector('.notice-bank-name').textContent=notice.bank; article.querySelector('.notice-holder').textContent=notice.holder; const container=article.querySelector('.essential-fields'); // Compact UI is a projection; copyTextFor always uses the full notice, including all supplementary information. const allFields=fields(notice); [0,3,4,5,6].forEach(index=>{const field=allFields[index];if(field[2])appendField(container,field);}); const extra=article.querySelector('.extra-fields'); [7,8].forEach(index=>appendField(extra,allFields[index],false)); article.querySelector('.copy-complete').addEventListener('click',()=>copyValue(copyTextFor(notice),'اطلاعات کامل')); article.querySelector('.receipt-link').href=link('payment-receipt.html',notice.id); button.addEventListener('click',()=>toggleNotice(article,notice)); return article; } function openNotice(article){ document.querySelectorAll('.payment-notice').forEach(item=>{ const open=item===article;item.querySelector('.notice-toggle').setAttribute('aria-expanded',String(open)); item.querySelector('.notice-detail').hidden=!open; }); } function toggleNotice(article,notice){ const open=article.querySelector('.notice-toggle').getAttribute('aria-expanded')==='true'; openNotice(open?null:article); const url=new URL(location.href);url.searchParams.delete('notice'); if(!open)url.searchParams.set('notice',notice.id); history.replaceState(null,'',url.href); } function initAccounts(){ const container=query('#payment-notices');notices.forEach(notice=>container.append(makeNotice(notice))); const search=query('#notice-search'); function filter(){ const term=search.value.trim().toLocaleLowerCase('fa');let count=0; notices.forEach(notice=>{ const article=document.getElementById(notice.id); const match=[notice.title,notice.invoice,notice.bank,notice.id].join(' ').toLocaleLowerCase('fa').includes(term); article.hidden=!match;if(match)count++; }); query('#notice-count').textContent=new Intl.NumberFormat('fa-IR').format(count)+' مورد'; query('#notices-empty').hidden=count!==0; } search.addEventListener('input',filter); query('#clear-search').addEventListener('click',()=>{search.value='';filter();search.focus();});filter(); if(!notices.length){query('#notices-empty h3').textContent='هنوز اطلاعات واریزی برای شما ارسال نشده است';query('#notices-empty p').textContent='پس از اعلام کارشناس، اطلاعات هر واریز در این بخش نمایش داده می‌شود.';query('#clear-search').hidden=true;search.disabled=true;} const id=new URLSearchParams(location.search).get('notice'); if(id){const notice=byId(id);if(notice){openNotice(document.getElementById(id));}else{feedback('این اعلامیه در دسترس نیست. فقط موارد اعلام‌شده به شما نمایش داده می‌شوند.');}} } function initReceipt(){ const select=query('#notice-select'); notices.forEach(notice=>{const option=document.createElement('option');option.value=notice.id;option.textContent=notice.invoice+' · '+money(notice)+' · '+notice.bank;select.append(option);}); if(!notices.length)query('#notice-selection-help').textContent='هنوز اعلامیه‌ای ندارید؛ از کارشناس بخواهید ایجاد کند یا واریز مستقل را انتخاب کنید.'; const modes=document.querySelectorAll('input[name="receipt-mode"]'); let invalid=false; function sync(){ const linked=query('input[name="receipt-mode"]:checked').value==='linked'; query('#linked-payment').hidden=!linked;query('#independent-help').hidden=linked; select.disabled=!linked;select.required=linked; if(!linked){select.value='';invalid=false;} const notice=linked?byId(select.value):null; query('#notice-invalid').hidden=!invalid; select.setAttribute('aria-invalid',String(invalid)); query('#selected-payment').hidden=!notice; query('#selected-fields').replaceChildren(); if(notice){ query('#selected-title').textContent=notice.title; [['مبلغ اعلام‌شده',money(notice),false],['شماره فاکتور',notice.invoice,true],['بانک مقصد',notice.bank,false],['شناسهٔ واریز',notice.deposit || 'اعلام نشده',true]].forEach(([label,value,ltr])=>appendField(query('#selected-fields'),[label,value,null,ltr],false)); query('#selected-details').href=link('bank-accounts.html',notice.id); } query('#receipt-summary').textContent=linked?(notice?'این فیش به فاکتور '+notice.invoice+' مرتبط می‌شود.':'برای فیش مرتبط، ابتدا واریز اعلام‌شده را انتخاب کنید.'):'نوع فیش: واریز مستقل؛ ارتباطی با اعلامیه‌های قبلی ندارد.'; const url=new URL(location.href);url.searchParams.delete('notice');if(notice)url.searchParams.set('notice',notice.id); history.replaceState(null,'',url.href); } const incoming=new URLSearchParams(location.search).get('notice'); if(incoming){query('input[value="linked"]').checked=true;if(byId(incoming)){select.value=incoming;}else{invalid=true;}} modes.forEach(mode=>mode.addEventListener('change',sync));select.addEventListener('change',()=>{invalid=false;sync();});sync(); const input=query('#receipt-file');const selection=query('#file-selection');const status=query('#file-status'); input.addEventListener('change',()=>{const file=input.files[0];selection.hidden=!file;status.textContent=file?'فایل انتخاب‌شده: '+file.name+' · ارسال نشده':'';}); query('#clear-file').addEventListener('click',()=>{input.value='';selection.hidden=true;status.textContent='';input.focus();}); query('#receipt-form').addEventListener('submit',event=>event.preventDefault()); } query('#select-copy-text').addEventListener('click',()=>{query('#manual-copy-text').focus();query('#manual-copy-text').select();}); query('#close-copy').addEventListener('click',()=>query('#manual-copy').close()); if(document.body.dataset.financePage==='accounts')initAccounts(); if(document.body.dataset.financePage==='receipt')initReceipt(); })();