@@ -1068,11 +1068,40 @@ <h4>📸 Upload Book Cover</h4>
10681068 } ) ;
10691069 $ ( '.copy-code' ) . off ( 'click' ) . on ( 'click' , function ( ) {
10701070 const code = $ ( this ) . data ( 'code' ) ;
1071- navigator . clipboard . writeText ( code ) . then ( ( ) => notifySuccess ( 'Classroom code copied to clipboard!' ) ) ;
1071+ copyToClipboard ( code ) ;
10721072 } ) ;
10731073 $ ( '#confirmEditClassNameBtn' ) . off ( 'click' ) . on ( 'click' , changeClassName ) ;
10741074 } catch ( e ) { console . error ( e ) ; }
10751075 }
1076+ function copyToClipboard ( text ) {
1077+ if ( navigator . clipboard && window . isSecureContext ) {
1078+ navigator . clipboard . writeText ( text ) . then ( ( ) => {
1079+ notifySuccess ( 'Classroom code copied to clipboard!' ) ;
1080+ } ) . catch ( err => {
1081+ console . warn ( 'Clipboard API failed, using fallback.' , err ) ;
1082+ fallbackCopy ( text ) ;
1083+ } ) ;
1084+ } else {
1085+ fallbackCopy ( text ) ;
1086+ }
1087+ }
1088+ function fallbackCopy ( text ) {
1089+ const textarea = document . createElement ( 'textarea' ) ;
1090+ textarea . value = text ;
1091+ textarea . style . position = 'fixed' ;
1092+ textarea . style . top = '-9999px' ;
1093+ textarea . style . left = '-9999px' ;
1094+ document . body . appendChild ( textarea ) ;
1095+ textarea . select ( ) ;
1096+ textarea . setSelectionRange ( 0 , text . length ) ;
1097+ const success = document . execCommand ( 'copy' ) ;
1098+ document . body . removeChild ( textarea ) ;
1099+ if ( success ) {
1100+ notifySuccess ( 'Classroom code copied to clipboard!' ) ;
1101+ } else {
1102+ notifyError ( 'Failed to copy. Please copy manually.' ) ;
1103+ }
1104+ }
10761105 async function showClassroomUsers ( id , name ) {
10771106 try {
10781107 const data = await apiCall ( 'GET' , `/api/classrooms/${ id } /users` ) ;
0 commit comments