Files
LiquidCode_Frontend/src/views/home/articles/ArticleItem.tsx
Виталий Лавшонок 02de330034 add filters
2025-12-10 00:04:20 +03:00

112 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useNavigate } from 'react-router-dom';
import { cn } from '../../../lib/cn';
import { useAppSelector } from '../../../redux/hooks';
export interface ArticleItemProps {
id: number;
name: string;
tags: string[];
}
const ArticleItem: React.FC<ArticleItemProps> = ({ id, name, tags }) => {
const navigate = useNavigate();
const filterTags = useAppSelector(
(state) => state.store.articles.articleTagFilter,
);
const nameFilter = useAppSelector(
(state) => state.store.articles.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;
};
return (
<div
className={cn(
'w-full relative rounded-[10px] text-liquid-white mb-[20px]',
// type == "first" ? "bg-liquid-lighter" : "bg-liquid-background",
'gap-[20px] px-[20px] py-[10px] box-border ',
'border-b-[1px] border-b-liquid-lighter cursor-pointer hover:bg-liquid-lighter transition-all duration-300',
)}
onClick={() => {
navigate(`/article/${id}`);
}}
>
<div className="h-[23px] flex ">
<div className="text-[18px] font-bold w-[60px] mr-[20px] flex items-center">
#{id}
</div>
<div className="text-[18px] font-bold flex items-center bg-red-400r">
{highlightZ(name, nameFilter)}
</div>
</div>
<div className="text-[14px] flex text-liquid-light gap-[10px] mt-[10px]">
{tags.map((v, i) => (
<div
key={i}
className={cn(
'rounded-full px-[16px] py-[8px] bg-liquid-lighter',
v == 'Sertificated' && 'text-liquid-green',
filterTags.includes(v) &&
'border-liquid-brightmain border-[1px] border-solid text-liquid-brightmain',
)}
>
{v}
</div>
))}
</div>
</div>
);
};
export default ArticleItem;