реактивное удаление
This commit is contained in:
parent
e7121cb06a
commit
1e8a50077b
@ -2,17 +2,16 @@ import { AuditoryItem } from "@/api/auditory";
|
|||||||
import CopyIcon from "@/assets/icons/CopyIcon";
|
import CopyIcon from "@/assets/icons/CopyIcon";
|
||||||
import Trash from "@/assets/icons/trash";
|
import Trash from "@/assets/icons/trash";
|
||||||
import { InfoPopover } from "@/ui_kit/InfoPopover";
|
import { InfoPopover } from "@/ui_kit/InfoPopover";
|
||||||
import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo";
|
|
||||||
import { useDomainDefine } from "@/utils/hooks/useDomainDefine";
|
import { useDomainDefine } from "@/utils/hooks/useDomainDefine";
|
||||||
import { IconButton, ListItem, Typography, useTheme } from "@mui/material";
|
import { IconButton, ListItem, Typography, useTheme } from "@mui/material";
|
||||||
|
|
||||||
interface AuditoryLinkProps {
|
interface AuditoryLinkProps {
|
||||||
item: AuditoryItem;
|
item: AuditoryItem;
|
||||||
index: number;
|
index: number;
|
||||||
deleteModal: (id:number) => void
|
onDelete: (id: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuditoryLink = ({ item, index, deleteModal }: AuditoryLinkProps) => {
|
export const AuditoryLink = ({ item, index, onDelete }: AuditoryLinkProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { isTestServer } = useDomainDefine();
|
const { isTestServer } = useDomainDefine();
|
||||||
|
|
||||||
@ -20,6 +19,10 @@ export const AuditoryLink = ({ item, index, deleteModal }: AuditoryLinkProps) =>
|
|||||||
navigator.clipboard.writeText(text);
|
navigator.clipboard.writeText(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDelete = () => {
|
||||||
|
onDelete(item.id);
|
||||||
|
};
|
||||||
|
|
||||||
const linkText = `${isTestServer ? "https://s.hbpn.link/" : "https://hbpn.link/"}?_paud=${item.id}`;
|
const linkText = `${isTestServer ? "https://s.hbpn.link/" : "https://hbpn.link/"}?_paud=${item.id}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -39,13 +42,18 @@ export const AuditoryLink = ({ item, index, deleteModal }: AuditoryLinkProps) =>
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '12px',
|
gap: '12px',
|
||||||
width: "70px",
|
width: "60px",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
secondaryAction={
|
secondaryAction={
|
||||||
<>
|
<>
|
||||||
<IconButton onClick={() => deleteModal(item.id)} edge="end" aria-label="info" sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}>
|
<IconButton
|
||||||
|
edge="end"
|
||||||
|
aria-label="delete"
|
||||||
|
sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}
|
||||||
|
onClick={handleDelete}
|
||||||
|
>
|
||||||
<Trash sx={{
|
<Trash sx={{
|
||||||
"& path": {
|
"& path": {
|
||||||
stroke: theme.palette.brightPurple.main,
|
stroke: theme.palette.brightPurple.main,
|
||||||
@ -53,11 +61,11 @@ export const AuditoryLink = ({ item, index, deleteModal }: AuditoryLinkProps) =>
|
|||||||
}} />
|
}} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton edge="end" aria-label="info" sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}>
|
<IconButton edge="end" aria-label="info" sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}>
|
||||||
<TooltipClickInfo title={`Возраст: ${item.age}\n Пол: ${item.sex ? "мужской" : "женский"}`} />
|
<InfoPopover />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton
|
||||||
edge="end"
|
edge="end"
|
||||||
aria-label="copy"
|
aria-label="copy"
|
||||||
sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18, marginRight: "-2px" }}
|
sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18, marginRight: "-2px" }}
|
||||||
onClick={() => handleCopy(linkText)}
|
onClick={() => handleCopy(linkText)}
|
||||||
>
|
>
|
||||||
|
@ -6,13 +6,11 @@ import { Box, Collapse, IconButton, List, Typography, useTheme } from "@mui/mate
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { AuditoryLink } from "./AuditoryLink";
|
import { AuditoryLink } from "./AuditoryLink";
|
||||||
|
|
||||||
|
export const AuditoryList = ({auditory, onDelete}:{auditory:AuditoryItem[], onDelete: (id: number) => void}) => {
|
||||||
export const AuditoryList = ({auditory, deleteModal}:{auditory:AuditoryItem[], deleteModal:(id:number) => void}) => {
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { isTestServer } = useDomainDefine();
|
const { isTestServer } = useDomainDefine();
|
||||||
const [linksOpen, setLinksOpen] = useState(true);
|
const [linksOpen, setLinksOpen] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
console.log("auditory-___---_auditory__---__-__auditory_------__---__-__---_------__---__-__---_------__---__-____--__")
|
console.log("auditory-___---_auditory__---__-__auditory_------__---__-__---_------__---__-__---_------__---__-____--__")
|
||||||
console.log(auditory)
|
console.log(auditory)
|
||||||
|
|
||||||
@ -41,7 +39,7 @@ export const AuditoryList = ({auditory, deleteModal}:{auditory:AuditoryItem[], d
|
|||||||
<Collapse in={linksOpen} timeout="auto" unmountOnExit sx={{ mt: "3px" }}>
|
<Collapse in={linksOpen} timeout="auto" unmountOnExit sx={{ mt: "3px" }}>
|
||||||
<List sx={{ gap: '8px', p: 0, m: 0 }}>
|
<List sx={{ gap: '8px', p: 0, m: 0 }}>
|
||||||
{auditory.map((item, idx) => (
|
{auditory.map((item, idx) => (
|
||||||
<AuditoryLink deleteModal={deleteModal} key={idx} item={item} index={idx} />
|
<AuditoryLink key={idx} item={item} index={idx} onDelete={onDelete} />
|
||||||
))}
|
))}
|
||||||
</List>
|
</List>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
@ -10,6 +10,7 @@ import { useTheme } from "@mui/material";
|
|||||||
import { AuditoryItem, auditoryAdd, auditoryDelete, auditoryGet } from "@/api/auditory";
|
import { AuditoryItem, auditoryAdd, auditoryDelete, auditoryGet } from "@/api/auditory";
|
||||||
import { useCurrentQuiz } from "@/stores/quizes/hooks";
|
import { useCurrentQuiz } from "@/stores/quizes/hooks";
|
||||||
import { AuditoryList } from "./AuditoryList";
|
import { AuditoryList } from "./AuditoryList";
|
||||||
|
import { useSnackbar } from "notistack";
|
||||||
|
|
||||||
|
|
||||||
export default function PersonalizationAI() {
|
export default function PersonalizationAI() {
|
||||||
@ -18,6 +19,7 @@ export default function PersonalizationAI() {
|
|||||||
const [auditory, setAuditory] = useState<AuditoryItem[]>([]);
|
const [auditory, setAuditory] = useState<AuditoryItem[]>([]);
|
||||||
const [deleteModal, setDeleteModal] = useState<number>(0);
|
const [deleteModal, setDeleteModal] = useState<number>(0);
|
||||||
const quiz = useCurrentQuiz();
|
const quiz = useCurrentQuiz();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@ -32,9 +34,45 @@ export default function PersonalizationAI() {
|
|||||||
})();
|
})();
|
||||||
}, [quiz]);
|
}, [quiz]);
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = async () => {
|
||||||
setDeleteModal(0)
|
// 1. Закрываем модалку
|
||||||
auditoryDelete({ quizId: quiz?.backendId, auditoryId: deleteModal })
|
setDeleteModal(0);
|
||||||
|
|
||||||
|
// 2. Находим индекс объекта в стейте
|
||||||
|
const indexToDelete = auditory.findIndex(item => item.id === deleteModal);
|
||||||
|
if (indexToDelete === -1) return;
|
||||||
|
|
||||||
|
// 3. Сохраняем удаляемый объект
|
||||||
|
const deletedItem = auditory[indexToDelete];
|
||||||
|
|
||||||
|
// 4. Меняем стейт, вырезая объект
|
||||||
|
setAuditory(prev => prev.filter(item => item.id !== deleteModal));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 5. Вызываем функцию удаления
|
||||||
|
const [result, error] = await auditoryDelete({
|
||||||
|
quizId: quiz?.backendId,
|
||||||
|
auditoryId: deleteModal
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
// 6. Если удалить не удалось - показываем снекбар и возвращаем ссылку
|
||||||
|
enqueueSnackbar('Не удалось удалить ссылку', { variant: 'error' });
|
||||||
|
setAuditory(prev => {
|
||||||
|
const newArray = [...prev];
|
||||||
|
newArray.splice(indexToDelete, 0, deletedItem);
|
||||||
|
return newArray;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Обработка ошибки сети или других ошибок
|
||||||
|
enqueueSnackbar('Произошла ошибка при удалении', { variant: 'error' });
|
||||||
|
setAuditory(prev => {
|
||||||
|
const newArray = [...prev];
|
||||||
|
newArray.splice(indexToDelete, 0, deletedItem);
|
||||||
|
return newArray;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -92,7 +130,7 @@ export default function PersonalizationAI() {
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<AuditoryList deleteModal={setDeleteModal} auditory={auditory} />
|
<AuditoryList onDelete={setDeleteModal} auditory={auditory} />
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
<Modal
|
<Modal
|
||||||
|
Loading…
Reference in New Issue
Block a user