feat: Long An SQL presets, clickable search examples

- custom-query: two new presets filtered by Long An (SBD prefix 49):
  Top 10 điểm Toán, Top 100 khối A (Toán+Lý+Hóa)
- search-form: show clickable example pills ("49008235" /
  "Nguyễn Minh Tiến") next to the empty-state hint; clicking fills
  the input and triggers the debounced live search
- App.css: .example-btn pill styling matching preset buttons
This commit is contained in:
2026-04-14 22:21:54 +07:00
parent 8a43f7214f
commit 8cfc9116fb
3 changed files with 56 additions and 0 deletions
+19
View File
@@ -322,6 +322,25 @@ header h1 {
color: var(--score-weak-accent);
}
.example-btn {
display: inline-block;
padding: 0.1rem 0.5rem;
font-size: 0.8rem;
font-family: inherit;
background: var(--surface-alt);
color: var(--text);
border: 1px solid var(--border);
border-radius: 999px;
cursor: pointer;
transition: background 0.15s, border-color 0.15s;
}
.example-btn:hover {
background: var(--primary);
color: var(--primary-ink);
border-color: var(--primary);
}
/* Loading */
.loading {
text-align: center;
+16
View File
@@ -20,6 +20,22 @@ ORDER BY khtn DESC LIMIT 10`,
sql: `SELECT so_bao_danh, ho_ten, lich_su, dia_ly, gdcd, khxh
FROM student WHERE khxh IS NOT NULL
ORDER BY khxh DESC LIMIT 10`,
},
{
label: "Top 10 điểm Toán - Long An",
sql: `SELECT so_bao_danh, ho_ten, ngay_sinh, toan
FROM student
WHERE so_bao_danh LIKE '49%' AND toan IS NOT NULL
ORDER BY toan DESC LIMIT 10`,
},
{
label: "Top 100 khối A - Long An",
sql: `SELECT so_bao_danh, ho_ten, toan, vat_ly, hoa_hoc,
ROUND(toan + vat_ly + hoa_hoc, 2) AS tong_khoi_a
FROM student
WHERE so_bao_danh LIKE '49%'
AND toan IS NOT NULL AND vat_ly IS NOT NULL AND hoa_hoc IS NOT NULL
ORDER BY tong_khoi_a DESC LIMIT 100`,
},
{
label: "Thí sinh đạt 9+ điểm Toán",
+21
View File
@@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from "react";
const DEBOUNCE_MS = 300;
const MIN_SBD_DIGITS = 3;
const MIN_NAME_CHARS = 2;
const EXAMPLES = ["49008235", "Nguyễn Minh Tiến"];
// Detect input mode for dynamic hint shown under the field
function detectMode(raw) {
@@ -92,6 +93,26 @@ export function SearchForm({ onSearch, onClear, disabled }) {
</div>
<p id="search-hint" className={`search-hint mode-${mode}`} aria-live="polite">
{hint}
{mode === "empty" && (
<>
{" · VD: "}
{EXAMPLES.map((ex, i) => (
<span key={ex}>
<button
type="button"
className="example-btn"
onClick={() => {
setQuery(ex);
inputRef.current?.focus();
}}
>
{ex}
</button>
{i < EXAMPLES.length - 1 ? " hoặc " : ""}
</span>
))}
</>
)}
</p>
</form>
);