diff --git a/package-lock.json b/package-lock.json index eadb7c4..200c5d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^7.1.5" }, "devDependencies": { "@types/react": "^18.0.37", @@ -935,6 +936,12 @@ "@types/chai": "*" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -1505,6 +1512,15 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "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.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3555,6 +3571,46 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", + "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "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.1.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.5.tgz", + "integrity": "sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.1.5" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", @@ -3723,6 +3779,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", @@ -3990,6 +4052,12 @@ "node": ">=14" } }, + "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", @@ -5038,6 +5106,11 @@ "@types/chai": "*" } }, + "@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -5464,6 +5537,11 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6960,6 +7038,25 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-router": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", + "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", + "requires": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + } + }, + "react-router-dom": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.5.tgz", + "integrity": "sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==", + "requires": { + "react-router": "7.1.5" + } + }, "regexp.prototype.flags": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", @@ -7073,6 +7170,11 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "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==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7274,6 +7376,11 @@ "punycode": "^2.3.0" } }, + "turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 727f1c1..61a7a7c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ }, "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^7.1.5" }, "devDependencies": { "@types/react": "^18.0.37", diff --git a/src/App.css b/src/App.css deleted file mode 100644 index b9d355d..0000000 --- a/src/App.css +++ /dev/null @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/App.jsx b/src/App.jsx index 1b51d87..037aa02 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,9 +1,34 @@ -import "./App.css"; +import { useState } from "react"; + +import companies from "./companies.json"; +import technologies from "./technologies.json"; +import Navbar from "./components/Navbar"; +import { Route, Routes } from "react-router-dom"; +import HomePage from "./pages/HomePage"; +import CompanyPage from "./pages/CompanyPage"; +import TechnologyPage from "./pages/TechnologyPage"; function App() { + const [companyList, setCompanyList] = useState(companies); + const [technologyList, setTechnologyList] = useState(technologies); + return (
-

LAB | React Stack Tracker

+ + + } + /> + } + /> + } + /> +
); } diff --git a/src/components/Navbar.css b/src/components/Navbar.css new file mode 100644 index 0000000..fcc21b2 --- /dev/null +++ b/src/components/Navbar.css @@ -0,0 +1,9 @@ +.navbar{ + background-color: rgb(98, 98, 242); + height: 50px; + color: white; + text-align: left; + padding: 20px 0 0 20px; + font-weight: bolder; + font-size: 1.3rem; +} \ No newline at end of file diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 09e2806..e182a67 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,5 +1,11 @@ +import "../components/Navbar.css"; + function Navbar() { - return ; + return ( + + ); } export default Navbar; diff --git a/src/index.css b/src/index.css index b121ef9..ef33746 100644 --- a/src/index.css +++ b/src/index.css @@ -21,12 +21,10 @@ a:hover { body { margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; + text-align: center; } + h1 { font-size: 3.2em; line-height: 1.1; @@ -50,15 +48,3 @@ button:focus-visible { outline: 4px auto -webkit-focus-ring-color; } -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/main.jsx b/src/main.jsx index 54b39dd..977d4cb 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,10 +1,13 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.jsx' -import './index.css' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.jsx"; +import "./index.css"; +import { BrowserRouter } from "react-router-dom"; -ReactDOM.createRoot(document.getElementById('root')).render( +ReactDOM.createRoot(document.getElementById("root")).render( - - , -) + + + + +); diff --git a/src/pages/CompanyPage.css b/src/pages/CompanyPage.css new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/CompanyPage.jsx b/src/pages/CompanyPage.jsx index cc5903c..d5cbaea 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -1,7 +1,40 @@ -function CompanyPage() { +/* eslint-disable react/prop-types */ +import { NavLink, useParams } from "react-router-dom"; + +import "../pages/CompanyPage.css"; + +function CompanyPage({ companyList }) { + const { companySlug } = useParams(); + + const company = companyList.find((companyObj) => { + return companyObj.slug == companySlug; + }); + return ( -
-

CompanyPage

+
+ {company.name} +
+

About

+

{company.description}

+
+
+
+ {company.techStack.map((techstackObj, i) => { + return ( +
+ + {techstackObj.slug} +

{techstackObj.name}

+
+
+ ); + })} +
+
); } diff --git a/src/pages/HomePage.css b/src/pages/HomePage.css new file mode 100644 index 0000000..9cf0f90 --- /dev/null +++ b/src/pages/HomePage.css @@ -0,0 +1,35 @@ +.card{ + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + gap: 90px; + margin: 100px; + + +} + +.card-content{ + width: 300px; + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); + transition: 0.3s; + height: 200px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 80px; + font-size: 1.5rem; + font-weight: bold; + +} + +.card-content img{ + width: 150px; + height: auto; + margin-top: 20px; +} + +.card-content:hover { + box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); + } diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index e97e7de..a365b1d 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,7 +1,23 @@ -function HomePage() { +/* eslint-disable react/prop-types */ +import { NavLink } from "react-router-dom"; +import "../pages/HomePage.css"; + +function HomePage({ companyListToDisplay }) { return (
-

HomePage

+

StackTracker: Discover Tech Stacks Used by Top Companies

+
+ {companyListToDisplay.map((companyObj) => ( +
+ +
+
{companyObj.name}
+ +
+
+
+ ))} +
); } diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 30f9414..2390fe4 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,7 +1,22 @@ -function TechnologyPage() { +import { useParams } from "react-router-dom"; + +/* eslint-disable react/prop-types */ +function TechnologyPage({ techList }) { + const { slug } = useParams(); + + const technology = techList.find((techObj) => { + return techObj.slug == slug; + }); + console.log(technology); + return ( -
-

TechnologyPage

+
+ {technology.name} +
+

{technology.name}

+

About

+

{technology.description}

+
); }