import { useState, useEffect } from 'react'; import * as XLSX from 'xlsx'; export default function EnhancedCommentGenerator() { // State management const [students, setStudents] = useState([]); const [classes, setClasses] = useState([]); const [selectedClass, setSelectedClass] = useState(''); const [selectedStudent, setSelectedStudent] = useState(null); const [positiveComments, setPositiveComments] = useState([]); const [developmentComments, setDevelopmentComments] = useState([]); const [behaviorComments, setBehaviorComments] = useState([]); const [improvementComments, setImprovementComments] = useState([]); const [customNotes, setCustomNotes] = useState(''); const [generatedComment, setGeneratedComment] = useState(''); const [isGenerating, setIsGenerating] = useState(false); const [characterCount, setCharacterCount] = useState(0); const [step, setStep] = useState(0); // Start at landing page (step 0) const [isUploading, setIsUploading] = useState(false); const [error, setError] = useState(''); const [generationAttempts, setGenerationAttempts] = useState(0); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [loginError, setLoginError] = useState(''); const [showLoginModal, setShowLoginModal] = useState(false); // API key is hardcoded const apiKey = "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"; // Aspire school classes const aspireClasses = [ "International Students", "7A", "7B", "7C", "8A", "8B", "8C", "9A", "9B", "9C", "10 Scientific (A)", "10 Arts (B)", "10 Arts (C)", "11 Scientific (A)", "11 Arts (B)", "11 Arts (C)", "12 Scientific (A)", "12 Arts (B)", "12 Arts (C)" ]; // Aspire student data const aspireStudentData = { "International Students": [ { id: "1908080", name: "ALSHAIKJOEGHARI MOHAMED NDAW", arabicName: "الشيخ جوغارى محمد نداو", grade: "12 (B)" }, { id: "2007030", name: "AHMAD NASIR", arabicName: "احمد ناصر", grade: "12 (A)" }, { id: "2307015", name: "ETHAN SOCORRO DEPINA ANDRADE", arabicName: "ايثان اندرادي", grade: "12 (A)" }, { id: "2308068", name: "EMMANUEL ADELEBARI FRANCIS", arabicName: "امانويل اديليبارى فرانسيس", grade: "11 (A)" }, { id: "2107028", name: "KRISTIJAN DANIJEL SARIC", arabicName: "كرستيان دانييل ساريك", grade: "11 (A)" }, { id: "2110004", name: "ABDULRAHMAN ALI POORGHARIB", arabicName: "عبدالرحمان على بورغريب", grade: "10 (A)" }, { id: "2109032", name: "FAZAL REHMAN NAEEM", arabicName: "فضل رحمان نعيم", grade: "10 (A)" }, { id: "2209058", name: "JAMAAL BADRU", arabicName: "جمال الدين", grade: "10 (A)" }, { id: "2311041", name: "OMODOT GRANT EMEM", arabicName: "اومودوت ايمم", grade: "9 (A)" }, { id: "2310029", name: "MALEK YOUNES", arabicName: "مالك يونس", grade: "9 (A)" }, { id: "2411020", name: "DENIJAL KOPIC", arabicName: "دينيجال كوبيك", grade: "9 (A)" }, { id: "2411057", name: "ZAID RIZWAN KAZI", arabicName: "زايد رضوان قاضى", grade: "9 (A)" }, { id: "2311001", name: "Abdallah LABRAOUI", arabicName: "عبدالله حميد لبراوي", grade: "8 (A)" }, { id: "2412031", name: "KAIS ELZHAR", arabicName: "كايس الزهر", grade: "8 (A)" }, { id: "2412030", name: "IURII KAZAKOV", arabicName: "اورى كازاكوف", grade: "7 (B)" } ], "7A": [ { id: "2412007", name: "ABDALLAH M. S. ABUHASANIN", arabicName: "عبد الله مثقال شحده ابو حسنين" }, { id: "2413010", name: "ABDELWAHAB MOHAMED ABDELWAHAB ABDELSALAM AHMED", arabicName: "عبد الوهاب محمد عبد الوهاب عبد السلام أحمد" }, { id: "2412011", name: "ABDULLAH ALI ABDULRAHMAN BA WAZIR", arabicName: "عبدالله علي عبدالرحمن باوزير" }, { id: "2412015", name: "AHMED MAHMOUD BEYALY MAHMOUD BEYALY BELTAGE", arabicName: "احمد محمود بيلى محمود بيلى بلتاجى" }, { id: "2412023", name: "FARES ABDULRAHIM ALHUWAIDI", arabicName: "فارس عبد الرحيم الهويدي" }, { id: "2412002", name: "HAMAD MOHAMMED A SH AL-RAYAHI", arabicName: "حمد محمد عبدالغفور شهاب الرياحي" }, { id: "2412028", name: "HASSAN MOHAMED SAMIR EID MOHAMED ALIAN", arabicName: "حسن محمد سمير عيد محمد عليان" }, { id: "2413003", name: "JAD MOHAMED HUSAM JBARA", arabicName: "جاد محمد حسام جبارة" }, { id: "2412032", name: "KAREEM MAHMOUD MOHAMED ABDELAZIZ MOHAMED", arabicName: "كريم محمود محمد عبد العزيز محمد" }, { id: "2412006", name: "OMAR RAFIK HASSAN ELBASIOUNY ABDELMAKSOUD", arabicName: "عمر رفيق حسن البسيونى عبد المقصود" }, { id: "2412055", name: "UMAR FAROOQ", arabicName: "عمر احمد" } ], "7B": [ { id: "2412012", name: "ABDULMALIK OLADIPUPO BELLO", arabicName: "عبدالملك سونكانمى توفيق بيلو" }, { id: "2411061", name: "ABOLFAZL MOHAMMADREZA GHAYEM", arabicName: "ابوالفضل محمدرضا قيم" }, { id: "2412030", name: "IURII KAZAKOV", arabicName: "اورى كازاكوف" }, { id: "2413034", name: "LAITH MOH'D BASIM AWAD", arabicName: "ليث محمد باسم عوض" }, { id: "2412004", name: "M TAIM AHMAD SABHAN", arabicName: "محمد تيم احمد صبحان" }, { id: "2412035", name: "MAHMOUD AHMED MOHAMED MOUSTAFA ELSEIRI", arabicName: "محمود احمد محمد مصطفى الصيرى" }, { id: "2412036", name: "MAHMOUD SAFWAT MAHMOUD ABDELMOHSEN MOHAMED", arabicName: "محمود صفوت محمود عبد المحسن محمد" }, { id: "2412038", name: "MOHAMED AZIZ BEN AMEUR", arabicName: "محمد عزيز بن بسام بنعامر" }, { id: "2411045", name: "MOUHAMAD NOUR JASEM ALFARAJ", arabicName: "محمد نور جاسم الفرج" }, { id: "2412047", name: "OMAR ALMAAMOUN ALABDULLA", arabicName: "عمر المامون العبد الله" }, { id: "2411049", name: "OMAR HOUSSAM MOUSTAFA HASSAN MOHAMED FARAG", arabicName: "عمر حسام مصطفى حسن محمد فرج" }, { id: "2412050", name: "OMAR HUSSEIN ABOUELENIN ABDELAZIM", arabicName: "عمر حسين ابو العنين عبد العظيم" } ], "7C": [ { id: "2412008", name: "ABDEL RAHMAN AYAD MOHAMMAD SULIMAN", arabicName: "عبد الرحمن اياد محمد سليمان" }, { id: "2412013", name: "ABDULLA SULAIMAN G A AL-SHARSHANI", arabicName: "عبدالله سليمان غانم عباس الشرشني" }, { id: "2412025", name: "FAYSAL MOHAMMED SALEM KHAMIS AL SHAMOUSI", arabicName: "فيصل بن محمد بن سالم بن خميس الشموسي" }, { id: "2412027", name: "HAMDAN ABDULRAHMAN A A ALRAFEEA", arabicName: "حمدان عبدالرحمن احمد الدلى الرفيع" }, { id: "2411059", name: "IBRAHIM KHALID S M AL-DOSARI", arabicName: "ابراهيم خالد سعد مبارك الدوسرى" }, { id: "2412033", name: "KHALFAN AHMED A K AL-MALKI", arabicName: "خلفان احمد على خميس المالكى" }, { id: "2412041", name: "MOHAMMED ALI M A AL-HITMI", arabicName: "محمد على محمد على الهتمى" }, { id: "2412046", name: "NASSER SALAH A H ZAENALABDEEN", arabicName: "ناصر صلاح عبدالرحمن حاجى زين العابدين" }, { id: "2412058", name: "REDA RAMDHAN ALMAS YOUSUF AL SAADI", arabicName: "رضا بن رمضان بن الماس بن يوسف السعدي" }, { id: "2412051", name: "SAAD ABDALLA SAAD MOHAMED ELARABI", arabicName: "سعد عبد الله سعد محمد العربى" }, { id: "2412054", name: "TAMIM AHMAD ZAREEI", arabicName: "تميم احمد زارعى" }, { id: "2412005", name: "YOUSUF ASHRAF ISMAIL ABDULLAH", arabicName: "يوسف اشرف اسماعيل عبد الله" }, { id: "2412056", name: "YOUSSEF EL DAWALI", arabicName: "يوسف حسن الدوالي" } ], "8A": [ { id: "2311001", name: "Abdallah LABRAOUI", arabicName: "عبدالله حميد لبراوي" }, { id: "2411016", name: "AHMAD ASAAD ALHAJ ALKHLF", arabicName: "احمد اسعد الحاج خلف" }, { id: "2311005", name: "AL YAZAN SALAH JUMA KHAMIS AL SAADI", arabicName: "اليزن بن صلاح بن جمعه بن خميس السعدي" }, { id: "2311057", name: "ALI A.RAHMAN A M AL-MALIK", arabicName: "على عبدالرحمن على محمد الملك" }, { id: "2411062", name: "AMIR MOHAMMED KHALAF OMUASH", arabicName: "امير محمد خلف العموش" }, { id: "2311011", name: "ARSLANE SAADELLAH", arabicName: "أرسلان سعد الله" }, { id: "2309012", name: "BAKRI MOHAMED BAKRI MOHAMED", arabicName: "بكرى محمد بكرى محمد" }, { id: "2411021", name: "ELSAYED AHMED ELSAYED AHMED", arabicName: "السيد احمد السيد احمد" }, { id: "2412024", name: "FARES IBRAHIM MOHAMED SOBHI IBRAHIM ELNOURY", arabicName: "فارس ابراهيم محمد صبحى ابراهيم النورى" }, { id: "2311021", name: "HAMZA ALSAYED AHMED ABDELAZIM EID", arabicName: "حمزه السيد احمد عبد العظيم عيد" }, { id: "2311022", name: "HATIM ELKHATTABI", arabicName: "حاتم الخطابي" }, { id: "2412031", name: "KAIS ELZHAR", arabicName: "كايس الزهر" }, { id: "2311039", name: "OMAR HAMAD O H ALAMRI", arabicName: "عمر حمد عمر حمد العامرى" }, { id: "2311045", name: "SAIFELDAIN AYMAN MOSTAFA IBRAHIM ALI ELTOKHY", arabicName: "سيف الدين ايمن مصطفى ابراهيم على الطوخى" }, { id: "2411057", name: "ZAID RIZWAN KAZI", arabicName: "زايد رضوان قاضى" } ], "8B": [ { id: "2411064", name: "ADAM JMAIEL", arabicName: "آدم بن محمد نبيل الجميل" }, { id: "2311004", name: "AHMAD MOHD S M AL-MALKI", arabicName: "احمد محمد سعيد محمد المالكى" }, { id: "2311016", name: "FAHAD RAQIBI", arabicName: "فهد رقيبي" }, { id: "2311054", name: "HAMAD MOHAMMED M B AL-MOADADI", arabicName: "حمد محمد مبارك بن اعبود المعضادى" }, { id: "2312027", name: "KHALID NASSER A M AL-SABEA", arabicName: "خالد ناصر عبدالله مبارك السبع" }, { id: "2311028", name: "LAITH BASHAR MOHAMMAD AL-GHOUL", arabicName: "ليث بشار محمد الغول" }, { id: "2412037", name: "MALEK TAMER YEHIA YOUSSEF SALEM", arabicName: "مالك تامر يحيى يوسف سالم" }, { id: "2411001", name: "MOHAMMAD YOUSSEF ZARAKET", arabicName: "محمد يوسف زراقط" }, { id: "2412043", name: "MOHAMMED WALEED I M AL-ASHAR", arabicName: "محمد وليد اسماعيل مندنى العشار" }, { id: "2311036", name: "NAWAF KHALAF SAIF BANI-ORAB", arabicName: "نواف بن خلف بن سيف بني عرابه" }, { id: "2311037", name: "NIDAL SAS", arabicName: "نضال ساس" }, { id: "2311048", name: "SULTAN NASSER S M AL-SULTAN", arabicName: "سلطان ناصر سالم مرزوق السلطان" }, { id: "2311052", name: "YOUSEF ABDULRAHMAN M J ALMALKI", arabicName: "يوسف عبدالرحمن محمد جمعه المالكى" }, { id: "2311058", name: "YOUSEF NAZARI TAKHTI NEJAD", arabicName: "يوسف نظرى تختى نزاد" } ], "8C": [ { id: "2311017", name: "FAHAD SAAD H S AL-QAHTANI", arabicName: "فهد سعد هادى ال سيف القحطانى" }, { id: "2311019", name: "FATEHI FIRAS FATHI ABU SALEM", arabicName: "فتحي فراس فتحي ابو سليم" }, { id: "2311056", name: "HAMAD ALI H S AL-KHALAF", arabicName: "حمد على حسن سالم الخلف" }, { id: "2311024", name: "JASSIM ALI J A AL-MANSOURI", arabicName: "جاسم على جاسم النصف المنصورى" }, { id: "2411063", name: "MOHAMAD FAYSAL ABDALLAH", arabicName: "محمد فيصل عبد الله" }, { id: "2411039", name: "MOHAMMAD ABDULLAH", arabicName: "محمد عبداللة" }, { id: "2312033", name: "MOHAMMED JUMA GHARIB SAID AL-BUSAIDI", arabicName: "محمد بن جمعه بن غريب بن سعيد البوسعيدي" }, { id: "2311034", name: "MOHAMMED KHALID F S SAEED", arabicName: "محمد خالد فواد سعيد سعيد" }, { id: "2311035", name: "NASSER MESHAL H A AL-KARBI", arabicName: "ناصر مشعل حمد ال مسفر الكربى" }, { id: "2311038", name: "OMAR A. M. ALMUGHANNI", arabicName: "عمر أحمد محمد المغني" }, { id: "2312040", name: "OMAR MOHAMMED ALI AZAB", arabicName: "عمر محمد على عزب" }, { id: "2412052", name: "SAAD ELLEMTY", arabicName: "سعد اللمطي" }, { id: "2311049", name: "TAHA YESSINE BHARA", arabicName: "طه ياسين بن ماهر بهاره" } ], "9A": [ { id: "2210076", name: "ABDALLA AHMED ELSAWI ELSAYED MOUSTAFA", arabicName: "عبد الله احمد الصاوى السيد مصطفى" }, { id: "2210075", name: "ABDULRHMAN TARIQ MOHAMMED MUSLEH", arabicName: "عبد الرحمن طارق محمد مصلح" }, { id: "2411060", name: "ABDEL RAHMAN OSAMA ADEL MATALAQEH", arabicName: "عبدالرحمن اسامه عادل مطالقه" }, { id: "2211074", name: "ABDULLAH NAJEB DAKAK", arabicName: "عبد الله نجيب دقاق" }, { id: "2411020", name: "DENIJAL KOPIC", arabicName: "دينيجال كوبيك" }, { id: "2311013", name: "ESSA IBRAHIM E TH AL-HADDAD", arabicName: "عيسى ابراهيم عيسى ثانى الحداد" }, { id: "2210092", name: "HAMED FADI HAMED QAISIEH", arabicName: "حامد فادي حامد القيسيه" }, { id: "2210093", name: "KHALID AHMED K ALANAZI", arabicName: "خالد بن احمد بن خالد العنزي" }, { id: "2310029", name: "MALEK YOUNES", arabicName: "مالك يونس" }, { id: "2310030", name: "MEHDI KAHIA", arabicName: "مهدي بن مروان كاهية" }, { id: "2210086", name: "MOHAMED OMER ABDEEN ALI", arabicName: "محمد عمر عابدين علي" }, { id: "2311041", name: "OMODOT GRANT EMEM", arabicName: "اومودوت ايمم" }, { id: "2210099", name: "TALAL MAJID N S AL-BADR", arabicName: "طلال ماجد ناصر سلطان البدر" }, { id: "2311051", name: "YOUNES MIRAD", arabicName: "يونس ميراد" }, { id: "2211097", name: "YOUSUF MAHMOD S D IBRAHIM", arabicName: "يوسف محمود صلاح دسوقى ابراهيم" } ], "9B": [ { id: "2409022", name: "ABDULLA ABDULRAHMAN D A AL-QADI", arabicName: "عبدالله عبدالرحمن درويش عبدالرحمن القاضى" }, { id: "2211073", name: "ADAM ABDALLA HAMED HEMIDA MORSY", arabicName: "ادم عبد الله حامد حميده مرسى" }, { id: "2210071", name: "AHMED ADEL MASOUD RAGAB ABOUELKOMSAN", arabicName: "احمد عادل مسعود رجب ابو القمصان" }, { id: "2411014", name: "AHMED HADDAD", arabicName: "أحمد بن فتحي الحداد" }, { id: "2410017", name: "AHMED MOHAMED KAMAL ALI ALI", arabicName: "أحمد محمد كمال على على" }, { id: "2310007", name: "ALI EBRAHIM A M AL-MALIK", arabicName: "على ابراهيم على محمد الملك" }, { id: "2210062", name: "ALI MOHAMED MAHMOUD ABDELSAMIE ELABSY", arabicName: "على محمد محمود عبد السميع العبسى" }, { id: "2210094", name: "KHALIFA EISSA HASSAN SAADOUN", arabicName: "خليفه عيسى حسن سعدون" }, { id: "2210105", name: "MAHMOUD TURJMAN", arabicName: "محمود سامر ترجمان" }, { id: "2209113", name: "MOHAMED AMEEN BEN GHARBIA", arabicName: "محمد أمين بن صالح بن غربية" }, { id: "2210078", name: "OMAR AHMED SAAD BASHA", arabicName: "عمر احمد سعد باشه" }, { id: "2410048", name: "OMAR AYMAN KAMAL SAYED MAHMOUD", arabicName: "عمر ايمن كمال سيد محمود" }, { id: "2211103", name: "OMAR MOHAMMED ALI MITWALLY FARAG", arabicName: "عمر محمد على متولى فرج" } ], "9C": [ { id: "2211108", name: "ABDULRAHMAN SALAH A H ZAENALABDEEN", arabicName: "عبدالرحمن صلاح عبدالرحمن حجى زين العابدين" }, { id: "2210072", name: "ADHAM ADNAN AHMED ADNAN", arabicName: "ادهم عدنان احمد عدنان" }, { id: "2210063", name: "ALI MOHAMMED JANGALI AKHARDAD NOWKARI", arabicName: "على محمد نوكرى" }, { id: "2311014", name: "ESSA MOHAMMED S A AL-KUWARI", arabicName: "عيسى محمد سعدون الجهام الكوارى" }, { id: "2210067", name: "EYAD MOHAMED MAHMOUD SAYED AHMED SHELEBY", arabicName: "اياد محمد محمود سيد احمد شليبي" }, { id: "2210069", name: "FAISAL ABDULRAHMAN F A ALKATHEERI", arabicName: "فيصل عبدالرحمن فيصل عامر الكثيرى" }, { id: "2210090", name: "MAHMOUD AHMAD ALISMAIL RIMI", arabicName: "محمود احمد الاسماعيل ريمي" }, { id: "2211089", name: "MALIK JAMIL AHMAD HAMDAN", arabicName: "مالك جميل احمد حمدان" }, { id: "2210088", name: "MANSOOR SAIF KHALAF BANI ARABA", arabicName: "منصور بن سيف بن خلف بني عرابة" }, { id: "2211104", name: "MOUEZ AHMED MOUSTAFA ELZAFARANI", arabicName: "معز احمد مصطفى الزعفرانى" }, { id: "2210107", name: "SAEED MOHD S M AL-MALKI", arabicName: "سعيد محمد سعيد محمد المالكى" }, { id: "2210122", name: "SAOUD ABDULLA M A AL-NAIMI", arabicName: "سعود عبدالله محمد عبدالله النعيمى" }, { id: "2311047", name: "SULTAN HAMAD S M AL-ABDULLA", arabicName: "سلطان حمد سلطان مبارك العبدالله" }, { id: "2210123", name: "TURKI SAAD J S AL-ABDULLA", arabicName: "تركى سعد جوهر سعد العبدالله" }, { id: "2410066", name: "ABDULLA MOHAMMED A A AL-MARRI", arabicName: "عبدالله محمد عبدالله المريزيق المرى" } ], "10 Scientific (A)": [ { id: "2109001", name: "ABDALLA MOHAMED HASSAN MOHAMED", arabicName: "عبدالله محمد حسن محمد" }, { id: "2410009", name: "ABDELRAHMAN OSAMA ABDELRAHMAN MOHAMED", arabicName: "عبد الرحمن اسامه عبد الرحمن محمد" }, { id: "2110003", name: "ABDULLA SAAD S A ALBADR", arabicName: "عبدالله سعد سبت ابوجسوم البدر" }, { id: "2110004", name: "ABDULRAHMAN ALI POORGHARIB", arabicName: "عبدالرحمان على بورغريب" }, { id: "2208115", name: "ABDULRAHMAN NASSAR ALI MOHAMMED", arabicName: "عبدالرحمن نصار علي محمد" }, { id: "2310003", name: "ADHAM WAFYELDIN SAYED ABDELRASOUL EMAM", arabicName: "ادهم وفي الدين سيد عبد الرسول امام" }, { id: "2210064", name: "ALI YOUSSEF YOUSSEF", arabicName: "على يوسف يوسف" }, { id: "2409019", name: "BARJAS MANSOUR MAHMOUD ALRAHAMNEH", arabicName: "برجس منصور محمود الرحامنه" }, { id: "2210066", name: "DHIAEDDINE LARBI BENYATLA", arabicName: "ضياء الدين العربي بن يطلع" }, { id: "2109032", name: "FAZAL REHMAN NAEEM", arabicName: "فضل رحمان نعيم" }, { id: "2409029", name: "IBRAHIM M. G. ELZAHARNA", arabicName: "ابراهيم محمد يوسف جودت الزهارنه" }, { id: "2209058", name: "JAMAAL BADRU", arabicName: "جمال الدين" }, { id: "2409065", name: "JUDE ABDALLAH", arabicName: "جود عبدالله" }, { id: "2410042", name: "MOHAMMAD OSAMA YACOUB NASIR", arabicName: "محمد اسامه يعقوب نصر" }, { id: "2407044", name: "MOUSTAFA RAFAAT ABDELMONSEF ALY HABIB", arabicName: "مصطفى رأفت عبد المنصف على حبيب" }, { id: "2209111", name: "OMER ADIL HAKIM KHALID", arabicName: "عمر عادل حاكم خالد" }, { id: "2209112", name: "OMAR KHALED ANWAR MOHAMED DEIF", arabicName: "عمر خالد انور محمد ضيف" }, { id: "2210102", name: "OMAR TALHA IBRAHIM ATIA IBRAHIM", arabicName: "عمر طلحا ابراهيم عطيه ابراهيم" }, { id: "2309046", name: "SHAHER WAEL ROUSTOM", arabicName: "شاهر وائل رستم" }, { id: "2408053", name: "SEIFELDIN AHMED SABER HASSANEIN", arabicName: "سيف الدين احمد صابر حسانين" }, { id: "2109035", name: "YOUSIF AHMED MAHMOUD ABDELZAHER ABDALLA", arabicName: "يوسف احمد محمود عبد الظاهر عبد الله" } ], "10 Arts (B)": [ { id: "2109006", name: "ABDOLAZIZ AHMAD PALANGI", arabicName: "عبدالعزيز احمد بلنكى" }, { id: "2109031", name: "AHMED A. B. ELKAHLOUT", arabicName: "احمد عبدالله بدر الكحلوت" }, { id: "2210061", name: "ALI ISMAIL ABBAS", arabicName: "على اسماعيل عباس" }, { id: "2209091", name: "KHALID AHMAD ABDEL LATIF ALMAJDOBA", arabicName: "خالد احمد عبد اللطيف المجدوبه" }, { id: "2109014", name: "MOHAMED MIRGHNI ALI FADIL", arabicName: "محمد ميرغني علي فضيل" }, { id: "2309031", name: "MOHAMED HASSANEIN YEHEA FADL", arabicName: "محمد حسنين يحيى فضل" }, { id: "2210082", name: "MOHAMMED FAWAZ A H AL-HAMAD", arabicName: "محمد فواز امان حارب الحمد" }, { id: "2109033", name: "OSAMA IBRAHIM OBIDO MOHAMED", arabicName: "اسامه ابراهيم عبيدو محمد" }, { id: "2109022", name: "SALEM MOHAMMED S A ALHAGRI", arabicName: "سالم محمد سالم على الهاجرى" }, { id: "2210100", name: "SULTAN MAHANNA A A AL-NAEMI", arabicName: "سلطان مهنا على عبدالله النعيمى" } ], "10 Arts (C)": [ { id: "2108009", name: "ABDULLA SAAD J S AL-ABDULLA", arabicName: "عبدالله سعد جوهر سعد العبدالله" }, { id: "2110049", name: "ADHAM EHAB AHMED SALEM ALDEEB", arabicName: "أدهم ايهاب احمد سالم الديب" }, { id: "2109021", name: "ALBARAA FAHAD M KH AL-MALKI", arabicName: "البراء فهد محمد خميس المالكى" }, { id: "2108007", name: "ARAFAT FAHD OBADI ABOBAKR QASEM", arabicName: "عرفات فهد عبادي ابوبكر قاسم" }, { id: "2409026", name: "HALIM KECIBA", arabicName: "حليم قصيبة" }, { id: "2307059", name: "HAMZA SAIFI", arabicName: "حمزة صيفي" }, { id: "2109008", name: "HASSAN IBRAHIM HASSAN OSMAN", arabicName: "حسن ابراهيم حسن عثمان" }, { id: "2308064", name: "MAHAMAT ABAKAR HISSEIN", arabicName: "مهمات ابكر حسين" }, { id: "2410040", name: "MOHAMMED ALI A H AL-HIJJI", arabicName: "محمد على اسد حجى الحجى" }, { id: "2109027", name: "MOHAMMED BILAL SHANNAN ALHARASI", arabicName: "محمد بن بلال بن شنان الحراصي" }, { id: "2109037", name: "NASSER AHMED A A AL-ATBI", arabicName: "ناصر احمد على احمد العتبى" }, { id: "2008070", name: "RAWAD AKRAM MAHMOUD ALNASER", arabicName: "رواد اكرم محمود الناصر" }, { id: "2109050", name: "SAAD MOHD M S AL-SULIATI", arabicName: "سعد محمد مسعود الصالح السليطى" }, { id: "2109020", name: "SALEH BADR S KH AL-SAHOTI", arabicName: "صالح بدر سعيد خليفه السحوتى" }, { id: "2108019", name: "SALEM HAMAD J A JAMAL", arabicName: "سالم حمد جمال احمد جمال" }, { id: "2209098", name: "YOUSSEF YASSER SOLIMAN ABDELTAWAB", arabicName: "يوسف ياسر سليمان عبد التواب" } ], "11 Scientific (A)": [ { id: "2008043", name: "ABDELAZIZ YOUNISS KHALIL MOHAMED ABDALLA ELHAMAIDA", arabicName: "عبد العزيز يونس خليل محمد عبد الله الحمايده" }, { id: "2008009", name: "ABDELRAHMAN MOHAMED HASSAN MOHAMED KAMEL", arabicName: "عبد الرحمن محمد حسن محمد كامل" }, { id: "2208114", name: "ABDELRAHMAN KHALED ANWAR MOHAMED DEIF", arabicName: "عبد الرحمن خالد انور محمد ضيف" }, { id: "2008001", name: "ABDELRAHMAN KHALED ZAHAB MOHAMED ZAHAB", arabicName: "عبد الرحمن خالد ذهب محمد ذهب" }, { id: "2208124", name: "ADAM FRIAKH", arabicName: "ادم فريخ" }, { id: "2008053", name: "AHMED EID YASSEIN MOHAMED KORANI", arabicName: "احمد عيد يسين محمد قرنى" }, { id: "2008044", name: "AHMED SABER FARRAG SABER ALY ABOUEITAH", arabicName: "احمد صابر فراج صابر على ابوعيطه" }, { id: "2409018", name: "ALI MOHAMED MEDHAT ESMAIEL ELNOURY", arabicName: "على محمد مدحت اسماعيل النورى" }, { id: "2009021", name: "ALY HANY ALY MOHAMED OUDA", arabicName: "على هانى على محمد عوده" }, { id: "2008046", name: "FAISSAL IRAHBINE", arabicName: "فيصل ارحبين" }, { id: "2008023", name: "HAMZA MAHMOUD IBRAHIM AHMED SHALAN", arabicName: "حمزه محمود ابراهيم احمد شعلان" }, { id: "2109010", name: "IBRAHIM JAMIL AHMAD HAMDAN", arabicName: "ابراهيم جميل احمد حمدان" }, { id: "2408068", name: "KARAM HADI (MUSBAHEDDIN) MALAK", arabicName: "كرم هادى (مصباح الدين) ملك" }, { id: "2008005", name: "KHALED CHOUKRI M MECHERNENE", arabicName: "خالد شكرى محمد مشرنن" }, { id: "2207120", name: "KHATAB NABAIL ABDALLA ADAM", arabicName: "خطاب نبيل عبدالله ادم" }, { id: "2107028", name: "KRISTIJAN DANIJEL SARIC", arabicName: "كرستيان دانييل ساريك" }, { id: "2008064", name: "MOHAMED AZIZ ISMAIL", arabicName: "محمد عزيز بن الجيلاني اسماعيل" }, { id: "2008042", name: "MOHAMMED JASSIM RASHID R S AL-MARRI", arabicName: "محمد جاسم راشد سالم المرى" }, { id: "2008074", name: "YAZAN HANI ISMAIL ABDELAZIM MOHAMED", arabicName: "يزن هانى اسماعيل عبد العظيم محمد" }, { id: "2109026", name: "ZIAD ABADALLA HAMED HEMIDA MORSY", arabicName: "زياد عبد الله حامد حميده مرسى" } ], "11 Arts (B)": [ { id: "2306066", name: "ALWALEED MOHAMMED IBRAHIM ALHAUSAWI", arabicName: "الوليد محمد ابراهيم الهوساوي" }, { id: "2008002", name: "ASKAR TALAB A M AL-KORBI", arabicName: "عسكر طالب عسكر محمد الكربى" }, { id: "2308068", name: "EMMANUEL ADELEBARI FRANCIS", arabicName: "امانويل اديليبارى فرانسيس" }, { id: "2109053", name: "FAHAD ABDULKAREEM J S SAEED", arabicName: "فهد عبدالكريم جوهر سعيد سعيد" }, { id: "2309062", name: "FAISAL BAKHIT S B AL-HAMAD", arabicName: "فيصل بخيت سلمان بخيت الحمد" }, { id: "2307026", name: "JOHAR SAAD J S AL-ABDULLA", arabicName: "جوهر سعد جوهر سعد العبدالله" }, { id: "2008047", name: "MOHAMED AKRAM MOHAMED NASR", arabicName: "محمد اكرم محمد نصر" }, { id: "2209080", name: "MOHSAIN ABDULLA M SH AL-HAJRI", arabicName: "محسن عبدالله محسن الشهوانى الهاجرى" }, { id: "2209121", name: "OMAR NASER ESSAM AL-SAFFAR", arabicName: "عمر نصر عصام الصفار" }, { id: "2207133", name: "RASHID SAAD J S AL-ABDULLA", arabicName: "راشد سعد جوهر سعد العبدالله" }, { id: "2008007", name: "SAAD SAQR S S ALABDULLA", arabicName: "سعد صقر سعد صقر العبدالله" }, { id: "2108038", name: "SALMAN ANWAR SALEH AL-NADHERA", arabicName: "سلمان انور صالح النظير" }, { id: "2008027", name: "TAMEEM NASSER S A AL-QADI", arabicName: "تميم ناصر سعيد على القاضى" }, { id: "2308053", name: "YOUSSEF MOHAMED FARAG ALY KHEDR", arabicName: "يوسف محمد فرج على خضر" } ], "11 Arts (C)": [ { id: "2207134", name: "ABDELRAHMAN MOHAMED ADEL MOHAMED IBRAHIM", arabicName: "عبد الرحمن محمد عادل محمد ابراهيم" }, { id: "2306061", name: "ABDRAMAN MAHAMAT MALKI KOGNE", arabicName: "ابدرمان مهمات مالكي كوجني" }, { id: "2008020", name: "ABDULRAHMAN HASAN HASAN NAJI AL-JADRAH", arabicName: "عبدالرحمن حسن حسن ناجي الجدره" }, { id: "2308002", name: "ABDULRAHMAN KHALID A A ALYAFEI", arabicName: "عبدالرحمن خالد عبدالقوى البكرى اليافعى" }, { id: "2208060", name: "ALI HASSAN ALKHLIF", arabicName: "علي حسان الخليف" }, { id: "2007012", name: "HAMAD EBRAHIM MOHAMED KHALIFA HAMAD", arabicName: "حمد ابراهيم محمد خليفه حمد" }, { id: "2008014", name: "IBRAHIM ALI S S AL-MAJID", arabicName: "ابراهيم على صقر سالمين الماجد" }, { id: "2009022", name: "MARWAN HANY MOHAMED AHMED MOHAMED HUSSEIN", arabicName: "مروان هانى محمد احمد محمد حسين" }, { id: "2309055", name: "MOHAMMED ALI H S AL-KHALAF", arabicName: "محمد على حسن سالم الخلف" }, { id: "2007061", name: "MOHAMMED GHANIM M A AL-KUWARI", arabicName: "محمد غانم محمد ال بن صقران الكوارى" }, { id: "2207136", name: "OSAMA MOHAMED SALIM MOHAMED", arabicName: "اسامه محمد سالم محمد" }, { id: "2008016", name: "YOUNES EID SH AL-BALUSHI", arabicName: "يونس عيد شعبان البلوشي" }, { id: "2306060", name: "ZINEDDINE FERRAH", arabicName: "زين الدين فراح" } ], "12 Scientific (A)": [ { id: "1907015", name: "ABDALLA AHMED SAMY ALGHAMRY", arabicName: "عبد الله احمد سامى الغمرى" }, { id: "2206110", name: "ACHRAF HIDARE", arabicName: "أشرف حيدار" }, { id: "2007030", name: "AHMAD NASIR", arabicName: "احمد ناصر" }, { id: "2207130", name: "AHMED MOHAMED SAID ALY DIAB", arabicName: "احمد محمد سعيد على دياب" }, { id: "2206070", name: "AKREM HAKIRI", arabicName: "أكرم بن مراد الحكيري" }, { id: "2207127", name: "ALI ABDULAZIZ A H A-MURAIKHI", arabicName: "على عبدالعزيز على هزيم المريخى" }, { id: "2307015", name: "ETHAN SOCORRO DEPINA ANDRADE", arabicName: "ايثان اندرادي" }, { id: "2007071", name: "FAHAD AHMAD K I KALA", arabicName: "فهد احمد خليل ابراهيم كلا" }, { id: "1907029", name: "KHALID MOHAMMED A S AL-HAMMADI", arabicName: "خالد محمد على صالح الحمادى" }, { id: "1907008", name: "KHALIL IBRAHIM A H AL-MUFTAH", arabicName: "خليل ابراهيم عبدالرحمن حمد المفتاح" }, { id: "1907022", name: "OSSAMA MAHMOUD MOAWAD RIAD", arabicName: "اسامه محمود معوض رياض" }, { id: "2309044", name: "SAADON MOHAMMED S A AL-KUWARI", arabicName: "سعدون محمد سعدون الجهام الكوارى" }, { id: "2007045", name: "SALEM SAED S K AL-MUHANNADI", arabicName: "سالم سعيد سالم خميس المهندى" }, { id: "2208096", name: "WARD OSSAMA ALZOUGHBI", arabicName: "ورد اسامه الزغبى" }, { id: "1908003", name: "YOUSEF EHAB AHMED SALEM ELDEEB", arabicName: "يوسف ايهاب احمد سالم الديب" }, { id: "2308067", name: "YOUSEF MOHAMMAD AHMAD SALMAN", arabicName: "يوسف محمد احمد سلمان" }, { id: "2008028", name: "ZAID FAISAL KTIT", arabicName: "زيد فيصل قطيط" }, { id: "1907034", name: "ZIAD TAREK RAGAB ALY MOHAMED", arabicName: "زياد طارق رجب على محمد" } ], "12 Arts (B)": [ { id: "1907017", name: "ABDULAZIZ MOHAMMED OMAR HUSSEIN", arabicName: "عبدالعزيز محمد عمر حسين" }, { id: "2008029", name: "ALI AHMAD A A ALSHAMARI", arabicName: "على احمد على عايد الشمرى" }, { id: "1908080", name: "ALSHAIKJOEGHARI MOHAMED NDAW", arabicName: "الشيخ جوغارى محمد نداو" }, { id: "1907024", name: "FAHAD MOHAMMED S A ALHAGRI", arabicName: "فهد محمد سالم على الهاجرى" }, { id: "1907054", name: "HAMZA HUSSAIN H A HASHEM", arabicName: "حمزه حسين حمزه اسد هاشم" }, { id: "1907060", name: "IBRAHIM AHMED I A AL-HILAL", arabicName: "ابراهيم احمد ابراهيم احمد الهلال" }, { id: "2107012", name: "KHALID ATIYAQ JUMA AL SHAAIBI", arabicName: "خالد بن عتيق بن جمعه الشعيبي" }, { id: "2008073", name: "MALIK MAGID M E HASSAN", arabicName: "مالك ماجد محمد امام حسن" }, { id: "1907010", name: "MOHAMED MUATASIM AHMED ELSIDDIG", arabicName: "محمد معتصم احمد الصديق" }, { id: "1907059", name: "MOHAMMED KHALID A A SHAMS", arabicName: "محمد خالد على احمد شمس" }, { id: "2208131", name: "MOHANNAD JAMIL SHARIF BABLI", arabicName: "مهند جميل شريف بابلي" }, { id: "1907016", name: "NASSER SULAIMAN G A AL-SHARSHANI", arabicName: "ناصر سليمان غلوم عباس الشرشنى" }, { id: "2008049", name: "OMAR ABDULAZIZ I A AL-MARZOUQI", arabicName: "عمر عبدالعزيز ابراهيم احمد المرزوقى" }, { id: "2206077", name: "OMAR GAMAL AHMED GAD", arabicName: "عمر جمال احمد جاد" }, { id: "1907044", name: "QAYS HUSHAM ALI AL-RAWI", arabicName: "قيس هشام علي الراوي" }, { id: "2008056", name: "SULTAN MAJID F M AL-ABDULRAHMAN", arabicName: "سلطان ماجد فرج مرزوق العبدالرحمن" }, { id: "2007031", name: "TAMEEM SALEH A M ABASHAAR", arabicName: "تميم صالح عبدالرحمن مسعد اباشعر" } ], "12 Arts (C)": [ { id: "2007032", name: "ABDALLA SALIH IDRIS ADAM", arabicName: "عبدالله صالح ادريس ادم" }, { id: "1906033", name: "ABDULAZIZ SAOUD A H SAAD", arabicName: "عبدالعزيز سعود على حسن سعد" }, { id: "1908007", name: "AHMED IDRIS AHMED IBRAHIM", arabicName: "احمد ادريس احمد ابراهيم" }, { id: "2208059", name: "HAMAD DHAWI F D ALSULTAN", arabicName: "حمد ضاوى فرج ضاوى السلطان" }, { id: "2207132", name: "HAMAD YOUSEF A YOUSEF", arabicName: "حمد يوسف عبدالله يوسف" }, { id: "1907048", name: "KHALID SALEH J M AL-SHIRAM", arabicName: "خالد صالح جمعه مبارك الشريم" }, { id: "2106056", name: "MAHAMAT ABAKAR ABDRAHMAN", arabicName: "محمد ابكر عبدالرحمن" }, { id: "2305063", name: "MOHAMED ALY ABDELMONEM MONSEF NOUFAL", arabicName: "محمد على عبدالمنعم منصف نوفل" }, { id: "2306032", name: "MOHAMMED JASSIM S A AL-FAKHROO", arabicName: "محمد جاسم سلطان على الفخرو" }, { id: "2207128", name: "MOHAMMED KHALED H ALSAIAARI", arabicName: "محمد خالد حسين الصيعرى" }, { id: "1906011", name: "MUBARAK ABDULLA S A AL-NOUBI", arabicName: "مبارك عبدالله سلطان عبدالله النوبى" }, { id: "1907051", name: "RAKAN MUBARAK K M AL-RASHIDI", arabicName: "راكان مبارك خصيف مبارك الرشيدى" }, { id: "2105052", name: "SEIFELDIN MOHAMED AWAD ABDELSALAM", arabicName: "سيف الدين محمد عوض عبدالسلام" }, { id: "1907001", name: "TAHA YEHYA ABDELKADER ABOUELSEOUD HASSAN", arabicName: "طه يحيى عبد القادر ابو السعود حسن" }, { id: "2306065", name: "YOUSSEF EL MALYANI", arabicName: "يوسف الملياني" } ] }; // Comment banks const positiveCommentsBank = [ "Completes work independently and shows consistent improvement.", "Demonstrates strong reading comprehension.", "Has good writing skills and creativity.", "Polite and well-mannered in class.", "Actively participates and engages in discussions.", "Shows dedication and effort in learning.", "Demonstrates confidence and is gaining independence.", "Talented and quick to grasp new language skills.", "Takes studies more seriously and shows maturity.", "Friendly and supportive to peers.", "Consistently improving both in reading and writing.", "Completes assignments with little or no guidance.", "Willingness to learn is evident.", "Shows steady progress over time.", "Attempts tasks without hesitation." ]; const developmentCommentsBank = [ "Improve writing mechanics (punctuation, spelling, grammar).", "Practice time management and task completion.", "Develop more consistent motivation across lessons.", "Strengthen ability to remain engaged throughout full class periods.", "Express ideas more clearly in writing.", "Improve tone when speaking to teachers or peers.", "Develop confidence to speak more often in class.", "Enhance note-taking and question-asking habits.", "Strengthen focus despite distractions around.", "Continue practicing on platforms like Write&Improve.", "Improve prioritization of tasks during class.", "Build stronger self-monitoring and self-discipline.", "Learn to transition between tasks more efficiently.", "Expand vocabulary to support academic writing.", "Apply learned concepts more consistently in assessments." ]; const behaviorCommentsBank = [ "Easily distracted and distracts others.", "Falls asleep during class.", "Watches shows or misuses tablet during lessons.", "Frequently side-tracks into unrelated conversations.", "Struggles to complete work due to lack of focus.", "Unmotivated attitude toward learning.", "Rarely participates in class activities.", "Lacks engagement, especially in critical moments.", "Constantly pulls peers into conversations.", "Can appear rude in tone, unintentionally.", "Only works when they feel like it.", "Distracts others by trying to entertain.", "Avoids tasks without teacher prompting.", "Slow to follow through on assigned tasks.", "Repeatedly asks for things without respecting boundaries." ]; const improvementCommentsBank = [ "Focus more during lessons to reduce distractions.", "Review lessons at home via platforms like Blackboard.", "Practice writing regularly to improve spelling and grammar.", "Stay engaged for the full lesson duration.", "Participate more actively in class discussions.", "Complete tasks within the given time.", "Be more consistent in submitting work.", "Minimize off-task behavior (e.g., chatting, daydreaming).", "Take learning seriously—this is a crucial year.", "Improve classroom behavior to support peers' focus.", "Take responsibility for personal academic progress.", "Be respectful in speech and actions toward others.", "Sleep well and stay energized for lessons.", "Practice using tone and expression appropriately.", "Set goals for each lesson to stay motivated." ]; // Handle Aspire database login const handleAspireLogin = (e) => { e.preventDefault(); if (username === 'Teacher2024' && password === 'Aspire123') { // Move to class selection step setStep(1.5); // New step for class selection setShowLoginModal(false); setLoginError(''); setClasses(aspireClasses); } else { setLoginError('Invalid username or password. Please try again.'); } }; // Handle class selection from Aspire database const handleAspireClassSelect = (className) => { setSelectedClass(className); // Load students for the selected class if (aspireStudentData[className]) { const formattedStudents = aspireStudentData[className].map(student => ({ id: student.id, name: student.name, arabicName: student.arabicName, class: className, grade: student.grade || className })); setStudents(formattedStudents); setStep(2); } }; // Handle file upload const handleFileUpload = (e) => { const file = e.target.files[0]; setIsUploading(true); if (file) { const reader = new FileReader(); reader.onload = (evt) => { try { const data = evt.target.result; const workbook = XLSX.read(data, { type: 'binary' }); const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; const jsonData = XLSX.utils.sheet_to_json(worksheet); // Process student data const processedStudents = jsonData.map(row => ({ name: row.Name || row.name || '', class: row.Class || row.class || '' })).filter(student => student.name && student.class); // Extract unique classes const uniqueClasses = [...new Set(processedStudents.map(student => student.class))]; setStudents(processedStudents); setClasses(uniqueClasses); setSelectedClass(uniqueClasses[0] || ''); setStep(2); setIsUploading(false); } catch (error) { console.error("Error processing file:", error); alert("Error processing file. Please ensure it's a valid Excel file."); setIsUploading(false); } }; reader.onerror = () => { alert("Error reading file"); setIsUploading(false); }; reader.readAsBinaryString(file); } }; // Select a student const handleStudentSelect = (student) => { setSelectedStudent(student); setPositiveComments([]); setDevelopmentComments([]); setBehaviorComments([]); setImprovementComments([]); setCustomNotes(''); setGeneratedComment(''); setError(''); setStep(3); }; // Toggle comment selection const toggleComment = (comment, type) => { switch (type) { case 'positive': setPositiveComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; case 'development': setDevelopmentComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; case 'behavior': setBehaviorComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; case 'improvement': setImprovementComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; default: break; } }; // Generate a fallback comment if API fails const generateFallbackComment = () => { const positive = positiveComments.length > 0 ? positiveComments[Math.floor(Math.random() * positiveComments.length)] : "shows good progress"; const development = developmentComments.length > 0 ? developmentComments[Math.floor(Math.random() * developmentComments.length)] : "needs to develop skills"; const behavior = behaviorComments.length > 0 ? behaviorComments[Math.floor(Math.random() * behaviorComments.length)] : ""; const improvement = improvementComments.length > 0 ? improvementComments[Math.floor(Math.random() * improvementComments.length)] : "should focus on improving"; const fallbackComment = `${selectedStudent.name} ${positive} ${behavior ? 'However, ' + behavior : ''} ${development} ${improvement}`; return fallbackComment; }; // Generate comment using OpenAI API const generateComment = async () => { if (!positiveComments.length || (!developmentComments.length && !behaviorComments.length && !improvementComments.length)) { setError("Please select at least one positive comment and one comment from any other category"); return; } setIsGenerating(true); setError(''); setGenerationAttempts(prev => prev + 1); try { // Prepare the prompt for OpenAI const prompt = `Write a personalized comment for ${selectedStudent.name} using these elements: Positive aspects: ${positiveComments.join(', ')} ${developmentComments.length > 0 ? `Areas for development: ${developmentComments.join(', ')}` : ''} ${behaviorComments.length > 0 ? `Behavior characteristics: ${behaviorComments.join(', ')}` : ''} ${improvementComments.length > 0 ? `Improvement suggestions: ${improvementComments.join(', ')}` : ''} ${customNotes ? `Additional notes: ${customNotes}` : ''} Follow these rules strictly: 1. Use a sandwich approach (positive-improvement-positive/encouragement) 2. Keep it EXACTLY between 350-450 characters including spaces (this is critical) 3. Make it sound natural and personalized, like a real teacher would write 4. Use the student's name 5. Don't simply list the comments, integrate them naturally 6. Vary sentence structure 7. Use simple, clear language at A2-B1 level (intermediate English) 8. Avoid complex vocabulary and sentence structures 9. Do not exceed 450 characters under any circumstances`; // Call OpenAI API const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [ { role: "system", content: "You are an experienced English teacher writing student comments. Write in a warm, supportive tone using simple language (A2-B1 level). Your comments must be EXACTLY between 350-450 characters including spaces." }, { role: "user", content: prompt } ], temperature: 0.7, max_tokens: 300 }), }); const data = await response.json(); if (data.error) { throw new Error(data.error.message || "Error calling OpenAI API"); } let generatedText = data.choices[0].message.content.trim(); const charCount = generatedText.length; // Check if the comment is within the character limit if (charCount < 350 || charCount > 450) { // Try again if outside the limit if (generationAttempts < 3) { setIsGenerating(false); return generateComment(); } } setGeneratedComment(generatedText); setCharacterCount(charCount); setStep(4); } catch (error) { console.error("Error generating comment:", error); // Use fallback if API fails if (generationAttempts > 2) { const fallbackComment = generateFallbackComment(); const charCount = fallbackComment.length; setGeneratedComment(fallbackComment); setCharacterCount(charCount); setStep(4); setError("API connection failed. Using simplified comment generation."); } else { setError(`Error: ${error.message}. Please try again.`); } } finally { setIsGenerating(false); } }; // Reset to start over const resetApp = () => { setSelectedStudent(null); setPositiveComments([]); setDevelopmentComments([]); setBehaviorComments([]); setImprovementComments([]); setCustomNotes(''); setGeneratedComment(''); setError(''); setGenerationAttempts(0); setStep(2); }; // Back to student selection const backToStudents = () => { setSelectedStudent(null); setPositiveComments([]); setDevelopmentComments([]); setBehaviorComments([]); setImprovementComments([]); setCustomNotes(''); setGeneratedComment(''); setError(''); setGenerationAttempts(0); setStep(2); }; // Back to comment selection const backToComments = () => { setGeneratedComment(''); setError(''); setGenerationAttempts(0); setStep(3); }; // Get step title const getStepTitle = () => { switch (step) { case 0: return "Welcome to Student Comment Generator"; case 1: return "Upload Student Data"; case 1.5: return "Select a Class"; case 2: return "Select a Student"; case 3: return selectedStudent ? `Select Comments for ${selectedStudent.name}` : "Select Comments"; case 4: return selectedStudent ? `Review Comment for ${selectedStudent.name}` : "Review Comment"; default: return ""; } }; // Copy comment to clipboard const copyComment = () => { navigator.clipboard.writeText(generatedComment); alert("Comment copied to clipboard!"); }; // Check if the character count is within the required range const isCharCountValid = () => { return characterCount >= 350 && characterCount <= 450; }; // Render login modal const renderLoginModal = () => { if (!showLoginModal) return null; return (

Aspire Database Login

{loginError && (

{loginError}

)}
setUsername(e.target.value)} required />
setPassword(e.target.value)} required />
); }; return (
{/* Header */}

Student Comment Generator

Streamline your feedback process with AI-powered comments

{/* Main Content */}
{/* Progress Steps - Only show for steps 1-4 */} {step > 0 && step !== 1.5 && (
{/* Progress Bar */}
{/* Step Circles */}
= 1 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 1
= 1 ? 'text-teal-600' : 'text-gray-400'}`}>Upload
= 2 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 2
= 2 ? 'text-teal-600' : 'text-gray-400'}`}>Select Student
= 3 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 3
= 3 ? 'text-teal-600' : 'text-gray-400'}`}>Choose Comments
= 4 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 4
= 4 ? 'text-teal-600' : 'text-gray-400'}`}>Review
)} {/* Content Card */}
{/* Card Header */}

{getStepTitle()}

{step > 0 && step !== 1.5 && ( )} {step === 1.5 && ( )}
{/* Card Content */}
{/* Error Message */} {error && (

{error}

)} {/* Step 0: Landing Page */} {step === 0 && (

Choose Your Data Source

Select how you want to access student data for generating comments. You can either connect to the Aspire database or upload your own student list.

{/* Aspire Database Option */}
setShowLoginModal(true)} >

Aspire Database

Connect to the Aspire school database to access your student records directly.

{/* Upload Own Data Option */}
setStep(1)} >

Upload Student List

Upload your own Excel file with student names and class information.

About This Tool

The Student Comment Generator helps teachers create personalized, well-structured comments for student reports. Select from pre-written comment banks and let AI combine them into natural-sounding feedback that follows the sandwich approach (positive-improvement-positive). All comments are between 350-450 characters.

)} {/* Step 1: File Upload */} {step === 1 && (

Upload an Excel file containing student names and class information. The file should have columns for "Name" and "Class".

Drag and drop your Excel file here, or

Sample Format:

Name Class
John Smith 9A
Emma Johnson 9A
Michael Brown 12B
)} {/* Step 1.5: Class Selection (Aspire) */} {step === 1.5 && (

Select a class to view its students. You can then select a student to generate comments.

{aspireClasses.map((className, index) => (
handleAspireClassSelect(className)} >
{className}
{aspireStudentData[className] ? `${aspireStudentData[className].length} students` : "No students"}
))}
)} {/* Step 2: Student Selection */} {step === 2 && (
{/* Class Filter - Only show if not from Aspire database */} {!aspireClasses.includes(selectedClass) && (
)} {/* Class Title */}

{selectedClass} Students

{/* Student List */}

Student List {students.length} students

{students.map((student, index) => (
handleStudentSelect(student)} >

{student.name}

{student.arabicName && (

{student.arabicName}

)}
ID: {student.id || "N/A"} {student.class || student.grade || ""}
))} {students.length === 0 && (

No students found in this class

Try selecting a different class or upload a new file

)}
)} {/* Step 3: Comment Selection */} {step === 3 && selectedStudent && (

Select comments from each category below. You can choose multiple comments in each section.

{/* Positive Comments */}

Positive Comments (Strengths & Praise) {positiveComments.length} selected

import { useState, useEffect } from 'react'; import * as XLSX from 'xlsx'; export default function EnhancedCommentGenerator() { // State management const [students, setStudents] = useState([]); const [classes, setClasses] = useState([]); const [selectedClass, setSelectedClass] = useState(''); const [selectedStudent, setSelectedStudent] = useState(null); const [positiveComments, setPositiveComments] = useState([]); const [developmentComments, setDevelopmentComments] = useState([]); const [behaviorComments, setBehaviorComments] = useState([]); const [improvementComments, setImprovementComments] = useState([]); const [customNotes, setCustomNotes] = useState(''); const [generatedComment, setGeneratedComment] = useState(''); const [isGenerating, setIsGenerating] = useState(false); const [characterCount, setCharacterCount] = useState(0); const [step, setStep] = useState(0); // Start at landing page (step 0) const [isUploading, setIsUploading] = useState(false); const [error, setError] = useState(''); const [generationAttempts, setGenerationAttempts] = useState(0); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [loginError, setLoginError] = useState(''); const [showLoginModal, setShowLoginModal] = useState(false); // API key is hardcoded const apiKey = "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"; // Sample student data for Aspire database const aspireStudents = [ { name: "Ahmed Al-Mansour", class: "9A" }, { name: "Fatima Al-Qasimi", class: "9A" }, { name: "Mohammed Al-Farsi", class: "9A" }, { name: "Aisha Al-Balushi", class: "9A" }, { name: "Omar Al-Hashimi", class: "9A" }, { name: "Layla Al-Mazrouei", class: "9B" }, { name: "Khalid Al-Suwaidi", class: "9B" }, { name: "Noura Al-Shamsi", class: "9B" }, { name: "Saeed Al-Zaabi", class: "9B" }, { name: "Maryam Al-Nuaimi", class: "9B" }, { name: "Ali Al-Dhaheri", class: "10A" }, { name: "Sara Al-Mansoori", class: "10A" }, { name: "Hamad Al-Ketbi", class: "10A" }, { name: "Hessa Al-Falasi", class: "10A" }, { name: "Rashid Al-Maktoum", class: "10A" }, { name: "Amna Al-Muhairi", class: "10B" }, { name: "Yousef Al-Naqbi", class: "10B" }, { name: "Maitha Al-Kaabi", class: "10B" }, { name: "Ibrahim Al-Marri", class: "10B" }, { name: "Shamma Al-Ameri", class: "10B" } ]; // Comment banks const positiveCommentsBank = [ "Completes work independently and shows consistent improvement.", "Demonstrates strong reading comprehension.", "Has good writing skills and creativity.", "Polite and well-mannered in class.", "Actively participates and engages in discussions.", "Shows dedication and effort in learning.", "Demonstrates confidence and is gaining independence.", "Talented and quick to grasp new language skills.", "Takes studies more seriously and shows maturity.", "Friendly and supportive to peers.", "Consistently improving both in reading and writing.", "Completes assignments with little or no guidance.", "Willingness to learn is evident.", "Shows steady progress over time.", "Attempts tasks without hesitation." ]; const developmentCommentsBank = [ "Improve writing mechanics (punctuation, spelling, grammar).", "Practice time management and task completion.", "Develop more consistent motivation across lessons.", "Strengthen ability to remain engaged throughout full class periods.", "Express ideas more clearly in writing.", "Improve tone when speaking to teachers or peers.", "Develop confidence to speak more often in class.", "Enhance note-taking and question-asking habits.", "Strengthen focus despite distractions around.", "Continue practicing on platforms like Write&Improve.", "Improve prioritization of tasks during class.", "Build stronger self-monitoring and self-discipline.", "Learn to transition between tasks more efficiently.", "Expand vocabulary to support academic writing.", "Apply learned concepts more consistently in assessments." ]; const behaviorCommentsBank = [ "Easily distracted and distracts others.", "Falls asleep during class.", "Watches shows or misuses tablet during lessons.", "Frequently side-tracks into unrelated conversations.", "Struggles to complete work due to lack of focus.", "Unmotivated attitude toward learning.", "Rarely participates in class activities.", "Lacks engagement, especially in critical moments.", "Constantly pulls peers into conversations.", "Can appear rude in tone, unintentionally.", "Only works when they feel like it.", "Distracts others by trying to entertain.", "Avoids tasks without teacher prompting.", "Slow to follow through on assigned tasks.", "Repeatedly asks for things without respecting boundaries." ]; const improvementCommentsBank = [ "Focus more during lessons to reduce distractions.", "Review lessons at home via platforms like Blackboard.", "Practice writing regularly to improve spelling and grammar.", "Stay engaged for the full lesson duration.", "Participate more actively in class discussions.", "Complete tasks within the given time.", "Be more consistent in submitting work.", "Minimize off-task behavior (e.g., chatting, daydreaming).", "Take learning seriously—this is a crucial year.", "Improve classroom behavior to support peers' focus.", "Take responsibility for personal academic progress.", "Be respectful in speech and actions toward others.", "Sleep well and stay energized for lessons.", "Practice using tone and expression appropriately.", "Set goals for each lesson to stay motivated." ]; // Handle Aspire database login const handleAspireLogin = (e) => { e.preventDefault(); if (username === 'Teacher2024' && password === 'Aspire123') { // Load the Aspire database setStudents(aspireStudents); // Extract unique classes const uniqueClasses = [...new Set(aspireStudents.map(student => student.class))]; setClasses(uniqueClasses); setSelectedClass(uniqueClasses[0] || ''); // Move to student selection step setStep(2); setShowLoginModal(false); setLoginError(''); } else { setLoginError('Invalid username or password. Please try again.'); } }; // Handle file upload const handleFileUpload = (e) => { const file = e.target.files[0]; setIsUploading(true); if (file) { const reader = new FileReader(); reader.onload = (evt) => { try { const data = evt.target.result; const workbook = XLSX.read(data, { type: 'binary' }); const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; const jsonData = XLSX.utils.sheet_to_json(worksheet); // Process student data const processedStudents = jsonData.map(row => ({ name: row.Name || row.name || '', class: row.Class || row.class || '' })).filter(student => student.name && student.class); // Extract unique classes const uniqueClasses = [...new Set(processedStudents.map(student => student.class))]; setStudents(processedStudents); setClasses(uniqueClasses); setSelectedClass(uniqueClasses[0] || ''); setStep(2); setIsUploading(false); } catch (error) { console.error("Error processing file:", error); alert("Error processing file. Please ensure it's a valid Excel file."); setIsUploading(false); } }; reader.onerror = () => { alert("Error reading file"); setIsUploading(false); }; reader.readAsBinaryString(file); } }; // Select a student const handleStudentSelect = (student) => { setSelectedStudent(student); setPositiveComments([]); setDevelopmentComments([]); setBehaviorComments([]); setImprovementComments([]); setCustomNotes(''); setGeneratedComment(''); setError(''); setStep(3); }; // Toggle comment selection const toggleComment = (comment, type) => { switch (type) { case 'positive': setPositiveComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; case 'development': setDevelopmentComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; case 'behavior': setBehaviorComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; case 'improvement': setImprovementComments(prev => prev.includes(comment) ? prev.filter(c => c !== comment) : [...prev, comment] ); break; default: break; } }; // Generate a fallback comment if API fails const generateFallbackComment = () => { const positive = positiveComments.length > 0 ? positiveComments[Math.floor(Math.random() * positiveComments.length)] : "shows good progress"; const development = developmentComments.length > 0 ? developmentComments[Math.floor(Math.random() * developmentComments.length)] : "needs to develop skills"; const behavior = behaviorComments.length > 0 ? behaviorComments[Math.floor(Math.random() * behaviorComments.length)] : ""; const improvement = improvementComments.length > 0 ? improvementComments[Math.floor(Math.random() * improvementComments.length)] : "should focus on improving"; const fallbackComment = `${selectedStudent.name} ${positive} ${behavior ? 'However, ' + behavior : ''} ${development} ${improvement}`; return fallbackComment; }; // Generate comment using OpenAI API const generateComment = async () => { if (!positiveComments.length || (!developmentComments.length && !behaviorComments.length && !improvementComments.length)) { setError("Please select at least one positive comment and one comment from any other category"); return; } setIsGenerating(true); setError(''); setGenerationAttempts(prev => prev + 1); try { // Prepare the prompt for OpenAI const prompt = `Write a personalized comment for ${selectedStudent.name} using these elements: Positive aspects: ${positiveComments.join(', ')} ${developmentComments.length > 0 ? `Areas for development: ${developmentComments.join(', ')}` : ''} ${behaviorComments.length > 0 ? `Behavior characteristics: ${behaviorComments.join(', ')}` : ''} ${improvementComments.length > 0 ? `Improvement suggestions: ${improvementComments.join(', ')}` : ''} ${customNotes ? `Additional notes: ${customNotes}` : ''} Follow these rules strictly: 1. Use a sandwich approach (positive-improvement-positive/encouragement) 2. Keep it EXACTLY between 350-450 characters including spaces (this is critical) 3. Make it sound natural and personalized, like a real teacher would write 4. Use the student's name 5. Don't simply list the comments, integrate them naturally 6. Vary sentence structure 7. Use simple, clear language at A2-B1 level (intermediate English) 8. Avoid complex vocabulary and sentence structures 9. Do not exceed 450 characters under any circumstances 10. Do NOT include a character count in your response`; // Call OpenAI API const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [ { role: "system", content: "You are an experienced English teacher writing student comments. Write in a warm, supportive tone using simple language (A2-B1 level). Your comments must be EXACTLY between 350-450 characters including spaces." }, { role: "user", content: prompt } ], temperature: 0.7, max_tokens: 300 }), }); const data = await response.json(); if (data.error) { throw new Error(data.error.message || "Error calling OpenAI API"); } let generatedText = data.choices[0].message.content.trim(); const charCount = generatedText.length; // Check if the comment is within the character limit if (charCount < 350 || charCount > 450) { // Try again if outside the limit if (generationAttempts < 3) { setIsGenerating(false); return generateComment(); } } setGeneratedComment(generatedText); setCharacterCount(charCount); setStep(4); } catch (error) { console.error("Error generating comment:", error); // Use fallback if API fails if (generationAttempts > 2) { const fallbackComment = generateFallbackComment(); const charCount = fallbackComment.length; setGeneratedComment(fallbackComment); setCharacterCount(charCount); setStep(4); setError("API connection failed. Using simplified comment generation."); } else { setError(`Error: ${error.message}. Please try again.`); } } finally { setIsGenerating(false); } }; // Reset to start over const resetApp = () => { setSelectedStudent(null); setPositiveComments([]); setDevelopmentComments([]); setBehaviorComments([]); setImprovementComments([]); setCustomNotes(''); setGeneratedComment(''); setError(''); setGenerationAttempts(0); setStep(2); }; // Back to student selection const backToStudents = () => { setSelectedStudent(null); setPositiveComments([]); setDevelopmentComments([]); setBehaviorComments([]); setImprovementComments([]); setCustomNotes(''); setGeneratedComment(''); setError(''); setGenerationAttempts(0); setStep(2); }; // Back to comment selection const backToComments = () => { setGeneratedComment(''); setError(''); setGenerationAttempts(0); setStep(3); }; // Get step title const getStepTitle = () => { switch (step) { case 0: return "Welcome to Student Comment Generator"; case 1: return "Upload Student Data"; case 2: return "Select a Student"; case 3: return selectedStudent ? `Select Comments for ${selectedStudent.name}` : "Select Comments"; case 4: return selectedStudent ? `Review Comment for ${selectedStudent.name}` : "Review Comment"; default: return ""; } }; // Copy comment to clipboard const copyComment = () => { navigator.clipboard.writeText(generatedComment); alert("Comment copied to clipboard!"); }; // Check if the character count is within the required range const isCharCountValid = () => { return characterCount >= 350 && characterCount <= 450; }; // Render login modal const renderLoginModal = () => { if (!showLoginModal) return null; return (

Aspire Database Login

{loginError && (

{loginError}

)}
setUsername(e.target.value)} required />
setPassword(e.target.value)} required />
); }; return (
{/* Header */}

Student Comment Generator

Streamline your feedback process with AI-powered comments

{/* Main Content */}
{/* Progress Steps - Only show for steps 1-4 */} {step > 0 && (
{/* Progress Bar */}
{/* Step Circles */}
= 1 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 1
= 1 ? 'text-teal-600' : 'text-gray-400'}`}>Upload
= 2 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 2
= 2 ? 'text-teal-600' : 'text-gray-400'}`}>Select Student
= 3 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 3
= 3 ? 'text-teal-600' : 'text-gray-400'}`}>Choose Comments
= 4 ? 'bg-teal-500 text-white shadow-md' : 'bg-white text-gray-400 border-2 border-gray-200' }`} > 4
= 4 ? 'text-teal-600' : 'text-gray-400'}`}>Review
)} {/* Content Card */}
{/* Card Header */}

{getStepTitle()}

{step > 1 && ( )}
{/* Card Content */}
{/* Error Message */} {error && (

{error}

)} {/* Step 0: Landing Page */} {step === 0 && (

Choose Your Data Source

Select how you want to access student data for generating comments. You can either connect to the Aspire database or upload your own student list.

{/* Aspire Database Option */}
setShowLoginModal(true)} >

Aspire Database

Connect to the Aspire school database to access your student records directly.

{/* Upload Own Data Option */}
setStep(1)} >

Upload Student List

Upload your own Excel file with student names and class information.

About This Tool

The Student Comment Generator helps teachers create personalized, well-structured comments for student reports. Select from pre-written comment banks and let AI combine them into natural-sounding feedback that follows the sandwich approach (positive-improvement-positive). All comments are between 350-450 characters.

)} {/* Step 1: File Upload */} {step === 1 && (

Upload an Excel file containing student names and class information. The file should have columns for "Name" and "Class".

Drag and drop your Excel file here, or

Sample Format:

Name Class
John Smith 9A
Emma Johnson 9A
Michael Brown 12B
)} {/* Step 2: Student Selection */} {step === 2 && (
{/* Class Filter */}
{/* Student List */}

{selectedClass ? `Students in ${selectedClass}` : 'All Students'} {students.filter(student => !selectedClass || student.class === selectedClass).length} students

{students .filter(student => !selectedClass || student.class === selectedClass) .map((student, index) => (
handleStudentSelect(student)} >

{student.name}

Class: {student.class}

))} {students.filter(student => !selectedClass || student.class === selectedClass).length === 0 && (

No students found in this class

Try selecting a different class or upload a new file

)}
)} {/* Step 3: Comment Selection */} {step === 3 && selectedStudent && (

Select comments from each category below. You can choose multiple comments in each section.

{/* Positive Comments */}

Positive Comments (Strengths & Praise) {positiveComments.length} selected

{positiveCommentsBank.map((comment, index) => (
toggleComment(comment, 'positive')} >
{positiveComments.includes(comment) && ( )}
{comment}
))}
{/* Development Comments */}

📘 Areas of Development (Skills to Build) {developmentComments.length} selected

{developmentCommentsBank.map((comment, index) => (
toggleComment(comment, 'development')} >
{developmentComments.includes(comment) && ( )}
{comment}
))}
{/* Behavior Comments */}

⚠️ Behaviour Issues or Characteristics {behaviorComments.length} selected

{behaviorCommentsBank.map((comment, index) => (
toggleComment(comment, 'behavior')} >
{behaviorComments.includes(comment) && ( )}
{comment}
))}
{/* Improvement Comments */}

🔧 Areas of Improvement (Targets & Suggestions) {improvementComments.length} selected

{improvementCommentsBank.map((comment, index) => (
toggleComment(comment, 'improvement')} >
{improvementComments.includes(comment) && ( )}
{comment}
))}
{/* Custom Notes */}

Additional Notes (Optional)

)} {/* Step 4: Review Generated Comment */} {step === 4 && generatedComment && (

{generatedComment}

450 ? 'text-red-600' : characterCount < 350 ? 'text-amber-600' : 'text-green-600' }`}> {characterCount} characters {characterCount > 450 ? ' (too long)' : characterCount < 350 ? ' (too short)' : ' (perfect!)'}
)}
{/* Footer */} {/* Login Modal */} {renderLoginModal()}
); }