Spaces:
Running
Running
root commited on
Commit ·
4d801c0
1
Parent(s): 2cf90d8
feat: add session duplication as collection and flatten question entry UI
Browse files- neetprep.py +49 -0
- templates/dashboard.html +30 -0
- templates/question_entry_v2.html +29 -44
neetprep.py
CHANGED
|
@@ -873,6 +873,55 @@ def update_bookmark_collection(session_id):
|
|
| 873 |
conn.close()
|
| 874 |
return jsonify({'success': True})
|
| 875 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 876 |
@neetprep_bp.route('/neetprep/bookmark', methods=['POST'])
|
| 877 |
@login_required
|
| 878 |
def add_bookmark():
|
|
|
|
| 873 |
conn.close()
|
| 874 |
return jsonify({'success': True})
|
| 875 |
|
| 876 |
+
@neetprep_bp.route('/neetprep/collections/duplicate/<source_session_id>', methods=['POST'])
|
| 877 |
+
@login_required
|
| 878 |
+
def duplicate_as_collection(source_session_id):
|
| 879 |
+
"""Duplicate a session as a neetprep collection, including only classified questions."""
|
| 880 |
+
import uuid
|
| 881 |
+
conn = get_db_connection()
|
| 882 |
+
|
| 883 |
+
# 1. Verify source session ownership and get metadata
|
| 884 |
+
source_session = conn.execute('SELECT name, subject, tags, notes, original_filename FROM sessions WHERE id = ? AND user_id = ?', (source_session_id, current_user.id)).fetchone()
|
| 885 |
+
if not source_session:
|
| 886 |
+
conn.close()
|
| 887 |
+
return jsonify({'error': 'Source session not found'}), 404
|
| 888 |
+
|
| 889 |
+
# 2. Get all classified questions from the source session
|
| 890 |
+
classified_questions = conn.execute("""
|
| 891 |
+
SELECT id FROM questions
|
| 892 |
+
WHERE session_id = ? AND subject IS NOT NULL AND chapter IS NOT NULL AND chapter != 'Unclassified'
|
| 893 |
+
""", (source_session_id,)).fetchall()
|
| 894 |
+
|
| 895 |
+
if not classified_questions:
|
| 896 |
+
conn.close()
|
| 897 |
+
return jsonify({'error': 'No classified questions found in this session.'}), 400
|
| 898 |
+
|
| 899 |
+
# 3. Create a new collection session
|
| 900 |
+
new_session_id = str(uuid.uuid4())
|
| 901 |
+
new_name = f"Copy of {source_session['name'] or source_session['original_filename']}"
|
| 902 |
+
|
| 903 |
+
conn.execute("""
|
| 904 |
+
INSERT INTO sessions (id, name, subject, tags, notes, user_id, session_type, persist)
|
| 905 |
+
VALUES (?, ?, ?, ?, ?, ?, 'neetprep_collection', 1)
|
| 906 |
+
""", (new_session_id, new_name, source_session['subject'], source_session['tags'], source_session['notes'], current_user.id))
|
| 907 |
+
|
| 908 |
+
# 4. Link classified questions to the new collection
|
| 909 |
+
for q in classified_questions:
|
| 910 |
+
conn.execute("""
|
| 911 |
+
INSERT INTO neetprep_bookmarks (user_id, neetprep_question_id, session_id, question_type)
|
| 912 |
+
VALUES (?, ?, ?, 'classified')
|
| 913 |
+
""", (current_user.id, str(q['id']), new_session_id))
|
| 914 |
+
|
| 915 |
+
conn.commit()
|
| 916 |
+
conn.close()
|
| 917 |
+
|
| 918 |
+
return jsonify({
|
| 919 |
+
'success': True,
|
| 920 |
+
'session_id': new_session_id,
|
| 921 |
+
'name': new_name,
|
| 922 |
+
'count': len(classified_questions)
|
| 923 |
+
})
|
| 924 |
+
|
| 925 |
@neetprep_bp.route('/neetprep/bookmark', methods=['POST'])
|
| 926 |
@login_required
|
| 927 |
def add_bookmark():
|
templates/dashboard.html
CHANGED
|
@@ -125,6 +125,7 @@
|
|
| 125 |
{% else %}
|
| 126 |
<a href="{{ url_for('main.question_entry_v2', session_id=session.id) }}" class="btn btn-sm btn-primary">View</a>
|
| 127 |
<a href="{{ url_for('main.crop_interface_v2', session_id=session.id, image_index=0) }}" class="btn btn-sm btn-secondary">Crop</a>
|
|
|
|
| 128 |
<button class="btn btn-sm btn-info toggle-persist-btn">Toggle Persist</button>
|
| 129 |
{% if show_size %}
|
| 130 |
<button class="btn btn-sm btn-warning reduce-space-btn">Reduce Space</button>
|
|
@@ -386,6 +387,35 @@ $(document).ready(function() {
|
|
| 386 |
}
|
| 387 |
});
|
| 388 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
});
|
| 390 |
</script>
|
| 391 |
{% endblock %}
|
|
|
|
| 125 |
{% else %}
|
| 126 |
<a href="{{ url_for('main.question_entry_v2', session_id=session.id) }}" class="btn btn-sm btn-primary">View</a>
|
| 127 |
<a href="{{ url_for('main.crop_interface_v2', session_id=session.id, image_index=0) }}" class="btn btn-sm btn-secondary">Crop</a>
|
| 128 |
+
<button class="btn btn-sm btn-outline-success duplicate-session-btn" data-session-id="{{ session.id }}" title="Duplicate as NEETprep Collection"><i class="bi bi-copy"></i></button>
|
| 129 |
<button class="btn btn-sm btn-info toggle-persist-btn">Toggle Persist</button>
|
| 130 |
{% if show_size %}
|
| 131 |
<button class="btn btn-sm btn-warning reduce-space-btn">Reduce Space</button>
|
|
|
|
| 387 |
}
|
| 388 |
});
|
| 389 |
});
|
| 390 |
+
|
| 391 |
+
// Duplicate session as collection
|
| 392 |
+
$('.duplicate-session-btn').on('click', function() {
|
| 393 |
+
const button = $(this);
|
| 394 |
+
const sessionId = button.data('session-id');
|
| 395 |
+
|
| 396 |
+
if (confirm('Duplicate this session as a NEETprep collection? Only classified questions (subject + topic) will be included.')) {
|
| 397 |
+
button.prop('disabled', true).html('<span class="spinner-border spinner-border-sm"></span>');
|
| 398 |
+
|
| 399 |
+
$.ajax({
|
| 400 |
+
url: `/neetprep/collections/duplicate/${sessionId}`,
|
| 401 |
+
type: 'POST',
|
| 402 |
+
success: function(response) {
|
| 403 |
+
if (response.success) {
|
| 404 |
+
alert(`Successfully duplicated! Created collection "${response.name}" with ${response.count} questions.`);
|
| 405 |
+
location.reload();
|
| 406 |
+
} else {
|
| 407 |
+
alert('Error duplicating session: ' + response.error);
|
| 408 |
+
button.prop('disabled', false).html('<i class="bi bi-copy"></i>');
|
| 409 |
+
}
|
| 410 |
+
},
|
| 411 |
+
error: function(xhr) {
|
| 412 |
+
const err = xhr.responseJSON ? xhr.responseJSON.error : 'Unknown error';
|
| 413 |
+
alert('Error duplicating session: ' + err);
|
| 414 |
+
button.prop('disabled', false).html('<i class="bi bi-copy"></i>');
|
| 415 |
+
}
|
| 416 |
+
});
|
| 417 |
+
}
|
| 418 |
+
});
|
| 419 |
});
|
| 420 |
</script>
|
| 421 |
{% endblock %}
|
templates/question_entry_v2.html
CHANGED
|
@@ -35,33 +35,32 @@
|
|
| 35 |
border: 1px solid var(--border-subtle);
|
| 36 |
background: transparent;
|
| 37 |
color: #fff;
|
| 38 |
-
border-radius:
|
| 39 |
cursor: pointer;
|
| 40 |
transition: all var(--transition-fast);
|
| 41 |
}
|
| 42 |
.status-btn.active { background: var(--accent-primary); border-color: var(--accent-primary); }
|
| 43 |
-
.status-btn:hover { background: var(--bg-hover);
|
| 44 |
.auto-extract-btn { min-width: 120px; }
|
| 45 |
|
| 46 |
/* Subject pills */
|
| 47 |
.subject-pill {
|
| 48 |
transition: all var(--transition-fast);
|
| 49 |
-
border-radius:
|
| 50 |
}
|
| 51 |
.subject-pill.active {
|
| 52 |
-
|
| 53 |
-
box-shadow: 0 0 12px rgba(255,255,255,0.3);
|
| 54 |
}
|
| 55 |
|
| 56 |
/* Range toggles */
|
| 57 |
.range-toggle {
|
| 58 |
transition: all var(--transition-fast);
|
| 59 |
-
border-radius:
|
| 60 |
}
|
| 61 |
.range-toggle:hover {
|
| 62 |
-
|
| 63 |
}
|
| 64 |
-
.range-toggle.active {
|
| 65 |
.range-toggle.active.btn-outline-primary { background: var(--accent-primary); color: #fff; }
|
| 66 |
.range-toggle.active.btn-outline-warning { background: var(--accent-warning); color: #000; }
|
| 67 |
.range-toggle.active.btn-outline-danger { background: var(--accent-danger); color: #fff; }
|
|
@@ -69,15 +68,15 @@
|
|
| 69 |
.range-toggle.active.btn-outline-info { background: var(--accent-info); color: #000; }
|
| 70 |
|
| 71 |
/* Range slider styling */
|
| 72 |
-
.range-slider-row { background: var(--bg-elevated); border-radius:
|
| 73 |
.range-slider-row:hover { background: var(--bg-hover); }
|
| 74 |
.dual-range-container { position: relative; height: 40px; }
|
| 75 |
-
.dual-range-track { position: absolute; top: 50%; left: 0; right: 0; height: 8px; background: var(--border-subtle); border-radius:
|
| 76 |
-
.dual-range-highlight { position: absolute; top: 50%; height: 8px; background:
|
| 77 |
.dual-range-container input[type="range"] { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: none; background: transparent; pointer-events: none; }
|
| 78 |
-
.dual-range-container input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width:
|
| 79 |
-
.dual-range-container input[type="range"]::-webkit-slider-thumb:hover {
|
| 80 |
-
.dual-range-container input[type="range"]::-moz-range-thumb { width:
|
| 81 |
|
| 82 |
/* Tom Select Dark Theme */
|
| 83 |
.ts-wrapper .ts-control, .ts-wrapper .ts-control input {
|
|
@@ -102,26 +101,21 @@
|
|
| 102 |
|
| 103 |
/* --- UNIFIED NOTE CARD STYLES --- */
|
| 104 |
.note-card {
|
| 105 |
-
background:
|
| 106 |
-
border: 1px solid rgba(13, 202, 240, 0.
|
| 107 |
-
border-radius:
|
| 108 |
padding: 10px;
|
| 109 |
margin-bottom: 8px;
|
| 110 |
transition: all var(--transition-fast);
|
| 111 |
}
|
| 112 |
.note-card:hover {
|
| 113 |
border-color: var(--accent-info);
|
| 114 |
-
box-shadow: 0 0 12px rgba(13, 202, 240, 0.15);
|
| 115 |
}
|
| 116 |
.note-thumbnail {
|
| 117 |
max-height: 80px;
|
| 118 |
object-fit: contain;
|
| 119 |
-
border-radius:
|
| 120 |
-
border: 1px solid rgba(13, 202, 240, 0.
|
| 121 |
-
transition: transform var(--transition-fast);
|
| 122 |
-
}
|
| 123 |
-
.note-thumbnail:hover {
|
| 124 |
-
transform: scale(1.05);
|
| 125 |
}
|
| 126 |
.note-actions {
|
| 127 |
display: flex;
|
|
@@ -137,12 +131,11 @@
|
|
| 137 |
|
| 138 |
/* --- UNIFIED BUTTON STYLES --- */
|
| 139 |
.btn-pill {
|
| 140 |
-
border-radius:
|
| 141 |
font-weight: 500;
|
| 142 |
transition: all var(--transition-fast);
|
| 143 |
}
|
| 144 |
.btn-pill:hover {
|
| 145 |
-
transform: translateY(-1px);
|
| 146 |
box-shadow: var(--shadow-sm);
|
| 147 |
}
|
| 148 |
</style>
|
|
@@ -421,7 +414,7 @@
|
|
| 421 |
<div class="modal fade" id="manualClassificationModal" tabindex="-1">
|
| 422 |
<div class="modal-dialog modal-lg">
|
| 423 |
<div class="modal-content bg-dark text-white">
|
| 424 |
-
<div class="modal-header border-secondary" style="background:
|
| 425 |
<h5 class="modal-title"><i class="bi bi-list-check me-2"></i>Quick Classification</h5>
|
| 426 |
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
| 427 |
</div>
|
|
@@ -516,11 +509,11 @@
|
|
| 516 |
<div class="modal fade" id="topicSelectionModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
|
| 517 |
<div class="modal-dialog modal-lg modal-dialog-centered">
|
| 518 |
<div class="modal-content bg-dark text-white border-secondary">
|
| 519 |
-
<div class="modal-header border-secondary py-2" style="background:
|
| 520 |
<div class="d-flex align-items-center gap-3">
|
| 521 |
<span class="badge bg-primary fs-6" id="topic_q_num">#1</span>
|
| 522 |
<div class="progress flex-grow-1" style="width: 150px; height: 6px;">
|
| 523 |
-
<div class="progress-bar" id="topic_progress_bar" role="progressbar" style="width: 0%; background:
|
| 524 |
</div>
|
| 525 |
<small id="topic_progress" class="text-muted">1/10</small>
|
| 526 |
</div>
|
|
@@ -534,20 +527,12 @@
|
|
| 534 |
|
| 535 |
<!-- Subject Selection (Auto-detected, editable) -->
|
| 536 |
<div class="mb-3">
|
| 537 |
-
<label class="form-label small text-muted mb-2">Subject
|
| 538 |
<div id="subject_pills" class="d-flex flex-wrap gap-2">
|
| 539 |
-
<button type="button" class="btn btn-outline-success subject-pill" data-subject="Biology">
|
| 540 |
-
|
| 541 |
-
</button>
|
| 542 |
-
<button type="button" class="btn btn-outline-
|
| 543 |
-
<i class="bi bi-droplet me-1"></i>Chemistry
|
| 544 |
-
</button>
|
| 545 |
-
<button type="button" class="btn btn-outline-info subject-pill" data-subject="Physics">
|
| 546 |
-
<i class="bi bi-lightning me-1"></i>Physics
|
| 547 |
-
</button>
|
| 548 |
-
<button type="button" class="btn btn-outline-danger subject-pill" data-subject="Mathematics">
|
| 549 |
-
<i class="bi bi-calculator me-1"></i>Mathematics
|
| 550 |
-
</button>
|
| 551 |
</div>
|
| 552 |
</div>
|
| 553 |
|
|
@@ -1599,7 +1584,7 @@
|
|
| 1599 |
chipsContainer.innerHTML = '';
|
| 1600 |
matches.forEach(suggestion => {
|
| 1601 |
const chip = document.createElement('button');
|
| 1602 |
-
chip.className = 'btn btn-outline-info btn-sm rounded-
|
| 1603 |
chip.innerText = suggestion;
|
| 1604 |
chip.onclick = () => { input.value = suggestion; container.classList.add('d-none'); };
|
| 1605 |
chipsContainer.appendChild(chip);
|
|
@@ -2008,7 +1993,7 @@
|
|
| 2008 |
|
| 2009 |
result.suggestions.forEach(suggestion => {
|
| 2010 |
const chip = document.createElement('button');
|
| 2011 |
-
chip.className = 'btn btn-outline-info btn-sm rounded-
|
| 2012 |
chip.innerText = suggestion;
|
| 2013 |
chip.onclick = () => {
|
| 2014 |
document.getElementById('topic_input').value = suggestion;
|
|
|
|
| 35 |
border: 1px solid var(--border-subtle);
|
| 36 |
background: transparent;
|
| 37 |
color: #fff;
|
| 38 |
+
border-radius: 4px;
|
| 39 |
cursor: pointer;
|
| 40 |
transition: all var(--transition-fast);
|
| 41 |
}
|
| 42 |
.status-btn.active { background: var(--accent-primary); border-color: var(--accent-primary); }
|
| 43 |
+
.status-btn:hover { background: var(--bg-hover); }
|
| 44 |
.auto-extract-btn { min-width: 120px; }
|
| 45 |
|
| 46 |
/* Subject pills */
|
| 47 |
.subject-pill {
|
| 48 |
transition: all var(--transition-fast);
|
| 49 |
+
border-radius: 4px;
|
| 50 |
}
|
| 51 |
.subject-pill.active {
|
| 52 |
+
box-shadow: 0 0 8px rgba(255,255,255,0.2);
|
|
|
|
| 53 |
}
|
| 54 |
|
| 55 |
/* Range toggles */
|
| 56 |
.range-toggle {
|
| 57 |
transition: all var(--transition-fast);
|
| 58 |
+
border-radius: 4px;
|
| 59 |
}
|
| 60 |
.range-toggle:hover {
|
| 61 |
+
background: var(--bg-hover);
|
| 62 |
}
|
| 63 |
+
.range-toggle.active { box-shadow: 0 0 4px rgba(255,255,255,0.1); }
|
| 64 |
.range-toggle.active.btn-outline-primary { background: var(--accent-primary); color: #fff; }
|
| 65 |
.range-toggle.active.btn-outline-warning { background: var(--accent-warning); color: #000; }
|
| 66 |
.range-toggle.active.btn-outline-danger { background: var(--accent-danger); color: #fff; }
|
|
|
|
| 68 |
.range-toggle.active.btn-outline-info { background: var(--accent-info); color: #000; }
|
| 69 |
|
| 70 |
/* Range slider styling */
|
| 71 |
+
.range-slider-row { background: var(--bg-elevated); border-radius: 4px; padding: 12px; margin-bottom: 10px; transition: all var(--transition-fast); }
|
| 72 |
.range-slider-row:hover { background: var(--bg-hover); }
|
| 73 |
.dual-range-container { position: relative; height: 40px; }
|
| 74 |
+
.dual-range-track { position: absolute; top: 50%; left: 0; right: 0; height: 8px; background: var(--border-subtle); border-radius: 2px; transform: translateY(-50%); }
|
| 75 |
+
.dual-range-highlight { position: absolute; top: 50%; height: 8px; background: var(--accent-primary); border-radius: 2px; transform: translateY(-50%); }
|
| 76 |
.dual-range-container input[type="range"] { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: none; background: transparent; pointer-events: none; }
|
| 77 |
+
.dual-range-container input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 24px; background: #fff; border: 2px solid var(--accent-primary); border-radius: 2px; cursor: pointer; pointer-events: auto; box-shadow: var(--shadow-sm); }
|
| 78 |
+
.dual-range-container input[type="range"]::-webkit-slider-thumb:hover { background: var(--accent-info); }
|
| 79 |
+
.dual-range-container input[type="range"]::-moz-range-thumb { width: 16px; height: 24px; background: #fff; border: 2px solid var(--accent-primary); border-radius: 2px; cursor: pointer; pointer-events: auto; box-shadow: var(--shadow-sm); }
|
| 80 |
|
| 81 |
/* Tom Select Dark Theme */
|
| 82 |
.ts-wrapper .ts-control, .ts-wrapper .ts-control input {
|
|
|
|
| 101 |
|
| 102 |
/* --- UNIFIED NOTE CARD STYLES --- */
|
| 103 |
.note-card {
|
| 104 |
+
background: rgba(13, 202, 240, 0.05);
|
| 105 |
+
border: 1px solid rgba(13, 202, 240, 0.2);
|
| 106 |
+
border-radius: 4px;
|
| 107 |
padding: 10px;
|
| 108 |
margin-bottom: 8px;
|
| 109 |
transition: all var(--transition-fast);
|
| 110 |
}
|
| 111 |
.note-card:hover {
|
| 112 |
border-color: var(--accent-info);
|
|
|
|
| 113 |
}
|
| 114 |
.note-thumbnail {
|
| 115 |
max-height: 80px;
|
| 116 |
object-fit: contain;
|
| 117 |
+
border-radius: 4px;
|
| 118 |
+
border: 1px solid rgba(13, 202, 240, 0.2);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
}
|
| 120 |
.note-actions {
|
| 121 |
display: flex;
|
|
|
|
| 131 |
|
| 132 |
/* --- UNIFIED BUTTON STYLES --- */
|
| 133 |
.btn-pill {
|
| 134 |
+
border-radius: 4px;
|
| 135 |
font-weight: 500;
|
| 136 |
transition: all var(--transition-fast);
|
| 137 |
}
|
| 138 |
.btn-pill:hover {
|
|
|
|
| 139 |
box-shadow: var(--shadow-sm);
|
| 140 |
}
|
| 141 |
</style>
|
|
|
|
| 414 |
<div class="modal fade" id="manualClassificationModal" tabindex="-1">
|
| 415 |
<div class="modal-dialog modal-lg">
|
| 416 |
<div class="modal-content bg-dark text-white">
|
| 417 |
+
<div class="modal-header border-secondary" style="background: var(--bg-card);">
|
| 418 |
<h5 class="modal-title"><i class="bi bi-list-check me-2"></i>Quick Classification</h5>
|
| 419 |
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
| 420 |
</div>
|
|
|
|
| 509 |
<div class="modal fade" id="topicSelectionModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
|
| 510 |
<div class="modal-dialog modal-lg modal-dialog-centered">
|
| 511 |
<div class="modal-content bg-dark text-white border-secondary">
|
| 512 |
+
<div class="modal-header border-secondary py-2" style="background: var(--bg-card);">
|
| 513 |
<div class="d-flex align-items-center gap-3">
|
| 514 |
<span class="badge bg-primary fs-6" id="topic_q_num">#1</span>
|
| 515 |
<div class="progress flex-grow-1" style="width: 150px; height: 6px;">
|
| 516 |
+
<div class="progress-bar" id="topic_progress_bar" role="progressbar" style="width: 0%; background: var(--accent-primary);"></div>
|
| 517 |
</div>
|
| 518 |
<small id="topic_progress" class="text-muted">1/10</small>
|
| 519 |
</div>
|
|
|
|
| 527 |
|
| 528 |
<!-- Subject Selection (Auto-detected, editable) -->
|
| 529 |
<div class="mb-3">
|
| 530 |
+
<label class="form-label small text-muted mb-2">Subject</label>
|
| 531 |
<div id="subject_pills" class="d-flex flex-wrap gap-2">
|
| 532 |
+
<button type="button" class="btn btn-sm btn-outline-success subject-pill" data-subject="Biology">Biology</button>
|
| 533 |
+
<button type="button" class="btn btn-sm btn-outline-warning subject-pill" data-subject="Chemistry">Chemistry</button>
|
| 534 |
+
<button type="button" class="btn btn-sm btn-outline-info subject-pill" data-subject="Physics">Physics</button>
|
| 535 |
+
<button type="button" class="btn btn-sm btn-outline-danger subject-pill" data-subject="Mathematics">Maths</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 536 |
</div>
|
| 537 |
</div>
|
| 538 |
|
|
|
|
| 1584 |
chipsContainer.innerHTML = '';
|
| 1585 |
matches.forEach(suggestion => {
|
| 1586 |
const chip = document.createElement('button');
|
| 1587 |
+
chip.className = 'btn btn-outline-info btn-sm rounded-1';
|
| 1588 |
chip.innerText = suggestion;
|
| 1589 |
chip.onclick = () => { input.value = suggestion; container.classList.add('d-none'); };
|
| 1590 |
chipsContainer.appendChild(chip);
|
|
|
|
| 1993 |
|
| 1994 |
result.suggestions.forEach(suggestion => {
|
| 1995 |
const chip = document.createElement('button');
|
| 1996 |
+
chip.className = 'btn btn-outline-info btn-sm rounded-1';
|
| 1997 |
chip.innerText = suggestion;
|
| 1998 |
chip.onclick = () => {
|
| 1999 |
document.getElementById('topic_input').value = suggestion;
|