1+ const params = new URLSearchParams ( window . location . search ) ;
2+ const shibirId = params . get ( "shibir_id" ) ;
3+ const sessionNo = params . get ( "session" ) || 1 ;
4+
5+ let isProcessing = false ;
6+
7+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
8+
9+ const heading = document . getElementById ( "scanner-heading" ) ;
10+ const cardInput = document . getElementById ( "cardno" ) ;
11+
12+ heading . innerText = `Tap card for Adhyayan Attendance (Session ${ sessionNo } )` ;
13+
14+ // Force focus after page load
15+ setTimeout ( ( ) => {
16+ cardInput . focus ( ) ;
17+ } , 300 ) ;
18+
19+ // Prevent losing focus
20+ setInterval ( ( ) => {
21+ if ( document . activeElement !== cardInput ) {
22+ cardInput . focus ( ) ;
23+ }
24+ } , 500 ) ;
25+
26+ // Scanner usually sends ENTER
27+ cardInput . addEventListener ( "keydown" , function ( e ) {
28+
29+ if ( e . key === "Enter" ) {
30+ e . preventDefault ( ) ;
31+
32+ const cardno = cardInput . value . trim ( ) ;
33+
34+ if ( cardno && ! isProcessing ) {
35+ markAttendance ( cardno ) ;
36+ }
37+ }
38+
39+ } ) ;
40+
41+ // Backup: if scanner doesn't send ENTER
42+ cardInput . addEventListener ( "input" , function ( ) {
43+
44+ const value = cardInput . value . trim ( ) ;
45+
46+ if ( value . length >= 4 && ! isProcessing ) {
47+ setTimeout ( ( ) => {
48+ if ( ! isProcessing && cardInput . value . trim ( ) . length >= 4 ) {
49+ markAttendance ( cardInput . value . trim ( ) ) ;
50+ }
51+ } , 50 ) ;
52+ }
53+
54+ } ) ;
55+
56+ } ) ;
57+
58+
59+ function showAlert ( element , message , type ) {
60+ element . className = `big-alert alert-${ type } ` ;
61+ element . textContent = message ;
62+ element . style . display = "block" ;
63+ }
64+
65+
66+ function resetAlert ( ) {
67+
68+ const alertBox = document . getElementById ( "alert" ) ;
69+ const formWrapper = document . getElementById ( "formWrapper" ) ;
70+
71+ alertBox . style . display = "none" ;
72+ alertBox . textContent = "" ;
73+ alertBox . className = "big-alert" ;
74+ formWrapper . style . display = "block" ;
75+
76+ }
77+
78+
79+ async function markAttendance ( cardno ) {
80+
81+ if ( isProcessing ) return ;
82+ isProcessing = true ;
83+
84+ resetAlert ( ) ;
85+
86+ try {
87+
88+ const response = await fetch (
89+ `${ CONFIG . basePath } /adhyayan/attendance/${ shibirId } /${ sessionNo } /${ cardno } ` ,
90+ {
91+ method : "POST" ,
92+ headers : {
93+ Authorization : `Bearer ${ sessionStorage . getItem ( "token" ) } `
94+ }
95+ }
96+ ) ;
97+
98+ const data = await response . json ( ) ;
99+
100+ const alertBox = document . getElementById ( "alert" ) ;
101+ const formWrapper = document . getElementById ( "formWrapper" ) ;
102+ const cardInput = document . getElementById ( "cardno" ) ;
103+
104+ formWrapper . style . display = "none" ;
105+
106+ if ( response . ok ) {
107+
108+ showAlert (
109+ alertBox ,
110+ `Attendance marked for ${ data . participantName } ` ,
111+ "success"
112+ ) ;
113+
114+ } else {
115+
116+ let alertType = "danger" ;
117+ const msg = data . message ?. toLowerCase ( ) || "" ;
118+
119+ if ( msg . includes ( "already" ) ) {
120+ alertType = "warning" ;
121+ }
122+
123+ showAlert ( alertBox , data . message || "Error marking attendance" , alertType ) ;
124+
125+ }
126+
127+ setTimeout ( ( ) => {
128+
129+ cardInput . value = "" ;
130+ resetAlert ( ) ;
131+ cardInput . focus ( ) ;
132+ isProcessing = false ;
133+
134+ } , 1000 ) ;
135+
136+ } catch ( error ) {
137+
138+ const alertBox = document . getElementById ( "alert" ) ;
139+ const formWrapper = document . getElementById ( "formWrapper" ) ;
140+ const cardInput = document . getElementById ( "cardno" ) ;
141+
142+ formWrapper . style . display = "none" ;
143+
144+ showAlert ( alertBox , "Unexpected error occurred" , "danger" ) ;
145+
146+ setTimeout ( ( ) => {
147+
148+ resetAlert ( ) ;
149+ cardInput . focus ( ) ;
150+ isProcessing = false ;
151+
152+ } , 1000 ) ;
153+
154+ }
155+
156+ }
0 commit comments