diff --git a/package.json b/package.json
index f36fd89..07e8673 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"next": "^14.0.2",
"next-pwa": "^5.6.0",
"next-remove-imports": "^1.0.12",
+ "node-fetch": "^2.6.7",
"postcss-focus-visible": "^6.0.4",
"puppeteer": "^22.0.0",
"react": "18.2.0",
@@ -80,15 +81,14 @@
"react-transition-group": "^4.4.5",
"react-visibility-sensor": "^5.1.1",
"reactjs-popup": "^2.0.5",
- "recharts": "^2.5.0",
+ "recharts": "^2.12.7",
"simplemde": "^1.11.2",
"socket.io-client": "^4.7.4",
"stripe": "^13.9.0",
"tailwind-merge": "^2.3.0",
"tailwindcss": "^3.2.1",
"tailwindcss-animate": "^1.0.7",
- "xterm": "^5.3.0",
- "node-fetch": "^2.6.7"
+ "xterm": "^5.3.0"
},
"devDependencies": {
"eslint": "8.26.0",
diff --git a/public/insightDemo.png b/public/insightDemo.png
new file mode 100644
index 0000000..f084d97
Binary files /dev/null and b/public/insightDemo.png differ
diff --git a/src/pages/challenges/[...id].jsx b/src/pages/challenges/[...id].jsx
index 669cbbf..ca01180 100644
--- a/src/pages/challenges/[...id].jsx
+++ b/src/pages/challenges/[...id].jsx
@@ -21,6 +21,7 @@ import Confetti from 'react-confetti';
import { Context } from '@/context';
import { useRef } from 'react';
import WriteupModal from '@/components/WriteupModal';
+import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
export default function Challenge() {
@@ -711,7 +712,56 @@ function HintsPage({ cache }) {
function DescriptionPage({ cache, fileIDName, fileIDLink }) {
+
+
const { challenge } = cache;
+
+ const [solvesData, setSolvesData] = useState([]);
+ const [creatorMode, setCreatorMode] = useState(false); // Add state for creator mode
+
+ const [insights, setInsights] = useState({
+ solves: 0,
+ attempts: 0,
+ solvesLast30Days: 0,
+ attemptsLast30Days: 0,
+ });
+
+ useEffect(() => {
+ const fetchSolvesData = async () => {
+ try {
+ const response = await request(`${process.env.NEXT_PUBLIC_API_URL}/${challenge.id}/insights/solvesLast10Days`, 'GET', null);
+ setSolvesData(response);
+ console.log(response);
+ } catch (error) {
+ console.error('Failed to fetch solves data: ', error);
+ }
+ };
+
+ const fetchCreatorMode = async () => {
+ try {
+ const response = await request(`${process.env.NEXT_PUBLIC_API_URL}/account`, 'GET', null);
+ setCreatorMode(response.creatorMode);
+ console.log(response.creatorMode);
+ } catch (error) {
+ console.error('Failed to fetch creator mode: ', error);
+ }
+ };
+
+ const fetchInsights = async () => {
+ try {
+ const response = await request(`${process.env.NEXT_PUBLIC_API_URL}/${challenge.id}/insights`, 'GET', null);
+ setInsights(response);
+ console.log(response);
+ } catch (error) {
+ console.error('Failed to fetch solves data: ', error);
+ }
+ };
+
+ fetchSolvesData();
+ fetchInsights();
+ fetchCreatorMode();
+ }, [challenge]);
+
const [challengeData, setChallengeData] = useState(null);
const [authorPfp, setAuthorPfp] = useState(null);
const { username } = useContext(Context);
@@ -821,8 +871,43 @@ function DescriptionPage({ cache, fileIDName, fileIDLink }) {
) : (
You may need to boot the terminal to see the associated files.
)}
-
-
+
+ {creatorMode && (
+ <>
+
+
+
+
Creator Insights
+
+
+
+
Solves
+
{insights.solves}
+
+
+
Attempts
+
{insights.attempts}
+
+
+
Solves (30d)
+
{insights.solvesLast30Days}
+
+
+
Attempts (30d)
+
{insights.attemptsLast30Days}
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
>
@@ -1603,4 +1688,3 @@ function DeleteCommentModal({ isOpen, onClose, onConfirm }) {
);
}
-
diff --git a/src/pages/create.jsx b/src/pages/create.jsx
index 337eac0..d103c52 100644
--- a/src/pages/create.jsx
+++ b/src/pages/create.jsx
@@ -20,6 +20,8 @@ import Box from '@mui/material/Box';
import { useRouter } from 'next/router';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
+import { Dialog, Transition } from '@headlessui/react';
+import { Fragment } from 'react';
export default function Create() {
const router = useRouter();
@@ -254,6 +256,52 @@ export default function Create() {
fetchNotifications();
}, []);
+ const [showCreatorMode, setShowCreatorMode] = useState(null);
+
+ const [isEnableModalOpen, setIsEnableModalOpen] = useState(false);
+ const [isDisableModalOpen, setIsDisableModalOpen] = useState(false);
+
+ const handleEnableCreatorMode = async () => {
+ try {
+ await request(`${process.env.NEXT_PUBLIC_API_URL}/account/creatorMode`, 'POST', { creatorMode: true });
+ setIsEnableModalOpen(false);
+ // Additional logic to enable creator mode
+ setCreatorMode(true);
+ setShowCreatorMode(true);
+ toast.success('Creator mode enabled successfully');
+ } catch (error) {
+ console.error('Error enabling creator mode:', error);
+ toast.error('Failed to enable creator mode');
+ }
+ };
+
+ const handleDisableCreatorMode = async () => {
+ try {
+ await request(`${process.env.NEXT_PUBLIC_API_URL}/account/creatorMode`, 'POST', { creatorMode: false });
+ setIsDisableModalOpen(false);
+ setCreatorMode(false);
+ setShowCreatorMode(true);
+ toast.success('Creator mode disabled successfully');
+ } catch (error) {
+ console.error('Error disabling creator mode:', error);
+ }
+ };
+
+ const [creatorMode, setCreatorMode] = useState(false);
+
+ useEffect(() => {
+ const fetchCreatorMode = async () => {
+ try {
+ const response = await request(`${process.env.NEXT_PUBLIC_API_URL}/account`, "GET", null);
+ setCreatorMode(response.creatorMode);
+ } catch (error) {
+ console.error('Error fetching creator mode:', error);
+ }
+ };
+
+ fetchCreatorMode();
+ }, []);
+
return (
<>
@@ -489,7 +537,7 @@ export default function Create() {
)}
-
+
@@ -567,8 +615,8 @@ export default function Create() {
-
-
+
+
@@ -593,7 +641,7 @@ export default function Create() {
Module Name
|
-
+
Last Updated
@@ -643,6 +691,135 @@ export default function Create() {
+
+
+
+
+
+
+
+
+
+
+
+
Challenge Notifications
@@ -673,6 +850,9 @@ export default function Create() {
)}
+
+
+
@@ -711,7 +891,7 @@ export default function Create() {
-
+
If you disagree with the changes, please join our Discord and voice your opinion.
diff --git a/yarn.lock b/yarn.lock
index 062215c..e9b8e35 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4680,7 +4680,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
-fast-equals@^5.0.0:
+fast-equals@^5.0.0, fast-equals@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d"
integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==
@@ -7159,7 +7159,7 @@ next@^14.0.2:
"@next/swc-win32-ia32-msvc" "14.0.4"
"@next/swc-win32-x64-msvc" "14.0.4"
-node-fetch@^2.6.12:
+node-fetch@^2.6.12, node-fetch@^2.6.7:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
@@ -8042,6 +8042,15 @@ react-smooth@^2.0.2:
fast-equals "^5.0.0"
react-transition-group "2.9.0"
+react-smooth@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.1.tgz#6200d8699bfe051ae40ba187988323b1449eab1a"
+ integrity sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==
+ dependencies:
+ fast-equals "^5.0.1"
+ prop-types "^15.8.1"
+ react-transition-group "^4.4.5"
+
react-swipeable@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/react-swipeable/-/react-swipeable-7.0.1.tgz#cd299f5986c5e4a7ee979839658c228f660e1e0c"
@@ -8143,7 +8152,21 @@ recharts-scale@^0.4.4:
dependencies:
decimal.js-light "^2.4.1"
-recharts@^2.3.2, recharts@^2.5.0:
+recharts@^2.12.7:
+ version "2.12.7"
+ resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.12.7.tgz#c7f42f473a257ff88b43d88a92530930b5f9e773"
+ integrity sha512-hlLJMhPQfv4/3NBSAyq3gzGg4h2v69RJh6KU7b3pXYNNAELs9kEoXOjbkxdXpALqKBoVmVptGfLpxdaVYqjmXQ==
+ dependencies:
+ clsx "^2.0.0"
+ eventemitter3 "^4.0.1"
+ lodash "^4.17.21"
+ react-is "^16.10.2"
+ react-smooth "^4.0.0"
+ recharts-scale "^0.4.4"
+ tiny-invariant "^1.3.1"
+ victory-vendor "^36.6.8"
+
+recharts@^2.3.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.7.2.tgz#6d813681910ad33a4bbf3bdd06c6f64f20b39319"
integrity sha512-HMKRBkGoOXHW+7JcRa6+MukPSifNtJlqbc+JreGVNA407VLE/vOP+8n3YYjprDVVIF9E2ZgwWnL3D7K/LUFzBg==
@@ -9230,6 +9253,11 @@ through@^2.3.8:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+tiny-invariant@^1.3.1:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
+ integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
+
tippy.js@^6.3.1:
version "6.3.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
|