add photo placeholder, mirrored camera capture, configurable footer, and student .url zip export
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
<input type="text" id="studentSearch" class="search-input" placeholder="Поиск по имени..." style="flex:1;min-width:200px;max-width:340px;padding:10px 14px;font-size:.9rem">
|
||||
<select id="studentGroupFilter" class="search-input" style="padding:10px 14px"><option value="">Все группы</option></select>
|
||||
<button class="btn-link" onclick="exportStudentsCSV()">Экспорт CSV</button>
|
||||
<button class="btn-link" onclick="exportStudentsUrls()">Экспорт URL</button>
|
||||
</div>
|
||||
<div class="list" id="studentList"></div>
|
||||
<div class="pager" id="pager"></div>
|
||||
@@ -67,6 +68,7 @@
|
||||
|
||||
<div class="toast" id="toast"></div>
|
||||
<script src="admin.js"></script>
|
||||
<script src="vendor/jszip.min.js"></script>
|
||||
<script>
|
||||
// --- Students ---
|
||||
let allStudents = [];
|
||||
@@ -216,6 +218,15 @@ function exportStudentsCSV() {
|
||||
showToast(`Экспортировано: ${list.length}`);
|
||||
}
|
||||
|
||||
async function exportStudentsUrls() {
|
||||
const gid = document.getElementById('studentGroupFilter').value;
|
||||
const list = gid ? allStudents.filter(s => String(s.group_id) === gid) : allStudents;
|
||||
if (!list.length) { alert('Нет данных для экспорта'); return; }
|
||||
const groupName = gid ? (allGroups.find(g => g.id == gid)?.name || 'group') : 'all';
|
||||
await exportStudentUrlZip(list, `students_${groupName.replace(/[\\/:*?"<>|]/g, '_')}.zip`);
|
||||
showToast(`Экспортировано: ${list.length}`);
|
||||
}
|
||||
|
||||
// --- Batch attach ---
|
||||
async function openBatchAttach() {
|
||||
const sel = document.getElementById('attachGroup');
|
||||
|
||||
Reference in New Issue
Block a user