diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75eb2b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +data_folder \ No newline at end of file diff --git a/data_folder/LongestCommanPrefix.json b/data_folder/LongestCommanPrefix.json deleted file mode 100644 index f50cbc8..0000000 --- a/data_folder/LongestCommanPrefix.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "id": 14, - "name": "Longest Common Prefix", - "defaultCode": "/**\n* @param {string[]} strs\n* @return {string}\n*/\nvar longestCommonPrefix = function(strs) {\n};", - "i_o_schema": "{string[]},{string}", - "compileFunctionName": "longestCommonPrefix", - "tags": ["easy", "arrays"], - "description": "Write a function to find the longest common prefix string amongst an array of strings.\n\nIf there is no common prefix, return an empty string \"\".", - "examples": [ - { - "input": ["flower", "flow", "flight"], - "output": "fl", - "explanation": "The longest common prefix among the input strings is 'fl'." - }, - { - "input": ["dog", "racecar", "car"], - "output": "", - "explanation": "There is no common prefix among the input strings." - } - ], - "constraints": ["1 <= strs.length <= 200", "0 <= strs[i].length <= 200", "strs[i] consists of only lowercase English letters."], - "testcases": [ - { - "id": 0, - "input": { - "strs": ["apple", "apricot", "apparel"] - }, - "output": "app", - "hidden": true - }, - { - "id": 1, - "input": { - "strs": ["banana", "band", "bank"] - }, - "output": "ban", - "hidden": true - }, - { - "id": 2, - "input": { - "strs": ["code", "coding", "coder"] - }, - "output": "cod", - "hidden": true - }, - { - "id": 3, - "input": { - "strs": ["programming", "program", "progress"] - }, - "output": "prog", - "hidden": true - }, - { - "id": 4, - "input": { - "strs": ["apple", "apricot", "application"] - }, - "output": "appl", - "hidden": true - }, - { - "id": 5, - "input": { - "strs": ["ball", "bat", "basket"] - }, - "output": "ba", - "hidden": true - }, - { - "id": 6, - "input": { - "strs": ["computation", "compute", "computer"] - }, - "output": "comput", - "hidden": true - }, - { - "id": 7, - "input": { - "strs": ["directory", "director", "direct"] - }, - "output": "direct", - "hidden": true - }, - { - "id": 8, - "input": { - "strs": ["electronics", "electric", "electricity"] - }, - "output": "electric", - "hidden": true - }, - { - "id": 9, - "input": { - "strs": ["fantastic", "fan", "fancy"] - }, - "output": "fan", - "hidden": true - } - ] - } - \ No newline at end of file diff --git a/data_folder/ValidParenthesis.json b/data_folder/ValidParenthesis.json deleted file mode 100644 index e7e16e9..0000000 --- a/data_folder/ValidParenthesis.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "id": 15, - "name": "Valid Parentheses", - "defaultCode": "/**\n * @param {string} s\n * @return {boolean}\n */\nvar isValid = function(s) {\n\n};", - "i_o_schema": "{string},{boolean}", - "compileFunctionName": "isValid", - "tags": ["easy"], - "description": "Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.\n\nAn input string is valid if:\n\n- Open brackets must be closed by the same type of brackets.\n- Open brackets must be closed in the correct order.\n- Every close bracket has a corresponding open bracket of the same type.", - "examples": [ - { - "input": "()", - "output": true, - "explanation": "The input string contains a pair of valid parentheses, so the output is true." - }, - { - "input": "()[]{}", - "output": true, - "explanation": "The input string contains valid pairs of parentheses, brackets, and curly braces, so the output is true." - }, - { - "input": "(]", - "output": false, - "explanation": "The input string contains mismatched parentheses, so the output is false." - } - ], - "constraints": [ - "1 <= s.length <= 104", - "s consists of parentheses only '()[]{}'." - ], - "testcases": [ - { - "id": 0, - "input": { - "s": "()" - }, - "output": true, - "hidden": false - }, - { - "id": 1, - "input": { - "s": "()[]{}" - }, - "output": true, - "hidden": false - }, - { - "id": 2, - "input": { - "s": "(]" - }, - "output": false, - "hidden": false - }, - { - "id": 3, - "input": { - "s": "(({{}}))" - }, - "output": true, - "hidden": true - }, - { - "id": 4, - "input": { - "s": "[{()}" - }, - "output": false, - "hidden": true - }, - { - "id": 5, - "input": { - "s": "(()()()" - }, - "output": false, - "hidden": true - }, - { - "id": 6, - "input": { - "s": "((((((" - }, - "output": false, - "hidden": true - }, - { - "id": 7, - "input": { - "s": "({[]})" - }, - "output": true, - "hidden": true - }, - { - "id": 8, - "input": { - "s": "{[()]()}" - }, - "output": true, - "hidden": true - }, - { - "id": 9, - "input": { - "s": "([)]" - }, - "output": false, - "hidden": true - }, - { - "id": 10, - "input": { - "s": "(){}[]" - }, - "output": true, - "hidden": true - }, - { - "id": 11, - "input": { - "s": "((())])" - }, - "output": false, - "hidden": true - }, - { - "id": 12, - "input": { - "s": "{[[]]}" - }, - "output": true, - "hidden": true - }, - { - "id": 13, - "input": { - "s": "((((((((((((((((((()))))))))))))))))))" - }, - "output": true, - "hidden": true - } - ] -} diff --git a/data_folder/contract...txt b/data_folder/contract...txt deleted file mode 100644 index fb80e6e..0000000 --- a/data_folder/contract...txt +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity >=0.7.0 <0.9.0; - -contract Question { - //predefiners... - string public QuestionData;//ipfs data goes here.... - string public topicName;//name of the bounty.... - address moderator;//owner of the bounty.... - address webHandler; - - //non static data... - struct CodeData{ - address by; - string code; - uint256 submitTime; - uint256 runTime; - } - uint256 public bountyValue; - bool public claimed = false;// initially the bounty will be unclaimed.... - address public bountyWinner = address(0); - string public winnerCode; - mapping(address => CodeData) codes; - CodeData[] submissions; - uint16 public difficulty; - - modifier onlyModerator(){ - require(msg.sender == moderator, "Not authoresised."); - _; - } - modifier onlyWebHandler(){ - require(msg.sender == webHandler, "Not authoresised."); - _; - } - constructor(string memory _name, string memory _quesData, address _mod, uint16 _diff, address _webHandler)payable{ - QuestionData = _quesData; - topicName = _name; - moderator = _mod; - //funding the question.... - bountyValue = msg.value; - claimed = false; - difficulty = _diff; - webHandler = _webHandler; - } - function submitCode(string memory _codeHash, address _sender, uint256 runTime)public onlyWebHandler{ - require(codes[_sender].by == _sender,"code allready submitted."); - codes[_sender] = CodeData( _sender, _codeHash, block.timestamp, runTime); - submissions.push(CodeData( _sender, _codeHash, block.timestamp, runTime)); - } - function giveAway(address _winner)public onlyModerator returns(bool){ - require(codes[_winner].by != address(0),"not one of submiters"); - require(!claimed, "allready claimed"); - (bool se, ) = _winner.call{value: bountyValue}(""); - claimed = se; - bountyWinner == _winner; - winnerCode = codes[_winner].code; - return se; - } - function haveSubmitted()public view returns(bool){ - return (codes[msg.sender].by != address(0)); - } - -} \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5dbdcf9..4f29182 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,9 +15,12 @@ "@noble/secp256k1": "^2.1.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.0.5", + "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-tabs": "^1.1.0", + "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-table": "^8.11.7", "@tronweb3/tronwallet-abstract-adapter": "^1.1.6", @@ -36,16 +39,19 @@ "constrained-editor-plugin": "^1.3.0", "firebase": "^10.11.1", "gsap": "^3.12.5", + "jwt-decode": "^4.0.0", "lucide-react": "^0.316.0", "next": "14.1.0", "react": "^18", "react-confetti": "^6.1.0", "react-dom": "^18", + "react-icons": "^5.2.1", "react-resizable-panels": "^2.0.3", "react-router-dom": "^6.22.0", "recoil": "^0.7.7", "sonner": "^1.4.0", "tailwind-merge": "^2.2.1", + "tailwind-scrollbar": "^3.1.0", "tailwindcss-animate": "^1.0.7", "tronweb": "^6.0.0-beta.2" }, @@ -2892,6 +2898,295 @@ } } }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.0.tgz", + "integrity": "sha512-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-presence": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.5.tgz", + "integrity": "sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tooltip": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", @@ -6168,6 +6463,14 @@ "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "engines": { + "node": ">=18" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -7116,6 +7419,14 @@ "react": "^18.2.0" } }, + "node_modules/react-icons": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -7939,6 +8250,17 @@ "url": "https://github.com/sponsors/dcastil" } }, + "node_modules/tailwind-scrollbar": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tailwind-scrollbar/-/tailwind-scrollbar-3.1.0.tgz", + "integrity": "sha512-pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg==", + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "tailwindcss": "3.x" + } + }, "node_modules/tailwindcss": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 7977fcd..116b69f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,9 +17,12 @@ "@noble/secp256k1": "^2.1.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.0.5", + "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-tabs": "^1.1.0", + "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-table": "^8.11.7", "@tronweb3/tronwallet-abstract-adapter": "^1.1.6", @@ -38,16 +41,19 @@ "constrained-editor-plugin": "^1.3.0", "firebase": "^10.11.1", "gsap": "^3.12.5", + "jwt-decode": "^4.0.0", "lucide-react": "^0.316.0", "next": "14.1.0", "react": "^18", "react-confetti": "^6.1.0", "react-dom": "^18", + "react-icons": "^5.2.1", "react-resizable-panels": "^2.0.3", "react-router-dom": "^6.22.0", "recoil": "^0.7.7", "sonner": "^1.4.0", "tailwind-merge": "^2.2.1", + "tailwind-scrollbar": "^3.1.0", "tailwindcss-animate": "^1.0.7", "tronweb": "^6.0.0-beta.2" }, diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 8617820..429a9ce 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -2,10 +2,10 @@ import { useMemo } from "react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import "./App.css"; import "./index.css"; -import MyQuestionDesc from "./pages/MyQuestionDesc"; -import MyQuestions from "./pages/MyQuestions"; import AddQuestion from "./pages/AddQuestion"; import Landing from "./pages/Landing"; +import MyQuestionDesc from "./pages/MyQuestionDesc"; +import MyQuestions from "./pages/MyQuestions"; import ProblemDesc from "./pages/ProblemDesc"; import Problems from "./pages/Problems."; //importing buffer tronweb access @@ -19,7 +19,12 @@ import { WalletProvider } from "@tronweb3/tronwallet-adapter-react-hooks"; import { WalletModalProvider } from "@tronweb3/tronwallet-adapter-react-ui"; import "@tronweb3/tronwallet-adapter-react-ui/style.css"; import { TronLinkAdapter } from "@tronweb3/tronwallet-adapter-tronlink"; +import { useEffect } from "react"; +import { useRecoilState, useSetRecoilState } from "recoil"; +import { authTokenState, userState } from "./atoms/userAtom"; import AlertModal from "./components/ui/AlertModal"; +import { jwtDecode } from "jwt-decode"; +import axios from "axios"; globalThis.Buffer = Buffer; @@ -42,6 +47,41 @@ function App() { return [tronLink]; }, []); + useEffect(() => { + adapters[0].on("chainChanged", (data) => { + console.log("chainChanged", JSON.stringify(data)); + }); + }); + + const [authToken, setAuthToken] = useRecoilState(authTokenState); + const setUser = useSetRecoilState(userState); + + useEffect(() => { + const token = localStorage.getItem("auth-token"); + + const getUser = async (userId) => { + try { + const { data } = await axios.get( + import.meta.env.VITE_BACKEND_URL + `/auth/user/${userId}`, + ); + + setUser(data); + } catch (err) { + console.error(err); + } + }; + + if (token) { + setAuthToken(token); + const decoded = jwtDecode(token); + const userId = decoded?.user?.id; + + if (userId) { + getUser(userId); + } + } + }, [authToken, setAuthToken]); + return ( <> diff --git a/frontend/src/atoms/problemAtom.js b/frontend/src/atoms/problemAtom.js index 05c495c..a8e97db 100644 --- a/frontend/src/atoms/problemAtom.js +++ b/frontend/src/atoms/problemAtom.js @@ -1,11 +1,53 @@ -import { atom } from "recoil"; +import { atom, selector } from "recoil"; export const outputAtom = atom({ key: "outputAtom", - default: null, + default: { + type: "run", + data: [], + expectedOutput: "", + }, }); export const resultAtom = atom({ key: "resultAtom", default: false, }); + +export const questionAddStatus = atom({ + key: "questionAddStatus", + default: -1, +}); + +export const codeRunLoadingState = atom({ + key: "codeRunLoadingState", + default: false, +}); + +// submissions atoms + +export const submissionResultState = atom({ + key: "submissionResultState", + default: null, +}); + +export const activeSubmissionIdState = atom({ + key: "activeSubmissionIdState", + default: null, +}); + +export const activeSubmissionResultSelector = selector({ + key: "activeSubmissionResultSelector", + get: ({ get }) => { + const activeSubmissionId = get(activeSubmissionIdState); + const submissionResult = get(submissionResultState); + return activeSubmissionId && submissionResult + ? submissionResult[activeSubmissionId] + : null; + }, +}); + +export const fetchSubmissionsLoadingState = atom({ + key: "fetchSubmissionsLoadingState", + default: false, +}); diff --git a/frontend/src/atoms/userAtom.js b/frontend/src/atoms/userAtom.js index d1eb11c..6b58a55 100644 --- a/frontend/src/atoms/userAtom.js +++ b/frontend/src/atoms/userAtom.js @@ -1,11 +1,18 @@ import { atom } from "recoil"; -export const userAtom = atom({ - key: "userAtom", - default: { - isLoggedin: false, - data: null, - }, +export const authTokenState = atom({ + key: "authTokenState", + default: null, +}); + +export const usernameState = atom({ + key: "usernameState", + default: "", +}); + +export const userState = atom({ + key: "userState", + default: {}, }); export const alertAtom = atom({ @@ -17,6 +24,11 @@ export const alertAtom = atom({ }, }); +export const tabsSelectorAtom = atom({ + key: "tabsSelectorAtom", + default: 0, +}) + export const submissionErrorAtom = atom({ key: "submissionErrorAtom", default: { diff --git a/frontend/src/components/AddProblemForm.jsx b/frontend/src/components/AddProblemForm.jsx index 5264dbb..ab64599 100644 --- a/frontend/src/components/AddProblemForm.jsx +++ b/frontend/src/components/AddProblemForm.jsx @@ -1,28 +1,129 @@ +import useDeployQuestion from "@/hooks/useDeployQuestion"; import { useEffect, useState } from "react"; +import { toast } from "sonner"; +import QuestionProgress from "./ui/QuestionProgress"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; +import { ArrowBigDownIcon } from "lucide-react"; +import { useRecoilValue } from "recoil"; +import { userState } from "@/atoms/userAtom"; -export default function ProblemForum({ DEPLOY }) { +export default function ProblemForum({ data }) { const [formSelector, setFormSelector] = useState(0); - const [difficulty, setDifficulty] = useState(); const [bountyValue, setBountyValue] = useState(); //not so imp consts... + const [loading, setLoading] = useState(false); const [In, setIn] = useState(""); const [Out, setOut] = useState(""); const [Exp, setExp] = useState(""); const [Cons, setCons] = useState(""); + const [isChecked, setChecked] = useState(false); + const user = useRecoilValue(userState); //consts ends... const [formData, setFormData] = useState({ name: "", description: "", defaultCode: "", compileFunctionName: "", - tags: [], + difficulty: "EASY", examples: [], constraints: [], testcases: [], }); - const [showAlert, setShowAlert] = useState(false); + const difficultyType = ["EASY", "HARD", "MEDIUM"]; + //deployment stuff... + const { DEPLOY, deployed, deployAddress, error } = useDeployQuestion(); + + // console.log("deploying status : ", useDeployQuestion()); + // const stateOfTransaction = useRecoilValue(questionAddStatus); + useEffect(() => { + if (deployAddress != "" && deployed) { + toast.success( + "Contract deployed, will be added soon to dashboard after a review!", + ); + } + }, [deployed, deployAddress, error]); + const [showAlert, setShowAlert] = useState(false); + const checkFormInvalid = () => { + //checking all the input vales sir.... + if (!formData.name) { + toast.error("The name is required!!"); + // alert("the name is required"); + setFormSelector(0); + return true; + } + if (!formData.description) { + toast.error("The description is required!!"); + setFormSelector(0); + return true; + } + if (!formData.examples) { + toast.error("The examples are required!!"); + setFormSelector(1); + return true; + } + if (formData.examples?.length > 0) { + formData.examples.forEach((example) => { + if (!example.input || !example.output || !example.explanation) { + toast.error("The examples are not valid!!"); + setFormSelector(1); + return true; + } + }); + } + if (!formData.testcases) { + toast.error("The testcases are required!!"); + setFormSelector(2); + return true; + } + if (formData.testcases?.length > 0) { + formData.testcases.forEach((testcase) => { + if (!testcase.input || !testcase.output) { + toast.error("The testcases are not valid!!"); + setFormSelector(2); + return true; + } + }); + } + if (!formData.defaultCode) { + toast.error("The default code is required!!"); + setFormSelector(4); + return true; + } + if (!bountyValue) { + toast.error("The bounty value is required!!"); + setFormSelector(5); + return true; + } + // if (typeof parseInt(difficulty) != "number") { + // toast.error("The bounty value is not valid!!"); + // setFormSelector(5); + // return true; + // } + // if (!difficulty) { + // toast.error("The difficulty is required!!"); + // setFormSelector(5); + // return true; + // } + // if (typeof parseInt(difficulty) != "number") { + // toast.error("The difficulty is not valid!!"); + // setFormSelector(5); + // return true; + // } + if (!formData.compileFunctionName) { + toast.error("The compile function name is required!!"); + setFormSelector(4); + return true; + } + return false; + }; useEffect(() => { const timeout = setTimeout(() => { setShowAlert(true); @@ -31,25 +132,28 @@ export default function ProblemForum({ DEPLOY }) { return () => clearTimeout(timeout); }, []); - const handleChange = (e) => { - const { name, value } = e.target; - setFormData({ ...formData, [name]: value }); - }; - - - const handleSubmit = async (e) => { - // setLoading(true); - const re = confirm("you sure doing this..."); - if(!re) return; - //define bounty value and difficulty here..... man bounty in trx... make sure of that... - DEPLOY(difficulty, formData, bountyValue); - //working man + const handleCompileFunctionNameChange = (e) => { + const { value } = e.target; + setFormData({ + ...formData, + compileFunctionName: value, + defaultCode: value + ? `const ${value} = (data) => {\n\t/*\n\t your code goes here\n\t*/\n}` + : "", + }); + }; - }; + const handleSubmit = async (e) => { + if (checkFormInvalid()) return; - return ( -
+ await DEPLOY(formData, bountyValue); + }; + + + return ( +
+
{formSelector == 0 && (
@@ -63,9 +167,11 @@ export default function ProblemForum({ DEPLOY }) { type="text" id="name" name="name" + onChange={(e) => + setFormData({ ...formData, name: e.target.value }) + } value={formData.name} - onChange={handleChange} - className="mt-1 w-full rounded-md border bg-black/40 p-2" + className="mt-1 w-full rounded-md border bg-black/40 p-2 text-white" required /> - + setFormData({ ...formData, description: e.target.value }) + } className="mt-1 w-full rounded-md border bg-black/40 p-2" required /> @@ -172,7 +280,7 @@ export default function ProblemForum({ DEPLOY }) {