удаление без реактивности, выведен корректный список линков
This commit is contained in:
parent
c2d79c04cc
commit
e7121cb06a
@ -47,13 +47,13 @@ export interface AuditoryAddParams {
|
||||
}
|
||||
|
||||
// API calls
|
||||
export const auditoryGet = async ({ quizId }: AuditoryGetParams): Promise<[AuditoryResponse | null, string?]> => {
|
||||
export const auditoryGet = async ({ quizId }: AuditoryGetParams): Promise<[AuditoryItem[] | null, string?]> => {
|
||||
if (!quizId) {
|
||||
return [null, "Quiz ID is required"];
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await makeRequest<AuditoryGetRequest, AuditoryResponse>({
|
||||
const response = await makeRequest<AuditoryGetRequest, AuditoryItem[]>({
|
||||
url: `${API_URL}/quiz/${quizId}/auditory`,
|
||||
method: "GET",
|
||||
});
|
||||
@ -72,10 +72,7 @@ export const auditoryDelete = async ({ quizId, auditoryId }: AuditoryDeleteParam
|
||||
|
||||
try {
|
||||
const response = await makeRequest<AuditoryDeleteRequest, AuditoryResponse>({
|
||||
url: `${API_URL}/quiz/${quizId}/auditory`,
|
||||
body: {
|
||||
id: auditoryId
|
||||
},
|
||||
url: `${API_URL}/quiz/${quizId}/auditory/${auditoryId}`,
|
||||
method: "DELETE",
|
||||
});
|
||||
|
||||
|
74
src/pages/PersonalizationAI/AuditoryLink.tsx
Normal file
74
src/pages/PersonalizationAI/AuditoryLink.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import { AuditoryItem } from "@/api/auditory";
|
||||
import CopyIcon from "@/assets/icons/CopyIcon";
|
||||
import Trash from "@/assets/icons/trash";
|
||||
import { InfoPopover } from "@/ui_kit/InfoPopover";
|
||||
import TooltipClickInfo from "@/ui_kit/Toolbars/TooltipClickInfo";
|
||||
import { useDomainDefine } from "@/utils/hooks/useDomainDefine";
|
||||
import { IconButton, ListItem, Typography, useTheme } from "@mui/material";
|
||||
|
||||
interface AuditoryLinkProps {
|
||||
item: AuditoryItem;
|
||||
index: number;
|
||||
deleteModal: (id:number) => void
|
||||
}
|
||||
|
||||
export const AuditoryLink = ({ item, index, deleteModal }: AuditoryLinkProps) => {
|
||||
const theme = useTheme();
|
||||
const { isTestServer } = useDomainDefine();
|
||||
|
||||
const handleCopy = (text: string) => {
|
||||
navigator.clipboard.writeText(text);
|
||||
};
|
||||
|
||||
const linkText = `${isTestServer ? "https://s.hbpn.link/" : "https://hbpn.link/"}?_paud=${item.id}`;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={index}
|
||||
disablePadding
|
||||
sx={{
|
||||
bgcolor: "#F2F3F7",
|
||||
borderRadius: "10px",
|
||||
p: "13px 14px 13px 20px",
|
||||
mb: "8px",
|
||||
maxWidth: "756px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
transition: 'background 0.2s, border 0.2s',
|
||||
'& .MuiListItemSecondaryAction-root': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
width: "70px",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
}}
|
||||
secondaryAction={
|
||||
<>
|
||||
<IconButton onClick={() => deleteModal(item.id)} edge="end" aria-label="info" sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18 }}>
|
||||
<Trash sx={{
|
||||
"& path": {
|
||||
stroke: theme.palette.brightPurple.main,
|
||||
}
|
||||
}} />
|
||||
</IconButton>
|
||||
<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 ? "мужской" : "женский"}`} />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
edge="end"
|
||||
aria-label="copy"
|
||||
sx={{ color: theme.palette.brightPurple.main, p: 0, width: 18, height: 18, marginRight: "-2px" }}
|
||||
onClick={() => handleCopy(linkText)}
|
||||
>
|
||||
<CopyIcon color={theme.palette.brightPurple.main} />
|
||||
</IconButton>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Typography sx={{ color: 'black', fontWeight: 400, fontSize: "16px" }}>
|
||||
{linkText}
|
||||
</Typography>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
@ -1,37 +1,17 @@
|
||||
import { auditoryGet, AuditoryResponse, AuditoryItem } from "@/api/auditory";
|
||||
import ArrowDownIcon from "@/assets/icons/ArrowDownIcon";
|
||||
import CopyIcon from "@/assets/icons/CopyIcon";
|
||||
import { useCurrentQuiz } from "@/stores/quizes/hooks";
|
||||
import { InfoPopover } from "@/ui_kit/InfoPopover";
|
||||
import { useDomainDefine } from "@/utils/hooks/useDomainDefine";
|
||||
import { Box, Collapse, IconButton, List, ListItem, Typography, useTheme } from "@mui/material";
|
||||
import { Box, Collapse, IconButton, List, Typography, useTheme } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import { AuditoryLink } from "./AuditoryLink";
|
||||
|
||||
const PURPLE = "#7E2AEA";
|
||||
|
||||
export const AuditoryList = () => {
|
||||
export const AuditoryList = ({auditory, deleteModal}:{auditory:AuditoryItem[], deleteModal:(id:number) => void}) => {
|
||||
const theme = useTheme();
|
||||
const quiz = useCurrentQuiz();
|
||||
const { isTestServer } = useDomainDefine();
|
||||
const [linksOpen, setLinksOpen] = useState(true);
|
||||
const [auditory, setAuditory] = useState<AuditoryItem[]>([]);
|
||||
|
||||
const handleCopy = (text: string) => {
|
||||
navigator.clipboard.writeText(text);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (quiz?.backendId) {
|
||||
const [result, error] = await auditoryGet({ quizId: quiz.backendId });
|
||||
console.log("result-___---_------__---__-__---_------__---__-__---_------__---__-__---_------__---__-____--__")
|
||||
console.log(result)
|
||||
if (result) {
|
||||
setAuditory(result);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [quiz]);
|
||||
|
||||
console.log("auditory-___---_auditory__---__-__auditory_------__---__-__---_------__---__-__---_------__---__-____--__")
|
||||
console.log(auditory)
|
||||
@ -51,7 +31,7 @@ export const AuditoryList = () => {
|
||||
Ваши сохраненные ссылки
|
||||
</Typography>
|
||||
<IconButton
|
||||
sx={{ cursor: 'pointer', color: PURPLE, display: 'flex', alignItems: 'center', transition: 'transform 0.2s', transform: linksOpen ? 'rotate(0deg)' : 'rotate(180deg)' }}
|
||||
sx={{ cursor: 'pointer', color: theme.palette.brightPurple.main, display: 'flex', alignItems: 'center', transition: 'transform 0.2s', transform: linksOpen ? 'rotate(0deg)' : 'rotate(180deg)' }}
|
||||
onClick={() => setLinksOpen((prev) => !prev)}
|
||||
size="large"
|
||||
>
|
||||
@ -60,52 +40,9 @@ export const AuditoryList = () => {
|
||||
</Box>
|
||||
<Collapse in={linksOpen} timeout="auto" unmountOnExit sx={{ mt: "3px" }}>
|
||||
<List sx={{ gap: '8px', p: 0, m: 0 }}>
|
||||
{auditory.map((item, idx) => {
|
||||
const linkText = `${isTestServer ? "https://s.hbpn.link/" : "https://hbpn.link/"}?_paud=${item.id}`;
|
||||
console.log(item)
|
||||
return (
|
||||
<ListItem
|
||||
key={idx}
|
||||
disablePadding
|
||||
sx={{
|
||||
bgcolor: "#F2F3F7",
|
||||
borderRadius: "10px",
|
||||
p: "13px 14px 13px 20px",
|
||||
mb: "8px",
|
||||
maxWidth: "756px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
transition: 'background 0.2s, border 0.2s',
|
||||
'& .MuiListItemSecondaryAction-root': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
width: "60px",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
}}
|
||||
secondaryAction={
|
||||
<>
|
||||
<IconButton edge="end" aria-label="info" sx={{ color: PURPLE, p: 0, width: 18, height: 18 }}>
|
||||
<InfoPopover />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
edge="end"
|
||||
aria-label="copy"
|
||||
sx={{ color: PURPLE, p: 0, width: 18, height: 18, marginRight: "-2px" }}
|
||||
onClick={() => handleCopy(linkText)}
|
||||
>
|
||||
<CopyIcon color={PURPLE} />
|
||||
</IconButton>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Typography sx={{ color: 'black', fontWeight: 400, fontSize: "16px" }}>
|
||||
{linkText}
|
||||
</Typography>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
{auditory.map((item, idx) => (
|
||||
<AuditoryLink deleteModal={deleteModal} key={idx} item={item} index={idx} />
|
||||
))}
|
||||
</List>
|
||||
</Collapse>
|
||||
</Box>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, Select, MenuItem, useTheme } from "@mui/material";
|
||||
import { Box, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, Select, MenuItem, useTheme, Button } from "@mui/material";
|
||||
import { InfoPopover } from '@ui_kit/InfoPopover';
|
||||
import CheckboxIcon from "@icons/Checkbox";
|
||||
|
||||
@ -7,6 +7,7 @@ interface GenderAndAgeSelectorProps {
|
||||
setGender: (gender: string) => void;
|
||||
}
|
||||
|
||||
|
||||
export default function GenderAndAgeSelector({ gender, setGender }: GenderAndAgeSelectorProps) {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
@ -167,6 +168,21 @@ export default function GenderAndAgeSelector({ gender, setGender }: GenderAndAge
|
||||
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{
|
||||
bgcolor: theme.palette.brightPurple.main,
|
||||
borderRadius: "8px",
|
||||
width: "130px",
|
||||
height: "48px",
|
||||
boxShadow: "none",
|
||||
textTransform: "none",
|
||||
fontSize: "18px",
|
||||
'&:hover': { bgcolor: theme.palette.brightPurple.main },
|
||||
}}
|
||||
>
|
||||
Ок
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Box, Container, Typography, TextField, Button, List, ListItem, IconButton } from "@mui/material";
|
||||
import { Box, Container, Typography, TextField, Button, List, ListItem, IconButton, Modal } from "@mui/material";
|
||||
import { InfoPopover } from '@ui_kit/InfoPopover';
|
||||
import CopyIcon from "@/assets/icons/CopyIcon";
|
||||
import GenderAndAgeSelector from "./GenderAndAgeSelector";
|
||||
@ -7,17 +7,38 @@ import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import Collapse from '@mui/material/Collapse';
|
||||
import { ArrowDownIcon } from "../../assets/icons/questionsPage/ArrowDownIcon";
|
||||
import { useTheme } from "@mui/material";
|
||||
import { auditoryAdd, auditoryGet } from "@/api/auditory";
|
||||
import { AuditoryItem, auditoryAdd, auditoryDelete, auditoryGet } from "@/api/auditory";
|
||||
import { useCurrentQuiz } from "@/stores/quizes/hooks";
|
||||
import { AuditoryList } from "./AuditoryList";
|
||||
|
||||
const PURPLE = "#7E2AEA";
|
||||
|
||||
export default function PersonalizationAI() {
|
||||
const theme = useTheme();
|
||||
const [gender, setGender] = useState('');
|
||||
const [auditory, setAuditory] = useState<AuditoryItem[]>([]);
|
||||
const [deleteModal, setDeleteModal] = useState<number>(0);
|
||||
const quiz = useCurrentQuiz();
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (quiz?.backendId) {
|
||||
const [result, error] = await auditoryGet({ quizId: quiz.backendId });
|
||||
console.log("result-___---_------__---__-__---_------__---__-__---_------__---__-__---_------__---__-____--__")
|
||||
console.log(result)
|
||||
if (result) {
|
||||
setAuditory(result);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [quiz]);
|
||||
|
||||
const handleDelete = () => {
|
||||
setDeleteModal(0)
|
||||
auditoryDelete({ quizId: quiz?.backendId, auditoryId: deleteModal })
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container id="PersonalizationAI" maxWidth={false} sx={{ minHeight: "100%", p: "20px" }}>
|
||||
<Typography variant="h5" color={theme.palette.grey3.main} fontWeight={700} sx={{ fontSize: 24, letterSpacing: "-0.2px" }}>
|
||||
Персонализация вопросов с помощью AI
|
||||
@ -60,7 +81,6 @@ export default function PersonalizationAI() {
|
||||
>
|
||||
Вставьте ссылку со всеми utm-метками
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', gap: 2, alignItems: 'center', mt: "6px" }}>
|
||||
<CustomTextField
|
||||
placeholder="linkexample.com"
|
||||
maxLength={5}
|
||||
@ -69,27 +89,41 @@ export default function PersonalizationAI() {
|
||||
}}
|
||||
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{
|
||||
bgcolor: PURPLE,
|
||||
borderRadius: "8px",
|
||||
width: "130px",
|
||||
height: "48px",
|
||||
boxShadow: "none",
|
||||
textTransform: "none",
|
||||
fontSize: "18px",
|
||||
'&:hover': { bgcolor: PURPLE },
|
||||
}}
|
||||
>
|
||||
Ок
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<AuditoryList />
|
||||
<AuditoryList deleteModal={setDeleteModal} auditory={auditory} />
|
||||
|
||||
</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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,9 +1,17 @@
|
||||
import { useState, MouseEvent } from "react";
|
||||
import { useState, MouseEvent, ReactNode } from "react";
|
||||
import Info from "@icons/Info";
|
||||
|
||||
import { Paper, Popover, SxProps, Typography } from "@mui/material";
|
||||
|
||||
export const InfoPopover = ({ blink = false, sx }: {blink?: boolean, sx?: SxProps}) => {
|
||||
export const InfoPopover = ({
|
||||
blink = false,
|
||||
sx,
|
||||
children = "подсказка"
|
||||
}: {
|
||||
blink?: boolean,
|
||||
sx?: SxProps,
|
||||
children?: ReactNode
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
|
||||
const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
@ -43,9 +51,7 @@ export const InfoPopover = ({ blink = false, sx }: {blink?: boolean, sx?: SxProp
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
подсказка
|
||||
</Typography>
|
||||
{children}
|
||||
</Paper>
|
||||
</Popover>
|
||||
</>
|
||||
|
@ -26,6 +26,10 @@ export default function TooltipClickInfo({ title }: { title: string }) {
|
||||
disableFocusListener
|
||||
disableHoverListener
|
||||
disableTouchListener
|
||||
sx={{
|
||||
fontSize: "12px",
|
||||
p:"10px"
|
||||
}}
|
||||
title={title}
|
||||
>
|
||||
<IconButton onClick={handleTooltipOpen}>
|
||||
|
Loading…
Reference in New Issue
Block a user