React + Tailwind
							
								
								
									
										61
									
								
								cdrm-frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@ -11,6 +11,7 @@
 | 
			
		||||
        "@tailwindcss/vite": "^4.1.4",
 | 
			
		||||
        "react": "^19.0.0",
 | 
			
		||||
        "react-dom": "^19.0.0",
 | 
			
		||||
        "react-router-dom": "^7.5.2",
 | 
			
		||||
        "tailwindcss": "^4.1.4"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
@ -1799,6 +1800,15 @@
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/cookie": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
 | 
			
		||||
      "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=18"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/cross-spawn": {
 | 
			
		||||
      "version": "7.0.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
 | 
			
		||||
@ -2928,6 +2938,45 @@
 | 
			
		||||
        "node": ">=0.10.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/react-router": {
 | 
			
		||||
      "version": "7.5.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.2.tgz",
 | 
			
		||||
      "integrity": "sha512-9Rw8r199klMnlGZ8VAsV/I8WrIF6IyJ90JQUdboupx1cdkgYqwnrYjH+I/nY/7cA1X5zia4mDJqH36npP7sxGQ==",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "cookie": "^1.0.1",
 | 
			
		||||
        "set-cookie-parser": "^2.6.0",
 | 
			
		||||
        "turbo-stream": "2.4.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=20.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "react": ">=18",
 | 
			
		||||
        "react-dom": ">=18"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "react-dom": {
 | 
			
		||||
          "optional": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/react-router-dom": {
 | 
			
		||||
      "version": "7.5.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.5.2.tgz",
 | 
			
		||||
      "integrity": "sha512-yk1XW8Fj7gK7flpYBXF3yzd2NbX6P7Kxjvs2b5nu1M04rb5pg/Zc4fGdBNTeT4eDYL2bvzWNyKaIMJX/RKHTTg==",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "react-router": "7.5.2"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=20.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "react": ">=18",
 | 
			
		||||
        "react-dom": ">=18"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/resolve-from": {
 | 
			
		||||
      "version": "4.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
 | 
			
		||||
@ -2993,6 +3042,12 @@
 | 
			
		||||
        "semver": "bin/semver.js"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/set-cookie-parser": {
 | 
			
		||||
      "version": "2.7.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
 | 
			
		||||
      "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/shebang-command": {
 | 
			
		||||
      "version": "2.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
 | 
			
		||||
@ -3082,6 +3137,12 @@
 | 
			
		||||
        "url": "https://github.com/sponsors/SuperchupuDev"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/turbo-stream": {
 | 
			
		||||
      "version": "2.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
 | 
			
		||||
      "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
 | 
			
		||||
      "license": "ISC"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/type-check": {
 | 
			
		||||
      "version": "0.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@
 | 
			
		||||
    "@tailwindcss/vite": "^4.1.4",
 | 
			
		||||
    "react": "^19.0.0",
 | 
			
		||||
    "react-dom": "^19.0.0",
 | 
			
		||||
    "react-router-dom": "^7.5.2",
 | 
			
		||||
    "tailwindcss": "^4.1.4"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,45 @@
 | 
			
		||||
import NavBarMain from "./components/NavBarMain"
 | 
			
		||||
import HomePage from "./components/HomePage";
 | 
			
		||||
import NavBar from "./components/NavBar";
 | 
			
		||||
import NavBarMain from "./components/NavBarMain";
 | 
			
		||||
import SideMenu from "./components/SideMenu"; // New side menu component
 | 
			
		||||
import { Routes, Route } from "react-router-dom";
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
 | 
			
		||||
function App() {
 | 
			
		||||
  const [isMenuOpen, setIsMenuOpen] = useState(false);
 | 
			
		||||
 | 
			
		||||
  // Function to toggle the side menu
 | 
			
		||||
  const handleMenuToggle = () => {
 | 
			
		||||
    setIsMenuOpen(prevState => !prevState);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div id="appcontainer" className="flex flex-row w-full h-full bg-black">
 | 
			
		||||
      <div id="navbarcontainer" className="hidden lg:flex lg:w-2xs bg-gray-950/55 border-r border-white/5 shadow-lg shadow-blue-900/50"> 
 | 
			
		||||
      <div
 | 
			
		||||
        id="navbarcontainer"
 | 
			
		||||
        className="hidden lg:flex lg:w-2xs bg-gray-950/55 border-r border-white/5 shadow-lg shadow-blue-900/50"
 | 
			
		||||
      >
 | 
			
		||||
        <NavBar />
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div id="maincontainer" className="w-full lg:w-5/6 bg-gray-950/50 flex flex-col">
 | 
			
		||||
        <div id="navbarmaincontainer" className="w-full lg:hidden h-16 bg-gray-950/10 border-b border-white/5 shadow-md shadow-blue-900/35 sticky top-0 z-10">
 | 
			
		||||
          <NavBarMain />
 | 
			
		||||
        <div
 | 
			
		||||
          id="navbarmaincontainer"
 | 
			
		||||
          className="w-full lg:hidden h-16 bg-gray-950/10 border-b border-white/5 shadow-md shadow-blue-900/35 sticky top-0 z-10"
 | 
			
		||||
        >
 | 
			
		||||
          <NavBarMain handleMenuToggle={handleMenuToggle} />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div id="maincontentcontainer" className="w-full grow">
 | 
			
		||||
          <Routes>
 | 
			
		||||
            <Route path="/" element={<HomePage />} />
 | 
			
		||||
          </Routes>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <SideMenu isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen} /> {/* Pass setIsMenuOpen as a prop */}
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default App
 | 
			
		||||
export default App;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/api.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <path d="M7 8L3 11.6923L7 16M17 8L21 11.6923L17 16M14 4L10 20" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 602 B  | 
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/cache.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg height="800px" width="800px" version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve" fill="#000000">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <style type="text/css"> .st0{fill:#ffffff;} </style> <g> <path class="st0" d="M0,17.067V153.6h512V17.067H0z M110.933,110.925h-51.2v-51.2h51.2V110.925z"/> <path class="st0" d="M0,324.267h512V187.733H0V324.267z M59.733,230.391h51.2v51.2h-51.2V230.391z"/> <path class="st0" d="M0,494.933h512V358.4H0V494.933z M59.733,401.058h51.2v51.2h-51.2V401.058z"/> </g> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 905 B  | 
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/close.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <circle cx="12" cy="12" r="10" stroke="#ffffff" stroke-width="1.5"/> <path d="M14.5 9.50002L9.5 14.5M9.49998 9.5L14.5 14.5" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round"/> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 641 B  | 
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/discord.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg width="800px" height="800px" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" fill="#ffffff">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <g id="Layer_2" data-name="Layer 2"> <g id="invisible_box" data-name="invisible box"> <rect width="48" height="48" fill="none"/> </g> <g id="Icons"> <g> <path d="M20.1,20.5a2.3,2.3,0,0,0-2.2,2.4,2.3,2.3,0,0,0,2.2,2.4,2.4,2.4,0,0,0,0-4.8Z"/> <path d="M28,20.5a2.4,2.4,0,1,0,2.2,2.4A2.3,2.3,0,0,0,28,20.5Z"/> <path d="M38.5,2H9.5A4.5,4.5,0,0,0,5,6.5V36.3a4.5,4.5,0,0,0,4.5,4.5H34.1l-1.2-4.1,2.8,2.7,2.6,2.4L43,46V6.5A4.5,4.5,0,0,0,38.5,2ZM30.2,30.7l-1.5-1.8a6.9,6.9,0,0,0,4-2.6,15.1,15.1,0,0,1-2.5,1.3,14.6,14.6,0,0,1-3.2,1,15,15,0,0,1-5.6,0,20.2,20.2,0,0,1-3.2-1l-1.6-.7h-.2c0-.1,0-.1-.1-.1l-.6-.4a6.9,6.9,0,0,0,3.8,2.6l-1.4,1.8a8,8,0,0,1-6.7-3.3,29,29,0,0,1,3.2-12.8,10.3,10.3,0,0,1,6.1-2.3l.2.2a15.4,15.4,0,0,0-5.7,2.9l1.3-.6a12.7,12.7,0,0,1,4.9-1.4h.4a20.6,20.6,0,0,1,4.3,0,16.3,16.3,0,0,1,6.6,2.1,13.5,13.5,0,0,0-5.4-2.8l.3-.3a10.3,10.3,0,0,1,6.1,2.3,29.7,29.7,0,0,1,3.1,12.8S35,30.6,30.2,30.7Z"/> </g> </g> </g> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										9
									
								
								cdrm-frontend/src/assets/icons/gitea.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,9 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier">
 | 
			
		||||
<path d="M4.209 4.603c-.247 0-.525.02-.84.088-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768 1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367 2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068 0 0 2.107-4.471 2.107-8.823-.042-1.318-.367-1.55-.443-1.627-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12zm8.33 2.554c.26.003.509.127.509.127l.868.422-.529 1.075a.686.686 0 0 0-.614.359.685.685 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527.687.687 0 0 0 .347.763.686.686 0 0 0 .867-.206.688.688 0 0 0-.069-.882l.916-1.874a.667.667 0 0 0 .237-.02.657.657 0 0 0 .271-.137 8.826 8.826 0 0 1 1.016.512.761.761 0 0 1 .286.282c.073.21-.073.569-.073.569-.087.29-.702 1.55-.702 1.55a.692.692 0 0 0-.676.477.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431.19-.397.515-1.16.515-1.16.035-.066.218-.394.103-.814-.095-.435-.48-.638-.48-.638-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.688.688 0 0 0-.148-.241l.516-1.062 2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.065 1.065 0 0 1-.393-.045l-.202-.08-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.855.855 0 0 1 .35-.077z"/>
 | 
			
		||||
</g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/home.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="#ffffff">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M8 0L0 6V8H1V15H4V10H7V15H15V8H16V6L14 4.5V1H11V2.25L8 0ZM9 10H12V13H9V10Z" fill="#ffffff"/> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 615 B  | 
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/telegram.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <title>telegram</title> <path d="M22.122 10.040c0.006-0 0.014-0 0.022-0 0.209 0 0.403 0.065 0.562 0.177l-0.003-0.002c0.116 0.101 0.194 0.243 0.213 0.403l0 0.003c0.020 0.122 0.031 0.262 0.031 0.405 0 0.065-0.002 0.129-0.007 0.193l0-0.009c-0.225 2.369-1.201 8.114-1.697 10.766-0.21 1.123-0.623 1.499-1.023 1.535-0.869 0.081-1.529-0.574-2.371-1.126-1.318-0.865-2.063-1.403-3.342-2.246-1.479-0.973-0.52-1.51 0.322-2.384 0.221-0.23 4.052-3.715 4.127-4.031 0.004-0.019 0.006-0.040 0.006-0.062 0-0.078-0.029-0.149-0.076-0.203l0 0c-0.052-0.034-0.117-0.053-0.185-0.053-0.045 0-0.088 0.009-0.128 0.024l0.002-0.001q-0.198 0.045-6.316 4.174c-0.445 0.351-1.007 0.573-1.619 0.599l-0.006 0c-0.867-0.105-1.654-0.298-2.401-0.573l0.074 0.024c-0.938-0.306-1.683-0.467-1.619-0.985q0.051-0.404 1.114-0.827 6.548-2.853 8.733-3.761c1.607-0.853 3.47-1.555 5.429-2.010l0.157-0.031zM15.93 1.025c-8.302 0.020-15.025 6.755-15.025 15.060 0 8.317 6.742 15.060 15.060 15.060s15.060-6.742 15.060-15.060c0-8.305-6.723-15.040-15.023-15.060h-0.002q-0.035-0-0.070 0z"/> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.5 KiB  | 
							
								
								
									
										7
									
								
								cdrm-frontend/src/assets/icons/testplayer.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 | 
			
		||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
 | 
			
		||||
<svg fill="#ffffff" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 491.52 491.52" xml:space="preserve">
 | 
			
		||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
 | 
			
		||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
 | 
			
		||||
<g id="SVGRepo_iconCarrier"> <g> <g> <path d="M0,0v327.68h491.52V0H0z M471.04,307.2H20.48V20.48h450.56V307.2z"/> </g> </g> <g> <g> <path d="M194.56,87.77v141.9l122.88-70.95L194.56,87.77z M215.04,123.25l61.44,35.47l-61.44,35.47V123.25z"/> </g> </g> <g> <g> <path d="M183.285,430.08c-4.758-23.34-25.441-40.96-50.165-40.96s-45.407,17.62-50.165,40.96H0v20.48h82.955 c4.758,23.34,25.441,40.96,50.165,40.96s45.407-17.62,50.165-40.96H491.52v-20.48H183.285z M133.12,471.04 c-16.94,0-30.72-13.78-30.72-30.72s13.78-30.72,30.72-30.72s30.72,13.78,30.72,30.72S150.06,471.04,133.12,471.04z"/> </g> </g> </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
							
								
								
									
										10
									
								
								cdrm-frontend/src/components/HomePage.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
			
		||||
function HomePage () {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="flex flex-col w-full h-full">
 | 
			
		||||
        </div>
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default HomePage
 | 
			
		||||
							
								
								
									
										116
									
								
								cdrm-frontend/src/components/NavBar.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,116 @@
 | 
			
		||||
import { NavLink } from 'react-router-dom';
 | 
			
		||||
import homeIcon from '../assets/icons/home.svg';
 | 
			
		||||
import cacheIcon from '../assets/icons/cache.svg';
 | 
			
		||||
import apiIcon from '../assets/icons/api.svg';
 | 
			
		||||
import testPlayerIcon from '../assets/icons/testplayer.svg';
 | 
			
		||||
import discordIcon from '../assets/icons/discord.svg';
 | 
			
		||||
import telegramIcon from '../assets/icons/telegram.svg';
 | 
			
		||||
import giteaIcon from '../assets/icons/gitea.svg';
 | 
			
		||||
 | 
			
		||||
function NavBar() {
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="flex flex-col w-full h-full bg-white/1">
 | 
			
		||||
            <div>
 | 
			
		||||
                <p className='text-white text-2xl font-bold p-3 text-center mb-5 bg-black/25'>
 | 
			
		||||
                    <a href='/'>
 | 
			
		||||
                        CDRM-Project
 | 
			
		||||
                    </a>
 | 
			
		||||
                </p>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className='overflow-y-auto grow'>
 | 
			
		||||
                <NavLink
 | 
			
		||||
                    to='/'
 | 
			
		||||
                    className={({ isActive }) =>
 | 
			
		||||
                        `flex flex-row p-3 border-l-3 ${isActive ? 'border-l-sky-500/50 bg-black/50' : 'hover:border-l-sky-500/50 hover:bg-white/5'}`
 | 
			
		||||
                    }
 | 
			
		||||
                >
 | 
			
		||||
                    <button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
 | 
			
		||||
                        <img src={homeIcon} alt="Home" className='w-1/2 cursor-pointer' />
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
 | 
			
		||||
                        Home
 | 
			
		||||
                    </p>
 | 
			
		||||
                </NavLink>
 | 
			
		||||
                <NavLink
 | 
			
		||||
                    to='/cache'
 | 
			
		||||
                    className={({ isActive }) =>
 | 
			
		||||
                        `flex flex-row p-3 border-l-3 ${isActive ? 'border-l-emerald-500/50 bg-black/50' : 'hover:border-l-emerald-500/50 hover:bg-white/5'}`
 | 
			
		||||
                    }
 | 
			
		||||
                >
 | 
			
		||||
                    <button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
 | 
			
		||||
                        <img src={cacheIcon} alt="Cache" className='w-1/2 cursor-pointer' />
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
 | 
			
		||||
                        Cache
 | 
			
		||||
                    </p>
 | 
			
		||||
                </NavLink>
 | 
			
		||||
                <NavLink
 | 
			
		||||
                    to='/api'
 | 
			
		||||
                    className={({ isActive }) =>
 | 
			
		||||
                        `flex flex-row p-3 border-l-3 ${isActive ? 'border-l-indigo-500/50 bg-black/50' : 'hover:border-l-indigo-500/50 hover:bg-white/5'}`
 | 
			
		||||
                    }
 | 
			
		||||
                >
 | 
			
		||||
                    <button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
 | 
			
		||||
                        <img src={apiIcon} alt="API" className='w-1/2 cursor-pointer' />
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
 | 
			
		||||
                        API
 | 
			
		||||
                    </p>
 | 
			
		||||
                </NavLink>
 | 
			
		||||
                <NavLink
 | 
			
		||||
                    to='/testplayer'
 | 
			
		||||
                    className={({ isActive }) =>
 | 
			
		||||
                        `flex flex-row p-3 border-l-3 ${isActive ? 'border-l-rose-700/50 bg-black/50' : 'hover:border-l-rose-700/50 hover:bg-white/5'}`
 | 
			
		||||
                    }
 | 
			
		||||
                >
 | 
			
		||||
                    <button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
 | 
			
		||||
                        <img src={testPlayerIcon} alt="Test Player" className='w-1/2 cursor-pointer' />
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
 | 
			
		||||
                        Test Player
 | 
			
		||||
                    </p>
 | 
			
		||||
                </NavLink>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className='flex flex-row w-full h-16 self-end bg-black/25'>
 | 
			
		||||
                <a
 | 
			
		||||
                    href='https://discord.cdrm-project.com'
 | 
			
		||||
                    target='_blank'
 | 
			
		||||
                    rel='noopener noreferrer'
 | 
			
		||||
                    className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer hover:bg-blue-950 group'
 | 
			
		||||
                >
 | 
			
		||||
                    <img
 | 
			
		||||
                        src={discordIcon}
 | 
			
		||||
                        alt="Discord"
 | 
			
		||||
                        className='w-1/2 cursor-pointer group-hover:animate-bounce'
 | 
			
		||||
                    />
 | 
			
		||||
                </a>
 | 
			
		||||
                <a
 | 
			
		||||
                    href='https://telegram.cdrm-project.com'
 | 
			
		||||
                    target='_blank'
 | 
			
		||||
                    rel='noopener noreferrer'
 | 
			
		||||
                    className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer hover:bg-blue-400 group'
 | 
			
		||||
                >
 | 
			
		||||
                    <img
 | 
			
		||||
                        src={telegramIcon}
 | 
			
		||||
                        alt="Telegram"
 | 
			
		||||
                        className='w-1/2 cursor-pointer group-hover:animate-bounce'
 | 
			
		||||
                    />
 | 
			
		||||
                </a>
 | 
			
		||||
                <a
 | 
			
		||||
                    href='https://cdm-project.com/tpd94/cdrm-project'
 | 
			
		||||
                    target='_blank'
 | 
			
		||||
                    rel='noopener noreferrer'
 | 
			
		||||
                    className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer hover:bg-green-700 group'
 | 
			
		||||
                >
 | 
			
		||||
                    <img
 | 
			
		||||
                        src={giteaIcon}
 | 
			
		||||
                        alt="Gitea"
 | 
			
		||||
                        className='w-1/2 cursor-pointer group-hover:animate-bounce'
 | 
			
		||||
                    />
 | 
			
		||||
                </a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default NavBar;
 | 
			
		||||
@ -1,18 +1,18 @@
 | 
			
		||||
import hamburgerIcon from '../assets/icons/hamburger.svg'
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
import hamburgerIcon from '../assets/icons/hamburger.svg';
 | 
			
		||||
 | 
			
		||||
function NavBarMain () {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="flex flex-row w-full h-full">
 | 
			
		||||
            <button className="w-24 p-4">
 | 
			
		||||
                <img src={hamburgerIcon} alt="Menu" className="w-full h-full cursor-pointer" />
 | 
			
		||||
            </button>
 | 
			
		||||
            <p className='grow text-white text-2xl font-bold text-center flex items-center justify-center'>
 | 
			
		||||
                CDRM-Project
 | 
			
		||||
            </p>
 | 
			
		||||
        </div>
 | 
			
		||||
    )
 | 
			
		||||
function NavBarMain({ handleMenuToggle }) {  // Receive handleMenuToggle as a prop
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="flex flex-row w-full h-full bg-white/1">
 | 
			
		||||
      <button className="w-24 p-4" onClick={handleMenuToggle}>
 | 
			
		||||
        <img src={hamburgerIcon} alt="Menu" className="w-full h-full cursor-pointer" />
 | 
			
		||||
      </button>
 | 
			
		||||
      <p className="grow text-white md:text-2xl font-bold text-center flex items-center justify-center p-4">
 | 
			
		||||
        CDRM-Project
 | 
			
		||||
      </p>
 | 
			
		||||
      <div className="w-24 p-4"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default NavBarMain
 | 
			
		||||
export default NavBarMain;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										122
									
								
								cdrm-frontend/src/components/SideMenu.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,122 @@
 | 
			
		||||
import closeIcon from '../assets/icons/close.svg';
 | 
			
		||||
import discordIcon from '../assets/icons/discord.svg';
 | 
			
		||||
import telegramIcon from '../assets/icons/telegram.svg';
 | 
			
		||||
import giteaIcon from '../assets/icons/gitea.svg';
 | 
			
		||||
import { NavLink } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
function SideMenu({ isMenuOpen, setIsMenuOpen }) {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <div
 | 
			
		||||
        className={`flex flex-col fixed top-0 left-0 w-full h-full bg-black transition-transform transform ${
 | 
			
		||||
          isMenuOpen ? 'translate-x-0' : '-translate-x-full'
 | 
			
		||||
        } z-50`}
 | 
			
		||||
        style={{ transitionDuration: '0.3s' }}
 | 
			
		||||
      >
 | 
			
		||||
        <div className="grow flex flex-col bg-gray-950/55">
 | 
			
		||||
          <div className="h-16 w-full border-b-2 border-white/5 flex flex-row">
 | 
			
		||||
            <div className="w-1/4 h-full"></div>
 | 
			
		||||
            <p className="grow text-white md:text-2xl font-bold text-center flex items-center justify-center p-4">
 | 
			
		||||
              CDRM-Project
 | 
			
		||||
            </p>
 | 
			
		||||
            <div className="w-1/4 h-full">
 | 
			
		||||
              <button
 | 
			
		||||
                className="w-full h-full flex items-center justify-center"
 | 
			
		||||
                onClick={() => setIsMenuOpen(false)}
 | 
			
		||||
              >
 | 
			
		||||
                <img src={closeIcon} alt="Close" className="w-1/2 h-1/2 cursor-pointer" />
 | 
			
		||||
              </button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div className="overflow-y-auto grow flex flex-col p-5 w-full space-y-2">
 | 
			
		||||
            <NavLink
 | 
			
		||||
              to="/"
 | 
			
		||||
              className={({ isActive }) =>
 | 
			
		||||
                `flex flex-row p-3 border-l-4 ${
 | 
			
		||||
                  isActive
 | 
			
		||||
                    ? 'border-l-sky-500/50 bg-black/50 text-white'
 | 
			
		||||
                    : 'border-transparent hover:border-l-sky-500/50 hover:bg-white/5 text-white/80'
 | 
			
		||||
                }`
 | 
			
		||||
              }
 | 
			
		||||
              onClick={() => setIsMenuOpen(false)}
 | 
			
		||||
            >
 | 
			
		||||
              Home
 | 
			
		||||
            </NavLink>
 | 
			
		||||
 | 
			
		||||
            <NavLink
 | 
			
		||||
              to="/cache"
 | 
			
		||||
              className={({ isActive }) =>
 | 
			
		||||
                `flex flex-row p-3 border-l-4 ${
 | 
			
		||||
                  isActive
 | 
			
		||||
                    ? 'border-l-emerald-500/50 bg-black/50 text-white'
 | 
			
		||||
                    : 'border-transparent hover:border-l-emerald-500/50 hover:bg-white/5 text-white/80'
 | 
			
		||||
                }`
 | 
			
		||||
              }
 | 
			
		||||
              onClick={() => setIsMenuOpen(false)}
 | 
			
		||||
            >
 | 
			
		||||
              Cache
 | 
			
		||||
            </NavLink>
 | 
			
		||||
 | 
			
		||||
            <NavLink
 | 
			
		||||
              to="/api"
 | 
			
		||||
              className={({ isActive }) =>
 | 
			
		||||
                `flex flex-row p-3 border-l-4 ${
 | 
			
		||||
                  isActive
 | 
			
		||||
                    ? 'border-l-indigo-500/50 bg-black/50 text-white'
 | 
			
		||||
                    : 'border-transparent hover:border-l-indigo-500/50 hover:bg-white/5 text-white/80'
 | 
			
		||||
                }`
 | 
			
		||||
              }
 | 
			
		||||
              onClick={() => setIsMenuOpen(false)}
 | 
			
		||||
            >
 | 
			
		||||
              API
 | 
			
		||||
            </NavLink>
 | 
			
		||||
 | 
			
		||||
            <NavLink
 | 
			
		||||
              to="/testplayer"
 | 
			
		||||
              className={({ isActive }) =>
 | 
			
		||||
                `flex flex-row p-3 border-l-4 ${
 | 
			
		||||
                  isActive
 | 
			
		||||
                    ? 'border-l-rose-700/50 bg-black/50 text-white'
 | 
			
		||||
                    : 'border-transparent hover:border-l-rose-700/50 hover:bg-white/5 text-white/80'
 | 
			
		||||
                }`
 | 
			
		||||
              }
 | 
			
		||||
              onClick={() => setIsMenuOpen(false)}
 | 
			
		||||
            >
 | 
			
		||||
              Test Player
 | 
			
		||||
            </NavLink>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div className="h-16 self-end w-full flex flex-row bg-white/5">
 | 
			
		||||
            <a
 | 
			
		||||
              href="https://discord.cdrm-project.com/"
 | 
			
		||||
              target="_blank"
 | 
			
		||||
              rel="noopener noreferrer"
 | 
			
		||||
              className="w-1/3 h-full flex items-center justify-center hover:bg-blue-950"
 | 
			
		||||
            >
 | 
			
		||||
              <img src={discordIcon} alt="Discord" className="w-full h-full p-1 cursor-pointer" />
 | 
			
		||||
            </a>
 | 
			
		||||
            <a
 | 
			
		||||
              href="https://telegram.cdrm-project.com"
 | 
			
		||||
              target="_blank"
 | 
			
		||||
              rel="noopener noreferrer"
 | 
			
		||||
              className="w-1/3 h-full flex items-center justify-center hover:bg-blue-400"
 | 
			
		||||
            >
 | 
			
		||||
              <img src={telegramIcon} alt="Telegram" className="w-full h-full p-1 cursor-pointer" />
 | 
			
		||||
            </a>
 | 
			
		||||
            <a
 | 
			
		||||
              href="https://cdm-project.com/tpd94/cdrm-project"
 | 
			
		||||
              target="_blank"
 | 
			
		||||
              rel="noopener noreferrer"
 | 
			
		||||
              className="w-1/3 h-full flex items-center justify-center hover:bg-green-700"
 | 
			
		||||
            >
 | 
			
		||||
              <img src={giteaIcon} alt="Gitea" className="w-full h-full p-1 cursor-pointer" />
 | 
			
		||||
            </a>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default SideMenu;
 | 
			
		||||
@ -1,10 +1,13 @@
 | 
			
		||||
import { StrictMode } from 'react'
 | 
			
		||||
import { createRoot } from 'react-dom/client'
 | 
			
		||||
import { BrowserRouter } from 'react-router-dom'
 | 
			
		||||
import './index.css'
 | 
			
		||||
import App from './App.jsx'
 | 
			
		||||
 | 
			
		||||
createRoot(document.getElementById('root')).render(
 | 
			
		||||
  <StrictMode>
 | 
			
		||||
    <App />
 | 
			
		||||
  </StrictMode>,
 | 
			
		||||
    <BrowserRouter>
 | 
			
		||||
      <App />
 | 
			
		||||
    </BrowserRouter>
 | 
			
		||||
  </StrictMode>
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||