CoolFace
Apppublic

mynewi/GradingApp

sourceHugging Faceupdated 28d agoView on Hugging Face
0likes
index.html272 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4  <meta charset="UTF-8" />5  <meta name="viewport" content="width=device-width, initial-scale=1.0" />6  <title>Academic Evaluator Pro</title>7  <link rel="preconnect" href="https://fonts.googleapis.com">8  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>9  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">10 11  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>12  <script src="https://unpkg.com/jszip/dist/jszip.min.js"></script>13  <script src="https://unpkg.com/docx-preview/dist/docx-preview.min.js"></script>14  <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>15  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>16  <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>17  <link rel="stylesheet" href="style.css" />18</head>19<body>20  <header class="app-header">21    <div class="brand-area">22      <div class="brand-title">Academic Evaluator <span>Pro</span></div>23      <div class="brand-subtitle">Flexible local grading workspace</div>24    </div>25    <div class="header-actions">26      <input type="file" id="file-upload" accept="application/pdf,.pdf,.docx" hidden />27      <button class="btn btn-primary" id="upload-btn">📄 Upload Assignment</button>28      <button class="btn btn-secondary" id="config-btn">⚙ Configurations</button>29      <button class="btn btn-secondary" id="new-batch-btn">🗂 New Student Batch</button>30      <button class="btn btn-secondary" id="gradebook-btn">👥 Gradebook</button>31      <button class="btn btn-highlight" id="export-btn">📊 Export Final Scores</button>32      <button class="btn btn-ghost" id="backup-btn">💾 Save / Backup Session</button>33    </div>34  </header>35 36  <main class="app-shell">37    <section class="document-pane" id="document-pane">38      <div class="viewer-statusbar">39        <div>40          <strong id="viewer-file-name">No assignment loaded</strong>41          <span id="viewer-file-meta">PDF and DOCX supported · Word files are converted locally for viewing</span>42        </div>43        <span id="autosave-pill" class="autosave-pill">✓ Auto-save active</span>44      </div>45 46      <div class="empty-state" id="empty-state">47        <div class="empty-icon">📚</div>48        <h2>Ready to grade</h2>49        <p>Upload a PDF or DOCX submission. Configurations, student records and unfinished grading entries are automatically saved in this browser.</p>50        <button class="btn btn-primary" id="empty-upload-btn">Upload Assignment</button>51        <div class="privacy-note"><strong>Local-first:</strong> this app does not send student grades to a grading server.</div>52      </div>53 54      <div id="custom-pdf-viewer" class="viewer-wrap" hidden>55        <div class="doc-toolbar">56          <div class="toolbar-group">57            <button class="btn btn-sm" id="pdf-prev">◀ Prev</button>58            <span class="page-info">Page <span id="page_num">1</span> / <span id="page_count">1</span></span>59            <button class="btn btn-sm" id="pdf-next">Next ▶</button>60            <span class="toolbar-divider"></span>61            <button class="btn btn-sm" id="pdf-zoom-out">−</button>62            <span class="zoom-info"><span id="zoom_val">120</span>%</span>63            <button class="btn btn-sm" id="pdf-zoom-in">+</button>64            <span class="toolbar-tip">Ctrl + scroll to zoom · scroll past page edge to change page</span>65          </div>66          <button class="btn btn-danger-soft btn-sm" id="drop-paper-pdf">✕ Drop Paper</button>67        </div>68        <div class="canvas-wrapper" id="canvas-wrapper">69          <canvas id="pdf-canvas"></canvas>70        </div>71      </div>72 73      <div id="conversion-state" class="conversion-state" hidden>74        <div class="conversion-card">75          <div class="conversion-spinner"></div>76          <h3>Preparing Word document</h3>77          <p id="conversion-message">Converting DOCX to a local PDF preview…</p>78        </div>79      </div>80      <div id="docx-conversion-host" aria-hidden="true"><div id="docx-conversion-content"></div></div>81    </section>82 83    <aside class="grading-pane">84      <section class="grading-section grading-top">85        <div class="section-title-row">86          <div>87            <div class="eyebrow">EVALUATION PANEL</div>88            <h2>Grade Submission</h2>89          </div>90          <span class="batch-chip" id="current-batch-chip">Batch will be set on first save</span>91        </div>92 93        <label class="field-label" for="active-config">Configuration</label>94        <select id="active-config" class="field-control"></select>95 96        <label class="field-label" for="active-assignment">Assignment</label>97        <select id="active-assignment" class="field-control"></select>98        <div id="assignment-meta" class="assignment-meta"></div>99 100        <div class="student-grid">101          <div>102            <label class="field-label" for="student-name">Student Name</label>103            <input id="student-name" class="field-control" autocomplete="off" placeholder="Student name" />104          </div>105          <div>106            <label class="field-label" for="student-id">Student ID</label>107            <input id="student-id" class="field-control" autocomplete="off" placeholder="Student ID" />108          </div>109        </div>110        <div id="group-field-wrap" hidden>111          <label class="field-label" for="group-number">Group #</label>112          <input id="group-number" class="field-control" autocomplete="off" placeholder="e.g. G03" />113        </div>114 115        <div class="progress-wrap">116          <div class="progress-label"><span>Rubric progress</span><span id="rubric-progress-text">0 / 0 criteria touched</span></div>117          <div class="progress-track"><div id="rubric-progress-bar" class="progress-bar"></div></div>118        </div>119      </section>120 121      <div id="sliders-container" class="sliders-container"></div>122 123      <section class="feedback-section">124        <label class="field-label" for="lecturer-feedback">Lecturer Feedback / Notes</label>125        <textarea id="lecturer-feedback" rows="4" placeholder="Overall feedback or notes..."></textarea>126      </section>127 128      <section class="score-dashboard">129        <div class="score-card">130          <span>Rubric Score</span>131          <strong id="rubric-score">0</strong><small>/ 100</small>132        </div>133        <div class="score-card">134          <span>Assignment Weight</span>135          <strong id="assignment-weight">0</strong><small>%</small>136        </div>137        <div class="score-card highlight">138          <span>Final Contribution</span>139          <strong id="weighted-score">0.00</strong><small>/ <span id="weighted-max">0</span></small>140        </div>141      </section>142 143      <section class="save-zone">144        <button class="btn btn-primary btn-full" id="save-record-btn">📥 Save Student Record & Next</button>145        <button class="btn btn-outline btn-full top-gap" id="group-import-open" hidden>👥 Import Group Assignment Grades</button>146        <div class="save-helper">Student ID is the primary key within the current batch.</div>147      </section>148    </aside>149  </main>150 151  <!-- CONFIGURATION -->152  <div class="modal-overlay" id="config-modal" hidden>153    <div class="modal-card modal-xl">154      <div class="modal-header">155        <div><div class="eyebrow">SAVED SETUPS</div><h2>Configurations</h2><p>Each configuration must total 100% across assignments, and every assignment rubric must total 100%.</p></div>156        <button class="icon-btn" data-close="config-modal">✕</button>157      </div>158      <div class="config-layout">159        <aside class="config-sidebar">160          <button class="btn btn-primary btn-full" id="new-config-btn">+ New Configuration</button>161          <div id="config-list" class="config-list"></div>162          <div class="sidebar-actions">163            <button class="btn btn-outline btn-full" id="duplicate-config-btn">Duplicate</button>164            <button class="btn btn-danger-soft btn-full" id="delete-config-btn">Delete</button>165          </div>166        </aside>167        <section class="config-editor">168          <div class="editor-heading-grid">169            <div><label class="field-label">Configuration Name</label><input id="config-name" class="field-control" /></div>170            <div><label class="field-label">Subject / Code (optional)</label><input id="config-code" class="field-control" /></div>171          </div>172          <div id="config-summary" class="config-summary"></div>173          <div id="assignment-editor-list"></div>174          <button class="btn btn-outline btn-full" id="add-assignment-btn">+ Add Assignment</button>175        </section>176      </div>177      <div class="modal-footer">178        <span class="footer-note">Saved configurations remain available in this browser for reuse across terms.</span>179        <button class="btn btn-secondary-dark" data-close="config-modal">Cancel</button>180        <button class="btn btn-primary" id="save-config-btn">Save Configuration</button>181      </div>182    </div>183  </div>184 185  <!-- FIRST BATCH SETUP -->186  <div class="modal-overlay" id="first-batch-modal" hidden>187    <div class="modal-card modal-sm">188      <div class="modal-header"><div><div class="eyebrow">FIRST STUDENT RECORD</div><h2>Set up this student batch</h2><p>This appears only when the first record is saved/imported for a new batch.</p></div></div>189      <div class="modal-body">190        <label class="field-label" for="first-batch-name">Batch / Term Name</label>191        <input id="first-batch-name" class="field-control" placeholder="e.g. September 2026 Intake" />192        <div class="info-box"><strong>Auto-save is already active in this browser.</strong> The batch name and grading records will continue to save automatically. Use “Save / Backup Session” whenever you want a separate backup file on your computer.</div>193      </div>194      <div class="modal-footer stacked-mobile">195        <button class="btn btn-outline" id="first-batch-cancel">Cancel</button>196        <button class="btn btn-primary" id="first-batch-browser">Start Batch & Save</button>197      </div>198    </div>199  </div>200 201  <!-- NEW BATCH -->202  <div class="modal-overlay" id="new-batch-modal" hidden>203    <div class="modal-card modal-sm">204      <div class="modal-header"><div><div class="eyebrow">NEW STUDENT BATCH</div><h2>Start a Fresh Batch</h2><p>The current configuration is reused; existing records are not deleted.</p></div><button class="icon-btn" data-close="new-batch-modal">✕</button></div>205      <div class="modal-body">206        <label class="field-label" for="new-batch-name">Batch / Term Name</label>207        <input id="new-batch-name" class="field-control" placeholder="e.g. January 2027 Intake" />208        <div class="info-box">This creates a new empty student record set for <strong id="new-batch-config-name"></strong>. Previous batches remain preserved in browser storage and in backups.</div>209      </div>210      <div class="modal-footer"><button class="btn btn-secondary-dark" data-close="new-batch-modal">Cancel</button><button class="btn btn-primary" id="create-batch-btn">Create New Batch</button></div>211    </div>212  </div>213 214  <!-- GROUP IMPORT -->215  <div class="modal-overlay" id="group-import-modal" hidden>216    <div class="modal-card modal-lg">217      <div class="modal-header"><div><div class="eyebrow">GROUP ASSIGNMENT</div><h2>Import Group Grades</h2><p>One uploaded row becomes one student assignment record.</p></div><button class="icon-btn" data-close="group-import-modal">✕</button></div>218      <div class="modal-body">219        <div class="info-box"><strong>Required columns:</strong> Student Name, Student ID, Grade, Group #. Grade is always entered out of 100. Student ID and Grade cannot be blank.</div>220        <div class="group-import-actions">221          <button class="btn btn-outline" id="download-group-template">⬇ Download Excel Template</button>222          <label class="btn btn-primary file-label">⬆ Upload Excel / CSV<input id="group-file-input" type="file" accept=".xlsx,.xls,.csv" hidden></label>223        </div>224        <div class="or-separator">OR PASTE FROM EXCEL / GOOGLE SHEETS</div>225        <textarea id="group-paste-area" rows="9" placeholder="Student Name    Student ID    Grade    Group #"></textarea>226        <button class="btn btn-outline btn-full top-gap" id="import-pasted-group">Import Pasted Rows</button>227        <div id="group-import-result" class="import-result" hidden></div>228      </div>229    </div>230  </div>231 232  <!-- GRADEBOOK -->233  <div class="modal-overlay" id="gradebook-modal" hidden>234    <div class="modal-card modal-xxl">235      <div class="modal-header"><div><div class="eyebrow">CURRENT BATCH</div><h2>Gradebook</h2><p id="gradebook-subtitle"></p></div><button class="icon-btn" data-close="gradebook-modal">✕</button></div>236      <div class="gradebook-toolbar">237        <input id="gradebook-search" class="field-control" placeholder="Search student name or ID" />238        <select id="gradebook-sort" class="field-control"><option value="id">Sort by Student ID</option><option value="name">Sort by Name</option><option value="score-desc">Highest Final Score</option><option value="score-asc">Lowest Final Score</option></select>239        <button class="btn btn-outline" id="gradebook-refresh">Refresh</button>240        <button class="btn btn-outline" id="print-reports">🖨 Student Reports</button>241        <button class="btn btn-primary" id="gradebook-export">📊 Export Excel</button>242      </div>243      <div class="gradebook-table-wrap"><table class="gradebook-table" id="gradebook-table"></table></div>244    </div>245  </div>246 247  <!-- STUDENT REPORT -->248  <div class="modal-overlay" id="student-report-modal" hidden>249    <div class="modal-card modal-lg">250      <div class="modal-header"><div><div class="eyebrow">STUDENT RECORD</div><h2 id="student-report-title">Student</h2><p id="student-report-subtitle"></p></div><button class="icon-btn" data-close="student-report-modal">✕</button></div>251      <div class="modal-body" id="student-report-body"></div>252    </div>253  </div>254 255  <!-- BACKUP -->256  <div class="modal-overlay" id="backup-modal" hidden>257    <div class="modal-card modal-sm">258      <div class="modal-header"><div><div class="eyebrow">LOCAL SAFETY COPY</div><h2>Save / Backup Your Session</h2><p>Your browser auto-saves continuously. Use these options for an extra recoverable copy.</p></div><button class="icon-btn" data-close="backup-modal">✕</button></div>259      <div class="modal-body">260        <div id="backup-status-card" class="storage-status-card"></div>261        <button class="btn btn-primary btn-full" id="export-backup-btn">⬇ Save Session Backup File (.json)</button>262        <label class="btn btn-outline btn-full top-gap file-label">⬆ Restore Session Backup<input id="restore-backup-file" type="file" accept="application/json" hidden></label>263        <p class="microcopy">Browser auto-save is the working copy. The JSON backup is a separate safety copy saved through your browser’s normal download process, so it also works when the app is embedded in Hugging Face.</p>264      </div>265    </div>266  </div>267 268  <div id="toast" class="toast" hidden></div>269  <script src="app.js"></script>270</body>271</html>272