update articles slice

This commit is contained in:
Виталий Лавшонок
2025-11-13 16:32:32 +03:00
parent 18d17f895d
commit ded41ba7f0
8 changed files with 496 additions and 285 deletions

View File

@@ -3,8 +3,7 @@ import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import { setMenuActiveProfilePage } from '../../../../redux/slices/store';
import { cn } from '../../../../lib/cn';
import { ChevroneDown, Edit } from '../../../../assets/icons/groups';
import { fetchArticles } from '../../../../redux/slices/articles';
import { fetchMyArticles } from '../../../../redux/slices/articles';
import { useNavigate } from 'react-router-dom';
export interface ArticleItemProps {
@@ -13,21 +12,21 @@ export interface ArticleItemProps {
tags: string[];
}
const ArticleItem: React.FC<ArticleItemProps> = ({ id, name, tags }) => {
const ArticleItem: FC<ArticleItemProps> = ({ id, name, tags }) => {
const navigate = useNavigate();
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 ',
'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}?back=/home/account/articles`);
}}
onClick={() =>
navigate(`/article/${id}?back=/home/account/articles`)
}
>
<div className="h-[23px] flex ">
<div className="h-[23px] flex">
<div className="text-[18px] font-bold w-[60px] mr-[20px] flex items-center">
#{id}
</div>
@@ -35,13 +34,14 @@ const ArticleItem: React.FC<ArticleItemProps> = ({ id, name, tags }) => {
{name}
</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',
v === 'Sertificated' && 'text-liquid-green',
)}
>
{v}
@@ -50,8 +50,9 @@ const ArticleItem: React.FC<ArticleItemProps> = ({ id, name, tags }) => {
</div>
<img
className=" absolute right-[10px] top-[10px] h-[24px] w-[24px] hover:bg-liquid-light rounded-[5px] transition-all duration-300"
className="absolute right-[10px] top-[10px] h-[24px] w-[24px] hover:bg-liquid-light rounded-[5px] transition-all duration-300"
src={Edit}
alt="Редактировать"
onClick={(e) => {
e.stopPropagation();
navigate(
@@ -69,49 +70,79 @@ interface ArticlesBlockProps {
const ArticlesBlock: FC<ArticlesBlockProps> = ({ className = '' }) => {
const dispatch = useAppDispatch();
const articles = useAppSelector((state) => state.articles.articles);
const [active, setActive] = useState<boolean>(true);
// ✅ Берём только "мои статьи"
const articles = useAppSelector(
(state) => state.articles.fetchMyArticles.articles,
);
const status = useAppSelector(
(state) => state.articles.fetchMyArticles.status,
);
const error = useAppSelector(
(state) => state.articles.fetchMyArticles.error,
);
useEffect(() => {
dispatch(setMenuActiveProfilePage('articles'));
dispatch(fetchArticles({}));
}, []);
dispatch(fetchMyArticles());
}, [dispatch]);
return (
<div className="h-full w-full relative p-[20px]">
<div
className={cn(
' border-b-[1px] border-b-liquid-lighter rounded-[10px]',
'border-b-[1px] border-b-liquid-lighter rounded-[10px]',
className,
)}
>
{/* Заголовок */}
<div
className={cn(
' h-[40px] text-[24px] font-bold flex gap-[10px] border-b-[1px] border-b-transparent items-center cursor-pointer transition-all duration-300',
active && ' border-b-liquid-lighter',
'h-[40px] text-[24px] font-bold flex gap-[10px] border-b-[1px] border-b-transparent items-center cursor-pointer transition-all duration-300',
active && 'border-b-liquid-lighter',
)}
onClick={() => {
setActive(!active);
}}
onClick={() => setActive(!active)}
>
<span>Мои статьи</span>
<img
src={ChevroneDown}
alt="toggle"
className={cn(
'transition-all duration-300',
active && 'rotate-180',
)}
/>
</div>
{/* Контент */}
<div
className={cn(
' grid grid-flow-row grid-rows-[0fr] opacity-0 transition-all duration-300',
'grid grid-flow-row grid-rows-[0fr] opacity-0 transition-all duration-300',
active && 'grid-rows-[1fr] opacity-100',
)}
>
<div className="overflow-hidden">
<div className="grid gap-[20px] pt-[20px] pb-[20px] box-border">
{articles.map((v, i) => (
<ArticleItem key={i} {...v} />
{status === 'loading' && (
<div className="text-liquid-light">
Загрузка статей...
</div>
)}
{status === 'failed' && (
<div className="text-liquid-red">
Ошибка:{' '}
{error || 'Не удалось загрузить статьи'}
</div>
)}
{status === 'successful' &&
articles.length === 0 && (
<div className="text-liquid-light">
У вас пока нет статей
</div>
)}
{articles.map((v) => (
<ArticleItem key={v.id} {...v} />
))}
</div>
</div>