Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
172 lines (158 loc) · 9.78 KB
/
Copy pathscript.js
File metadata and controls
172 lines (158 loc) · 9.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
const API_BASE='https://sunnah.amanahagent.cloud/api/v1';
const API_KEY=window.AMANAH_API_KEY||'';
const toast=document.getElementById('toast');
const input=document.getElementById('searchInput');
const backdrop=document.getElementById('modalBackdrop');
const modalBody=document.getElementById('modalBody');
const modalClose=document.getElementById('modalClose');
function showToast(message){
toast.textContent=message;
toast.classList.add('show');
clearTimeout(window._toast);
window._toast=setTimeout(()=>toast.classList.remove('show'),2600);
}
function openModal(title,html){
modalBody.innerHTML='<h2 id="modalTitle">'+title+'</h2>'+html;
backdrop.classList.add('show');
document.body.classList.add('modal-open');
}
function closeModal(){
backdrop.classList.remove('show');
document.body.classList.remove('modal-open');
}
modalClose.onclick=closeModal;
backdrop.onclick=e=>{if(e.target===backdrop)closeModal()};
document.addEventListener('keydown',e=>{if(e.key==='Escape')closeModal()});
async function api(path,options={}){
if(!API_KEY) throw new Error('API configuration is not available yet.');
const res=await fetch(API_BASE+path,{
...options,
headers:{'Content-Type':'application/json','X-API-Key':API_KEY,...(options.headers||{})}
});
let data={}; try{data=await res.json()}catch{}
if(!res.ok) throw new Error(data.error||'Unable to load Islamic knowledge.');
return data;
}
function esc(v=''){return String(v).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]))}
function loading(title){openModal(title,'<div class="loading">Loading Islamic knowledge…</div>')}
function errorBox(err){openModal('Unable to load', '<div class="error-box">'+esc(err.message||err)+'</div>')}
async function searchKnowledge(q){
loading('Search results');
try{
const data=await api('/search',{method:'POST',body:JSON.stringify({q,type:'',limit:10})});
const results=data.results||[];
const html=results.length?'<div class="result-list">'+results.map((r,i)=>{
const type=r._type||'result', title=r.collection_name||r.surah_name_en||type;
const text=r.text_arabic||r.text_hindi||r.text||r.name||'';
return '<article class="result-item"><span class="result-type">'+esc(type)+'</span><h3>'+esc(title)+'</h3><p class="arabic-result">'+esc(r.text_arabic||'')+'</p><p>'+esc(r.text_hindi||'Hindi translation is not available from the selected verified source.')+'</p><small>'+esc(r.hadith_key||r.ayah_key||'')+'</small></article>'
}).join('')+'</div>':'<div class="empty-state">No matching references were found.</div>';
openModal('Search: '+esc(q),html);
}catch(e){errorBox(e)}
}
async function loadQuran(key='2:255'){
loading('Quran');
try{
// Arabic text + Hindi translation from established Quran editions.
// No machine translation is performed here.
const [arabicRes,hindiRes]=await Promise.all([
api('/quran/'+encodeURIComponent(key)),
fetch('https://api.alquran.cloud/v1/surah/'+encodeURIComponent(key.split(':')[0])+'/hi.hindi')
.then(r=>{if(!r.ok) throw new Error('Hindi Quran translation source is unavailable.'); return r.json()})
]);
const surahData=hindiRes.data||{};
const ayahNo=Number(key.split(':')[1]);
const h=(surahData.ayahs||[]).find(a=>a.numberInSurah===ayahNo)||{};
const d=arabicRes;
openModal((d.surah_name_en||'Quran')+' — '+esc(d.ayah_key||key),
'<div class="detail-card"><div class="arabic-large">'+esc(d.text_arabic||h.text||'')+'</div><p>'+esc(h.text||'Hindi translation unavailable for this ayah.')+'</p><small>Surah '+esc(d.surah_name_en||h.surah?.englishName||'')+' ('+esc(d.ayah_key||key)+') · Hindi edition: hi.hindi</small></div>');
}catch(e){errorBox(e)}
}
async function loadHadith(key='bukhari:1'){
loading('Hadith');
try{
const d=await api('/hadith/'+encodeURIComponent(key));
openModal(esc(d.collection_name||'Hadith')+' — '+esc(d.hadith_number||key),
'<div class="detail-card"><div class="arabic-large">'+esc(d.text_arabic||'')+'</div><p>'+esc(d.text_hindi||'Hindi translation is not available from the selected verified source.')+'</p><div class="source-line">'+esc((d.grades||[]).map(x=>x.grade).join(', ')||'Reference available')+'</div></div>');
}catch(e){errorBox(e)}
}
async function loadList(endpoint,title,mapper){
loading(title);
try{
const d=await api(endpoint);
const arr=Array.isArray(d)?d:(d.results||d.data||d.items||d.names||d.duas||d.amalan||[]);
const html=arr.length?'<div class="result-list">'+arr.map(mapper).join('')+'</div>':'<div class="empty-state">No content available.</div>';
openModal(title,html);
}catch(e){errorBox(e)}
}
const simpleMapper=item=>{
const name=item.name||item.name_en||item.title||item.name_arabic||'';
const ar=item.arabic||item.text_arabic||item.arabic_text||'';
const en=item.meaning_hindi||item.translation_hindi||item.text_hindi||item.description_hindi||item.benefit_hindi||'';
return '<article class="result-item"><h3>'+esc(name)+'</h3><p class="arabic-result">'+esc(ar)+'</p><p>'+esc(en)+'</p></article>'
};
async function loadDuas(){
await loadList('/doa','Daily Duas',item=>{
const name=item.name_hindi||item.title_hindi||item.name||item.title||'Dua';
const ar=item.arabic||item.text_arabic||item.arabic_text||'';
const hi=item.text_hindi||item.translation_hindi||item.meaning_hindi||'';
const ref=item.reference||item.source||'';
return '<article class="result-item"><h3>'+esc(name)+'</h3><p class="arabic-result">'+esc(ar)+'</p><p>'+esc(hi||'इस दुआ का प्रमाणित हिंदी अनुवाद इस API में उपलब्ध नहीं है। हमने जानबूझकर इंडोनेशियाई या मशीन-अनुवाद नहीं दिखाया है।')+'</p><small>'+esc(ref)+'</small></article>'
})
}
async function loadNames(){await loadList('/asmaul-husna','99 Names of Allah',simpleMapper)}
async function loadSunnah(){await loadList('/amalan','Sunnah Practices',simpleMapper)}
async function loadCalendar(){
loading('Islamic Calendar');
try{
const d=await api('/sunnah-calendar?date='+new Date().toISOString().slice(0,10));
const events=(d.events||[]).map(x=>'<li><b>'+esc(x.label)+'</b><small>'+esc(x.dalil||'')+'</small></li>').join('');
openModal('Islamic Calendar','<div class="detail-card"><h3>'+esc(d.hijri?.day||'')+' '+esc(d.hijri?.monthName||'')+' '+esc(d.hijri?.year||'')+' AH</h3><p>'+esc(d.date||'')+'</p><ul class="event-list">'+(events||'<li>No special event listed for today.</li>')+'</ul></div>');
}catch(e){errorBox(e)}
}
document.getElementById('searchForm').addEventListener('submit',e=>{
e.preventDefault();
const q=input.value.trim();
if(q) searchKnowledge(q); else input.focus();
});
document.getElementById('focusSearch').onclick=()=>{
input.focus();window.scrollTo({top:0,behavior:'smooth'});
};
document.querySelectorAll('.popular button').forEach(b=>b.onclick=()=>{
input.value=b.textContent.trim();searchKnowledge(input.value.trim());
});
document.getElementById('menuBtn').onclick=()=>document.querySelector('.nav').classList.toggle('open');
document.querySelectorAll('.nav a').forEach(a=>a.onclick=()=>document.querySelector('.nav').classList.remove('open'));
document.querySelectorAll('.feature').forEach(card=>card.addEventListener('click',e=>{
const target=card.getAttribute('href');
if(target==='#quran'){e.preventDefault();loadQuran()}
else if(target==='#hadith'){e.preventDefault();loadHadith()}
else if(target==='#duas'){e.preventDefault();loadDuas()}
else if(target==='#names'){e.preventDefault();loadNames()}
else if(target==='#sunnah'){e.preventDefault();loadSunnah()}
}));
document.querySelectorAll('.quick a').forEach(a=>a.addEventListener('click',e=>{
const t=a.textContent.toLowerCase();
if(t.includes('duas')){e.preventDefault();loadDuas()}
else if(t.includes('calendar')){e.preventDefault();loadCalendar()}
else if(t.includes('figures')){e.preventDefault();loadList('/figures','Islamic Figures',simpleMapper)}
else if(t.includes('namaz')||t.includes('fasting')||t.includes('hajj')){e.preventDefault();searchKnowledge(a.textContent.trim())}
}));
document.querySelectorAll('.topic').forEach(a=>a.addEventListener('click',e=>{
e.preventDefault();searchKnowledge(a.querySelector('b')?.textContent||a.textContent.trim());
}));
document.querySelector('.verse-card .card-head a')?.addEventListener('click',e=>{e.preventDefault();loadQuran()});
document.querySelector('.hadith-card .card-head a')?.addEventListener('click',e=>{e.preventDefault();loadHadith()});
document.querySelector('.verse-card .play')?.addEventListener('click',()=>showToast('Audio playback will be added when an audio source is available.'));
document.querySelector('.verse-card .card-foot button:nth-of-type(2)')?.addEventListener('click',()=>showToast('Audio playback will be added when an audio source is available.'));
document.querySelector('.verse-card .card-foot button:nth-of-type(4)')?.addEventListener('click',()=>loadQuran());
document.querySelector('.hadith-card .card-foot button:first-child')?.addEventListener('click',()=>loadHadith());
document.querySelectorAll('.card-foot button:last-child').forEach(btn=>btn.addEventListener('click',async()=>{
try{
await navigator.clipboard.writeText(location.href);
showToast('Link copied.');
}catch{showToast('Share link: '+location.href)}
}));
document.querySelector('.calendar .today')?.addEventListener('click',loadCalendar);
document.querySelector('.calendar-row')?.addEventListener('click',e=>{e.preventDefault();loadCalendar()});
document.querySelector('.lang')?.addEventListener('click',()=>showToast('English is currently selected. More languages can be added later.'));
if(!API_KEY) console.warn('AMANAH_API_KEY is not available. GitHub Pages deployment must generate runtime-config.js from the repository secret.');