frontPanel/src/pages/PersonalizationAI/PersonalizationAI.tsx

195 lines
7.1 KiB
TypeScript
Raw Normal View History

import { Box, Container, Typography, TextField, Button, List, ListItem, IconButton, Modal } from "@mui/material";
2025-05-25 13:21:19 +00:00
import { InfoPopover } from '@ui_kit/InfoPopover';
import GenderAndAgeSelector from "./GenderAndAgeSelector";
import { useEffect, useState } from "react";
2025-05-25 13:21:19 +00:00
import CustomTextField from "@ui_kit/CustomTextField";
import { useTheme } from "@mui/material";
import { AuditoryItem, auditoryAdd, auditoryDelete, auditoryGet } from "@/api/auditory";
import { useCurrentQuiz } from "@/stores/quizes/hooks";
import { AuditoryList } from "./AuditoryList";
2025-06-01 21:36:55 +00:00
import { useSnackbar } from "notistack";
2025-05-25 13:21:19 +00:00
export default function PersonalizationAI() {
const theme = useTheme();
const [auditory, setAuditory] = useState<AuditoryItem[]>([]);
const [deleteModal, setDeleteModal] = useState<number>(0);
2025-06-01 22:48:35 +00:00
const [link, setLink] = useState<string>('');
const [utmParams, setUtmParams] = useState<string>('');
const quiz = useCurrentQuiz();
2025-06-01 21:36:55 +00:00
const { enqueueSnackbar } = useSnackbar();
useEffect(() => {
(async () => {
if (quiz?.backendId) {
const [result, error] = await auditoryGet({ quizId: quiz.backendId });
console.log("result-___---_------__---__-__---_------__---__-__---_------__---__-__---_------__---__-____--__")
console.log(result)
if (result) {
setAuditory(result);
}
}
})();
}, [quiz]);
2025-06-01 21:36:55 +00:00
const handleDelete = async () => {
// 1. Закрываем модалку
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;
});
}
}
2025-05-25 13:21:19 +00:00
2025-06-01 22:02:43 +00:00
const handleAdd = (item:AuditoryItem) => {
setAuditory(old => ([...old, item]))
}
2025-06-01 22:48:35 +00:00
const handleLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newLink = e.target.value;
setLink(newLink);
// Регулярное выражение для поиска параметров URL
const paramRegex = /[?&]([^=&]+)=([^&]*)/g;
const params: Record<string, string> = {};
let match;
// Ищем все параметры в строке
while ((match = paramRegex.exec(newLink)) !== null) {
const key = decodeURIComponent(match[1]);
const value = decodeURIComponent(match[2]);
params[key] = value;
}
// Преобразуем объект параметров в строку URL
const paramString = Object.entries(params)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&');
setUtmParams(paramString);
};
2025-05-25 13:21:19 +00:00
return (
<>
2025-06-01 22:02:43 +00:00
<Container id="PersonalizationAI" maxWidth={false} sx={{ minHeight: "100%", p: "20px", height: " calc(100vh - 80px)", overflow: "auto", pt: "55px"}}>
<Typography variant="h5" color={theme.palette.grey3.main} fontWeight={700} sx={{ fontSize: 24, letterSpacing: "-0.2px" }}>
Персонализация вопросов с помощью AI
</Typography>
<Typography sx={{
color: theme.palette.grey3.main, fontSize: "18px", maxWidth: 796, m: 0,
mt: "19px",
letterSpacing: "0.009px",
wordSpacing: "0.1px",
lineHeight: "21.4px"
}}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</Typography>
2025-05-25 13:21:19 +00:00
{/* Первый белый блок */}
<Box sx={{
bgcolor: "#fff",
borderRadius: "12px",
mt: "40px",
p: "20px 20px 30px",
boxShadow: "none",
maxWidth: "796px"
}}>
2025-06-01 22:02:43 +00:00
<GenderAndAgeSelector handleAdd={handleAdd} />
2025-05-25 13:21:19 +00:00
{/* Ссылка */}
<Box sx={{ mt: "34px" }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
<Typography sx={{ color: theme.palette.grey3.main, fontSize: "18px", fontWeight: 500 }}>Ссылка</Typography>
<InfoPopover />
</Box>
<Typography
sx={{
fontSize: "14px",
lineHeight: "100%",
letterSpacing: "0 %",
color: theme.palette.grey2.main,
mt: "16px"
}}
>
Вставьте ссылку со всеми utm-метками
</Typography>
2025-05-25 13:21:19 +00:00
<CustomTextField
placeholder="linkexample.com"
2025-06-01 22:48:35 +00:00
maxLength={500}
value={link}
onChange={handleLinkChange}
2025-05-25 13:21:19 +00:00
sxForm={{
width: "615px",
}}
/>
</Box>
</Box>
2025-06-01 22:48:35 +00:00
<AuditoryList utmParams={utmParams} onDelete={setDeleteModal} auditory={auditory} />
2025-05-25 13:21:19 +00:00
</Container>
<Modal
open={Boolean(deleteModal)}
onClose={() => setDeleteModal(0)}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box
sx={{
position: "absolute" as "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
maxWidth: "620px",
width: "100%",
bgcolor: "background.paper",
borderRadius: "12px",
boxShadow: 24,
p: "20px",
display: "flex",
flexDirection: "column",
alignItems: "center"
}}
>
<Typography sx={{ width: "100%" ,textAlign: "center", mb: "25px"}}>Уверены, что хотите удалить ссылку?</Typography>
<Button sx={{mb: "20px"}} onClick={handleDelete}>Удалить</Button>
<Button variant="contained" onClick={() => setDeleteModal(0)} >Отмена</Button>
</Box>
</Modal>
</>
2025-05-25 13:21:19 +00:00
);
}