add filters
This commit is contained in:
@@ -83,6 +83,61 @@ const PastContestItem: React.FC<PastContestItemProps> = ({
|
||||
(state) => state.contests.fetchParticipating,
|
||||
);
|
||||
|
||||
const nameFilter = useAppSelector(
|
||||
(state) => state.store.contests.filterName,
|
||||
);
|
||||
|
||||
const highlightZ = (name: string, filter: string) => {
|
||||
if (!filter) return name;
|
||||
|
||||
const s = filter.toLowerCase();
|
||||
const t = name.toLowerCase();
|
||||
const n = t.length;
|
||||
const m = s.length;
|
||||
|
||||
const mark = Array(n).fill(false);
|
||||
|
||||
// Проходимся с конца и ставим отметки
|
||||
for (let i = n - 1; i >= 0; i--) {
|
||||
if (i + m <= n && t.slice(i, i + m) === s) {
|
||||
for (let j = i; j < i + m; j++) {
|
||||
if (mark[j]) break;
|
||||
mark[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === Формируем единые жёлтые блоки ===
|
||||
const result: any[] = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < n) {
|
||||
if (!mark[i]) {
|
||||
// обычный символ
|
||||
result.push(name[i]);
|
||||
i++;
|
||||
} else {
|
||||
// начинаем жёлтый блок
|
||||
let j = i;
|
||||
while (j < n && mark[j]) j++;
|
||||
|
||||
const chunk = name.slice(i, j);
|
||||
result.push(
|
||||
<span
|
||||
key={i}
|
||||
className="bg-yellow-400 text-black rounded px-1"
|
||||
>
|
||||
{chunk}
|
||||
</span>,
|
||||
);
|
||||
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setRole(
|
||||
(() => {
|
||||
@@ -119,7 +174,9 @@ const PastContestItem: React.FC<PastContestItemProps> = ({
|
||||
navigate(`/contest/${contestId}?${params}`);
|
||||
}}
|
||||
>
|
||||
<div className="text-left font-bold text-[18px]">{name}</div>
|
||||
<div className="text-left font-bold text-[18px]">
|
||||
{highlightZ(name, nameFilter)}
|
||||
</div>
|
||||
<div className="text-center text-liquid-brightmain font-normal flex items-center justify-center">
|
||||
{username}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user