dx v2.1
This commit is contained in:
+10
-1
@@ -34,6 +34,15 @@ input {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cfilter id='noise' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.8 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.45'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
body > *:not(#root):not(vite-error-overlay) {
|
||||
/* free ad blocker*/
|
||||
body:not(.dev) > *:not(#root):not(vite-error-overlay):not([k-version]) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
[k-version] {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
font-size: 1rem;
|
||||
color: #eee5;
|
||||
}
|
||||
|
||||
+5
-1
@@ -22,8 +22,12 @@ import "@fontsource/jost/700.css";
|
||||
import "@fontsource/jost/800.css";
|
||||
//import "@fontsource/jost/900.css";
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
document.body.classList.add("dev");
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
+49
-24
@@ -10,24 +10,20 @@ import {
|
||||
import Logo from "../assets/logo.svg";
|
||||
import LogoAlternative from "../assets/fully_alternative_logo.svg";
|
||||
import {
|
||||
Switch,
|
||||
// AnimatedCanvas,
|
||||
LoadingSpinner,
|
||||
DatePicker,
|
||||
TextPreloader,
|
||||
// CoolMouseBg,
|
||||
} from "../trash/trash-components";
|
||||
import {
|
||||
AdminReq,
|
||||
AdminUserFRequest,
|
||||
classUserFRequest,
|
||||
RaspGet,
|
||||
} from "../trash/req_mgr";
|
||||
import { AdminReq, classUserFRequest, RaspGet } from "../trash/req_mgr";
|
||||
import { AnimatePresence, LayoutGroup, motion } from "motion/react";
|
||||
|
||||
import { apiFormatDate, isTimeBeforeNow } from "../trash/dengi";
|
||||
import { useAtom } from "jotai";
|
||||
import { API_BASE_URL } from "../App";
|
||||
import { copyDXLink, ifstyle } from "../trash/helpers";
|
||||
import { useWebHaptics } from "web-haptics/react";
|
||||
|
||||
export function DX4App({
|
||||
classIDAtom,
|
||||
@@ -78,7 +74,7 @@ export function DX4App({
|
||||
(err) => {
|
||||
if (cancelled) return;
|
||||
setRasp([true, "ошибка: " + err]);
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
if (cancelled) return;
|
||||
@@ -133,15 +129,15 @@ export function DX4App({
|
||||
if (classId !== "")
|
||||
promises.push(
|
||||
dengi_cash.withCacheAsync(`userfr-${classId}`, async () =>
|
||||
classUserFRequest(API_BASE_URL, classId)
|
||||
)
|
||||
classUserFRequest(API_BASE_URL, classId),
|
||||
),
|
||||
);
|
||||
else promises.push(Promise.resolve([0]));
|
||||
if (adminId !== "")
|
||||
promises.push(
|
||||
dengi_cash.withCacheAsync(`admindata-${adminId}`, async () =>
|
||||
AdminReq(API_BASE_URL, adminId)
|
||||
)
|
||||
AdminReq(API_BASE_URL, adminId),
|
||||
),
|
||||
);
|
||||
else promises.push(Promise.resolve([0]));
|
||||
Promise.all(promises).then(([classRes, adminRes]) => {
|
||||
@@ -192,6 +188,9 @@ export function DX4App({
|
||||
if (classId === "") {
|
||||
setsetRoute(setRoute, "/");
|
||||
}
|
||||
const { trigger } = useWebHaptics();
|
||||
|
||||
const raspDragStartX = useRef(0);
|
||||
return (
|
||||
<>
|
||||
<motion.div className="w-full h-screen flex flex-col items-center justify-center gap-5 overflow-x-hidden z-2">
|
||||
@@ -236,7 +235,12 @@ export function DX4App({
|
||||
>
|
||||
<BiDotsHorizontalRounded
|
||||
size={35}
|
||||
onClick={() => setOpenUserSettings(!openUserSettings)}
|
||||
onClick={() => {
|
||||
setOpenUserSettings(!openUserSettings);
|
||||
trigger([{ duration: 10 }, { delay: 100, duration: 10 }], {
|
||||
intensity: 1,
|
||||
});
|
||||
}}
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
setPickmeMode(!pickmeMode);
|
||||
@@ -269,7 +273,7 @@ export function DX4App({
|
||||
|
||||
{adminId != "" && managing && (
|
||||
<motion.div
|
||||
className="flex w-full justify-end"
|
||||
className="flex w-full justify-end not-md:px-4"
|
||||
layout="position"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
@@ -326,7 +330,28 @@ export function DX4App({
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative">
|
||||
<motion.div
|
||||
className="relative min-h-[50vh]"
|
||||
drag="x"
|
||||
dragConstraints={{ top: 0, right: 0, bottom: 0, left: 0 }}
|
||||
dragElastic={0.2}
|
||||
onDragStart={(ev) => {
|
||||
raspDragStartX.current = ev.clientX;
|
||||
}}
|
||||
onDragEnd={(ev) => {
|
||||
if (raspDragStartX.current > ev.clientX + 150) {
|
||||
const d = new Date(selectedDate);
|
||||
d.setDate(d.getDate() + 1);
|
||||
setSelectedDate(d);
|
||||
trigger([{ duration: 10 }], { intensity: 1 });
|
||||
} else if (raspDragStartX.current < ev.clientX - 150) {
|
||||
const d = new Date(selectedDate);
|
||||
d.setDate(d.getDate() - 1);
|
||||
setSelectedDate(d);
|
||||
trigger([{ duration: 10 }], { intensity: 1 });
|
||||
}
|
||||
}}
|
||||
>
|
||||
<LayoutGroup>
|
||||
<RaspView {...{ rasp, pickmeMode, selectedDate }} />
|
||||
</LayoutGroup>
|
||||
@@ -343,7 +368,7 @@ export function DX4App({
|
||||
<LoadingSpinner size={25} />
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
@@ -370,8 +395,8 @@ export const RaspView = memo(({ rasp, pickmeMode, selectedDate }) => {
|
||||
key={selectedDate}
|
||||
className={
|
||||
"w-full border-collapse border-spacing-x-0 border-spacing-y-[10px] bg-gradient-to-br mb-10 " +
|
||||
(pickmeMode ? "from-pink-400/30" : "from-zinc-800/40") +
|
||||
" to-transparent rounded-2xl selectable"
|
||||
(pickmeMode ? "from-pink-400/30" : "from-[#101011ee]") +
|
||||
" to-[#030303fa] rounded-2xl"
|
||||
}
|
||||
onContextMenu={(ev) => {
|
||||
ev.preventDefault();
|
||||
@@ -419,7 +444,7 @@ export const RaspView = memo(({ rasp, pickmeMode, selectedDate }) => {
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="*:*:text-center *:*:py-2 *:not-last:border-b *:not-last:border-zinc-800 text-white">
|
||||
<tbody className="*:*:text-center *:*:py-2 *:not-last:border-b *:not-last:border-zinc-800 text-white ">
|
||||
{rasp[1].map((d, i) => (
|
||||
<TableItem {...{ d }} key={`table-header-${i}`} />
|
||||
))}
|
||||
@@ -542,13 +567,13 @@ const UserSettings = memo(
|
||||
>
|
||||
{item[0]} {item[1]}
|
||||
</div>
|
||||
)
|
||||
),
|
||||
)}
|
||||
</motion.div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
class GlobalListener {
|
||||
@@ -592,10 +617,10 @@ const TableItem = memo(({ d }) => {
|
||||
<tr
|
||||
//layout="position"
|
||||
className={
|
||||
"transition-colors *:transition-colors " +
|
||||
"transition-colors *:transition-colors last:*:first:rounded-bl-2xl last:*:last:rounded-br-2xl " +
|
||||
(sel
|
||||
? "bg-zinc-300/15 lg:hover:bg-zinc-300/20"
|
||||
: " lg:hover:bg-zinc-300/15")
|
||||
? "*:bg-zinc-300/15 lg:hover:*:bg-zinc-300/20"
|
||||
: " lg:hover:*:bg-zinc-300/15")
|
||||
}
|
||||
onClick={() => {
|
||||
setSel(!sel);
|
||||
|
||||
+12
-6
@@ -22,6 +22,7 @@ import {
|
||||
import { TableEditor } from "../trash/editorTable";
|
||||
import { ifstyle } from "../trash/helpers";
|
||||
import { API_BASE_URL } from "../App";
|
||||
import { useWebHaptics } from "web-haptics/react";
|
||||
|
||||
export default function EditorPage(props) {
|
||||
const [classId, _setUserId] = useAtom(props.classIDAtom);
|
||||
@@ -49,17 +50,18 @@ export default function EditorPage(props) {
|
||||
let cancelled = false;
|
||||
const promises = [];
|
||||
if (classId !== "")
|
||||
// TODO: rewrite this bullshit into one pretty request
|
||||
promises.push(
|
||||
props.dengi_cash.withCacheAsync(`userfr-${classId}`, async () =>
|
||||
classUserFRequest(API_BASE_URL, classId)
|
||||
)
|
||||
classUserFRequest(API_BASE_URL, classId),
|
||||
),
|
||||
);
|
||||
else promises.push(Promise.resolve([0]));
|
||||
if (adminId !== "")
|
||||
promises.push(
|
||||
props.dengi_cash.withCacheAsync(`adminfr-${adminId}`, async () =>
|
||||
AdminUserFRequest(API_BASE_URL, adminId)
|
||||
)
|
||||
AdminUserFRequest(API_BASE_URL, adminId),
|
||||
),
|
||||
);
|
||||
else promises.push(Promise.resolve([0]));
|
||||
Promise.all(promises).then(([classRes, adminRes]) => {
|
||||
@@ -79,9 +81,12 @@ export default function EditorPage(props) {
|
||||
props.dengi_cash.delete(
|
||||
"editor_schedule",
|
||||
"editor_changes",
|
||||
"editor_rings"
|
||||
"editor_rings",
|
||||
);
|
||||
}, []); // clean on full rerender
|
||||
|
||||
const { trigger } = useWebHaptics();
|
||||
|
||||
// tabs
|
||||
const tabs = [
|
||||
[
|
||||
@@ -189,7 +194,7 @@ export default function EditorPage(props) {
|
||||
"flex items-center gap-2 transition-colors " +
|
||||
ifstyle(
|
||||
selectedTab == 2,
|
||||
"text-transparent pointer-events-none select-none"
|
||||
"text-transparent pointer-events-none select-none",
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -238,6 +243,7 @@ export default function EditorPage(props) {
|
||||
key={idx}
|
||||
onClick={() => {
|
||||
if (selectedTab == idx) return;
|
||||
trigger([{ duration: 35 }], { intensity: 1 });
|
||||
if (!changesWereMade) {
|
||||
selectTab(idx);
|
||||
} else {
|
||||
|
||||
+28
-11
@@ -42,6 +42,7 @@ import {
|
||||
EditorRemoveRequest,
|
||||
} from "./editor_req_mgr";
|
||||
import { API_BASE_URL } from "../App";
|
||||
import { useWebHaptics } from "web-haptics/react";
|
||||
|
||||
// Configuration
|
||||
const COLUMNS = [
|
||||
@@ -171,7 +172,7 @@ function SortableRow({
|
||||
transition,
|
||||
opacity: isDragging ? 0.5 : 1,
|
||||
};
|
||||
|
||||
const { trigger } = useWebHaptics();
|
||||
return (
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
@@ -207,7 +208,10 @@ function SortableRow({
|
||||
<span className="w-[98%] mx-auto h-[1px] bg-zinc-500" />
|
||||
<div className="flex justify-end w-full">
|
||||
<button
|
||||
onClick={() => onDuplicate(item.id)}
|
||||
onClick={() => {
|
||||
onDuplicate(item.id);
|
||||
trigger([{ duration: 25 }], { intensity: 0.7 });
|
||||
}}
|
||||
className="min-w-12 min-h-12 transition-colors bg-zinc-600/20 text-zinc-400 hover:bg-zinc-600/40 hover:text-zinc-300 flex items-center justify-center rounded-l-md"
|
||||
>
|
||||
<BiCopy size={20} />
|
||||
@@ -220,7 +224,14 @@ function SortableRow({
|
||||
<BiDotsVertical size={24} />
|
||||
</div>
|
||||
<button
|
||||
onClick={() => onDelete(item.id)}
|
||||
onClick={() => {
|
||||
onDelete(item.id);
|
||||
trigger([
|
||||
{ duration: 40, intensity: 0.7 },
|
||||
{ delay: 40, duration: 40, intensity: 0.7 },
|
||||
{ delay: 40, duration: 40, intensity: 0.9 },
|
||||
]);
|
||||
}}
|
||||
className="min-w-12 min-h-12 transition-colors bg-red-600/20 text-red-400 hover:bg-red-600/40 hover:text-red-300 active:bg-red-600/60 flex items-center justify-center rounded-r-md"
|
||||
>
|
||||
<BiX size={24} />
|
||||
@@ -235,7 +246,7 @@ async function getPrefilledRasp(tab, date, adminId) {
|
||||
API_BASE_URL,
|
||||
tab,
|
||||
adminId,
|
||||
apiFormatDate(date)
|
||||
apiFormatDate(date),
|
||||
);
|
||||
if (a[0] == 1 && a[1]) {
|
||||
return convertApiToEditor(a[1]);
|
||||
@@ -291,7 +302,7 @@ export function TableEditor({
|
||||
delay: 200,
|
||||
tolerance: 8,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const updateItems = (newItems) => {
|
||||
@@ -330,7 +341,7 @@ export function TableEditor({
|
||||
clearTimeout(updateTimeoutRef.current[key]);
|
||||
}
|
||||
const newItems = items.map((item) =>
|
||||
item.id === id ? { ...item, [field]: value } : item
|
||||
item.id === id ? { ...item, [field]: value } : item,
|
||||
);
|
||||
updateItems(newItems);
|
||||
updateTimeoutRef.current[key] = setTimeout(() => {
|
||||
@@ -338,7 +349,7 @@ export function TableEditor({
|
||||
const itemsWithOriginalValue = items.map((item) =>
|
||||
item.id === id
|
||||
? { ...item, [field]: previousValueRef.current[key] }
|
||||
: item
|
||||
: item,
|
||||
);
|
||||
setUndoItems([itemsWithOriginalValue, ...undoItems]);
|
||||
|
||||
@@ -406,7 +417,7 @@ export function TableEditor({
|
||||
const lastPosition =
|
||||
items.length > 0
|
||||
? String(
|
||||
parseInt(sortedItems[sortedItems.length - 1].position || "0") + 1
|
||||
parseInt(sortedItems[sortedItems.length - 1].position || "0") + 1,
|
||||
)
|
||||
: "1";
|
||||
|
||||
@@ -425,7 +436,7 @@ export function TableEditor({
|
||||
left: window.scrollX, // preserve current X
|
||||
behavior: "smooth",
|
||||
}),
|
||||
100
|
||||
100,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -461,7 +472,7 @@ export function TableEditor({
|
||||
selectedTab,
|
||||
adminId,
|
||||
apiFormatDate(date),
|
||||
JSON.stringify(convertEditorToApi(items))
|
||||
JSON.stringify(convertEditorToApi(items)),
|
||||
).then(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
@@ -471,6 +482,11 @@ export function TableEditor({
|
||||
setDeleteDiag(true);
|
||||
};
|
||||
|
||||
const { trigger } = useWebHaptics();
|
||||
const handleDragOver = (ev) => {
|
||||
trigger([{ duration: 25 }], { intensity: 0.7 });
|
||||
};
|
||||
|
||||
let deleteDialogBusy = false; // NOTE: we don't need a state
|
||||
return (
|
||||
<>
|
||||
@@ -496,7 +512,7 @@ export function TableEditor({
|
||||
API_BASE_URL,
|
||||
selectedTab,
|
||||
adminId,
|
||||
apiFormatDate(date)
|
||||
apiFormatDate(date),
|
||||
).then(() => {
|
||||
deleteDialogBusy = false; // for 100% sure
|
||||
setDeleteDiag(false);
|
||||
@@ -573,6 +589,7 @@ export function TableEditor({
|
||||
sensors={sensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDragOver={handleDragOver}
|
||||
>
|
||||
<SortableContext
|
||||
items={items.map((item) => item.id)}
|
||||
|
||||
@@ -7,9 +7,11 @@ import {
|
||||
BiShow,
|
||||
BiX,
|
||||
} from "react-icons/bi";
|
||||
import { formatDate, getDateTags } from "./dengi.js";
|
||||
import { apiFormatDate, formatDate, getDateTags } from "./dengi.js";
|
||||
import { AnimatePresence, motion, LayoutGroup } from "motion/react";
|
||||
import trashcss from "./trash.module.css";
|
||||
import { useWebHaptics } from "web-haptics/react";
|
||||
|
||||
export function Switch({
|
||||
checked,
|
||||
defaultChecked = false,
|
||||
@@ -98,6 +100,7 @@ export function LoadingSpinner({ size }) {
|
||||
}
|
||||
|
||||
function DatePickerButton({ next = false, date, setDate, pink = false }) {
|
||||
const { trigger } = useWebHaptics();
|
||||
return (
|
||||
<span
|
||||
className={`cursor-pointer ${
|
||||
@@ -109,6 +112,7 @@ function DatePickerButton({ next = false, date, setDate, pink = false }) {
|
||||
const d = new Date(date);
|
||||
d.setDate(d.getDate() + (next ? 1 : -1));
|
||||
setDate(d);
|
||||
trigger([{ duration: 15 }], { intensity: 1 });
|
||||
}}
|
||||
>
|
||||
{!next ? <BiLeftArrowAlt size={34} /> : <BiRightArrowAlt size={34} />}
|
||||
@@ -118,7 +122,7 @@ function DatePickerButton({ next = false, date, setDate, pink = false }) {
|
||||
|
||||
export const DatePicker = (props) => {
|
||||
const dateTag = getDateTags(props.date);
|
||||
|
||||
const { trigger } = useWebHaptics();
|
||||
return (
|
||||
<LayoutGroup>
|
||||
<div
|
||||
@@ -133,20 +137,27 @@ export const DatePicker = (props) => {
|
||||
/>
|
||||
<AnimatePresence mode="popLayout">
|
||||
<motion.span
|
||||
key={formatDate(props.date)}
|
||||
// key={formatDate(props.date)}
|
||||
className={`cursor-pointer flex items-center gap-1 justify-center w-[80%] lg:hover:text-black *:transition-colors transition-colors p-1 rounded-3xl text-zinc-300 ${
|
||||
!props.pink
|
||||
? "lg:hover:bg-white lg:hover:*:text-black"
|
||||
: "lg:hover:bg-pink-500 lg:hover:*:text-white"
|
||||
} px-3 overflow-hidden `}
|
||||
variants={{
|
||||
a: { opacity: 0, filter: "blur(1px)" },
|
||||
b: { opacity: 1, filter: "blur(0px)" },
|
||||
}}
|
||||
initial="a"
|
||||
animate="b"
|
||||
exit="a"
|
||||
// variants={{
|
||||
// a: { opacity: 0, filter: "blur(1px)" },
|
||||
// b: { opacity: 1, filter: "blur(0px)" },
|
||||
// }}
|
||||
// initial="a"
|
||||
// animate="b"
|
||||
// exit="a"
|
||||
|
||||
onClick={() => {
|
||||
if (apiFormatDate(props.date) != apiFormatDate(new Date()))
|
||||
trigger([
|
||||
{ duration: 10, intensity: 1 },
|
||||
{ delay: 40, duration: 20, intensity: 0.26 },
|
||||
{ delay: 90, duration: 20, intensity: 0.34 },
|
||||
]);
|
||||
props.setDate(new Date());
|
||||
}}
|
||||
>
|
||||
@@ -160,7 +171,7 @@ export const DatePicker = (props) => {
|
||||
: " bg-transparent")
|
||||
}
|
||||
layoutId="datepicker_indicator"
|
||||
layout="position"
|
||||
// layout="position"
|
||||
/>
|
||||
<motion.span
|
||||
layoutId="datepicker_date"
|
||||
@@ -173,7 +184,7 @@ export const DatePicker = (props) => {
|
||||
<>
|
||||
<motion.div
|
||||
className="flex"
|
||||
layoutId="datepicker_date_div"
|
||||
// layoutId="datepicker_date_div"
|
||||
layout="position"
|
||||
>
|
||||
<span
|
||||
@@ -183,9 +194,9 @@ export const DatePicker = (props) => {
|
||||
/>
|
||||
</motion.div>
|
||||
<motion.span
|
||||
initial={{ x: 10, opacity: 0 }}
|
||||
initial={{ opacity: 0 }}
|
||||
transition={{ delay: 0.1 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
animate={{ opacity: 1 }}
|
||||
className="text-zinc-600 italic"
|
||||
>
|
||||
{dateTag}
|
||||
@@ -211,6 +222,8 @@ export function DengiButton({
|
||||
disabled = false,
|
||||
className = "",
|
||||
}) {
|
||||
const { trigger } = useWebHaptics();
|
||||
|
||||
return (
|
||||
<span
|
||||
role="button"
|
||||
@@ -223,7 +236,19 @@ export function DengiButton({
|
||||
(className ? className : "")
|
||||
}
|
||||
aria-disabled={disabled}
|
||||
onClick={disabled ? null : onClick}
|
||||
onClick={
|
||||
disabled
|
||||
? null
|
||||
: () => {
|
||||
onClick();
|
||||
trigger([
|
||||
{
|
||||
duration: 40,
|
||||
intensity: 0.8,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
@@ -285,6 +310,22 @@ export function DengiYesOrNoDialog({
|
||||
show,
|
||||
onAnswer,
|
||||
}) {
|
||||
const { trigger } = useWebHaptics();
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
trigger([
|
||||
{
|
||||
duration: 40,
|
||||
intensity: 0.8,
|
||||
},
|
||||
{
|
||||
delay: 15,
|
||||
duration: 170,
|
||||
intensity: 0.9,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}, [show]);
|
||||
return (
|
||||
<>
|
||||
<AnimatePresence>
|
||||
@@ -296,8 +337,10 @@ export function DengiYesOrNoDialog({
|
||||
exit="off"
|
||||
className="fixed z-99 bg-black/50 backdrop-blur-xl top-0 left-0 w-full h-full overflow-hidden flex items-center justify-center"
|
||||
onClick={(e) => {
|
||||
if (e.target === e.currentTarget && content.bgDissmis)
|
||||
if (e.target === e.currentTarget && content.bgDissmis) {
|
||||
onAnswer(false);
|
||||
trigger([{ duration: 40, intensity: 1 }]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<motion.div
|
||||
|
||||
Reference in New Issue
Block a user