From 109b7fd9811cd336752e74cf372be8046c629c7b Mon Sep 17 00:00:00 2001 From: rbc33 Date: Fri, 31 Oct 2025 21:45:51 +0100 Subject: [PATCH 1/3] Done --- package-lock.json | 83 ++++++++++++++++++++++++++++++++++- package.json | 3 +- src/App.css | 84 +++++++++++++++++++++++++++--------- src/App.jsx | 34 ++++++++++++--- src/components/Navbar.jsx | 4 +- src/index.css | 72 +++++++++++++++---------------- src/main.jsx | 9 ++-- src/pages/CompanyPage.jsx | 37 +++++++++++++--- src/pages/HomePage.jsx | 26 ++++++++--- src/pages/TechnologyPage.jsx | 12 +++--- 10 files changed, 273 insertions(+), 91 deletions(-) diff --git a/package-lock.json b/package-lock.json index eadb7c4..efb2e66 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.9.5" }, "devDependencies": { "@types/react": "^18.0.37", @@ -1505,6 +1506,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 +3565,44 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.5.tgz", + "integrity": "sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.5.tgz", + "integrity": "sha512-mkEmq/K8tKN63Ae2M7Xgz3c9l9YNbY+NHH6NNeUmLA3kDkhKXRsNb/ZpxaEunvGo2/3YXdk5EJU3Hxp3ocaBPw==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.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 +3771,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5464,6 +5518,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 +7019,23 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-router": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.5.tgz", + "integrity": "sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==", + "requires": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + } + }, + "react-router-dom": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.5.tgz", + "integrity": "sha512-mkEmq/K8tKN63Ae2M7Xgz3c9l9YNbY+NHH6NNeUmLA3kDkhKXRsNb/ZpxaEunvGo2/3YXdk5EJU3Hxp3ocaBPw==", + "requires": { + "react-router": "7.9.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 +7149,11 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 727f1c1..c7a6df6 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.9.5" }, "devDependencies": { "@types/react": "^18.0.37", diff --git a/src/App.css b/src/App.css index b9d355d..85042d7 100644 --- a/src/App.css +++ b/src/App.css @@ -1,42 +1,84 @@ #root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; } .logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; } .logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); + filter: drop-shadow(0 0 2em #646cffaa); } .logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); + filter: drop-shadow(0 0 2em #61dafbaa); } @keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + 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; - } + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } } .card { - padding: 2em; + padding: 2em; } .read-the-docs { - color: #888; + color: #888; +} + +nav { + position: absolute; + top: 0; + left: 0; + display: flex; + justify-content: baseline; + height: 10vh; + width: 100%; + align-items: center; + background-color: purple; + padding: 0.2rem; + font-size: 1.5rem; +} +.App { + text-align: center; + margin-top: 7vh; + font-size: 0.75rem; +} + +.companies { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + padding: 20px; + max-width: 40vw; +} +.companyDet { + display: flex; + justify-content: space-around; + /* max-width: 40vw; */ + margin-bottom: 5vh; +} +.companyDet p { + max-width: 40vh; +} +.stack { + list-style: none; + display: flex; + gap: 2vw; + overflow-x: auto; } diff --git a/src/App.jsx b/src/App.jsx index 1b51d87..62b8e1b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,11 +1,31 @@ -import "./App.css"; +import './App.css' +import { useState } from 'react' +import comp from '/src/companies.json' +import tech from '/src/technologies.json' +import { Routes, Route } from 'react-router-dom' +import HomePage from './pages/HomePage' +import CompanyPage from './pages/CompanyPage' +import TechnologyPage from './pages/TechnologyPage' +import Navbar from './components/Navbar' function App() { - return ( -
-

LAB | React Stack Tracker

-
- ); + const [companies, setCompanies] = useState(comp) + const [technologies, setTechnologies] = useState(tech) + return ( + <> + +
+ + } /> + } + /> + } /> + +
+ + ) } -export default App; +export default App diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 09e2806..a23bfc5 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,5 +1,5 @@ function Navbar() { - return ; + return } -export default Navbar; +export default Navbar diff --git a/src/index.css b/src/index.css index b121ef9..9c10475 100644 --- a/src/index.css +++ b/src/index.css @@ -1,64 +1,64 @@ :root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; } a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; + font-weight: 500; + color: #646cff; + text-decoration: inherit; } a:hover { - color: #535bf2; + color: #535bf2; } -body { +/* body { margin: 0; display: flex; place-items: center; min-width: 320px; min-height: 100vh; -} +} */ h1 { - font-size: 3.2em; - line-height: 1.1; + font-size: 3.2em; + line-height: 1.1; } button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - cursor: pointer; - transition: border-color 0.25s; + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + cursor: pointer; + transition: border-color 0.25s; } button:hover { - border-color: #646cff; + border-color: #646cff; } button:focus, button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; + 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; - } + :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..ebbc939 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -2,9 +2,12 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' import './index.css' +import { BrowserRouter as Router } from 'react-router-dom' ReactDOM.createRoot(document.getElementById('root')).render( - - - , + + + + + ) diff --git a/src/pages/CompanyPage.jsx b/src/pages/CompanyPage.jsx index cc5903c..9352005 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -1,9 +1,32 @@ -function CompanyPage() { - return ( -
-

CompanyPage

-
- ); +import { useParams } from 'react-router-dom' + +function CompanyPage({ companies }) { + const { companySlug } = useParams() + const company = companies.find((c) => c.slug === companySlug) + console.log(company) + return ( +
+

Company Profile

+
+
+ +
+
+

{company.name}

+

About

+

{company.description}

+
+
+
+ {company.techStack.map((st) => ( +
  • + +

    {st.name}

    +
  • + ))} +
    +
    + ) } -export default CompanyPage; +export default CompanyPage diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index e97e7de..0543753 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,9 +1,21 @@ -function HomePage() { - return ( -
    -

    HomePage

    -
    - ); +import { Link } from 'react-router-dom' + +function HomePage({ companies }) { + console.log(companies) + return ( +
    +

    StackTracker: Discover Tech Stacks Used by Top Companies

    +
    + {companies && + companies.map((company) => ( + + +

    {company.name}

    + + ))} +
    +
    + ) } -export default HomePage; +export default HomePage diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 30f9414..86cb907 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,9 +1,9 @@ function TechnologyPage() { - return ( -
    -

    TechnologyPage

    -
    - ); + return ( +
    +

    Technology Details

    +
    + ) } -export default TechnologyPage; +export default TechnologyPage From 1759d9297c2d677f4e04a46af44cf2583543ad99 Mon Sep 17 00:00:00 2001 From: rbc33 Date: Fri, 31 Oct 2025 21:55:33 +0100 Subject: [PATCH 2/3] bonus --- src/App.jsx | 5 ++++- src/pages/CompanyPage.jsx | 8 +++++--- src/pages/TechnologyPage.jsx | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 62b8e1b..d90066d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -21,7 +21,10 @@ function App() { path="/company/:companySlug" element={} /> - } /> + } + /> diff --git a/src/pages/CompanyPage.jsx b/src/pages/CompanyPage.jsx index 9352005..6a941ef 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -1,4 +1,4 @@ -import { useParams } from 'react-router-dom' +import { Link, useParams } from 'react-router-dom' function CompanyPage({ companies }) { const { companySlug } = useParams() @@ -20,8 +20,10 @@ function CompanyPage({ companies }) {
    {company.techStack.map((st) => (
  • - -

    {st.name}

    + + +

    {st.name}

    +
  • ))}
    diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 86cb907..348376f 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,7 +1,21 @@ -function TechnologyPage() { +import { useParams } from 'react-router-dom' + +function TechnologyPage({ technologies }) { + const { slug } = useParams() + const tech = technologies.find((t) => t.slug === slug) return (

    Technology Details

    +
    +
    + +
    +
    +

    {tech.name}

    +

    About

    +

    {tech.description}

    +
    +
    ) } From 943f2ec8a075aae8cb4493cc4c9cda8b76645b89 Mon Sep 17 00:00:00 2001 From: rbc33 Date: Fri, 31 Oct 2025 22:14:19 +0100 Subject: [PATCH 3/3] bonus redo --- src/pages/CompanyPage.jsx | 3 +-- src/pages/HomePage.jsx | 1 - src/pages/TechnologyPage.jsx | 8 +++++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/CompanyPage.jsx b/src/pages/CompanyPage.jsx index 6a941ef..4f8ec1c 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -3,7 +3,6 @@ import { Link, useParams } from 'react-router-dom' function CompanyPage({ companies }) { const { companySlug } = useParams() const company = companies.find((c) => c.slug === companySlug) - console.log(company) return (

    Company Profile

    @@ -20,7 +19,7 @@ function CompanyPage({ companies }) {
    {company.techStack.map((st) => (
  • - +

    {st.name}

    diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index 0543753..cabb16a 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,7 +1,6 @@ import { Link } from 'react-router-dom' function HomePage({ companies }) { - console.log(companies) return (

    StackTracker: Discover Tech Stacks Used by Top Companies

    diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 348376f..49a50e6 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,8 +1,11 @@ -import { useParams } from 'react-router-dom' +import { Link, useParams, useSearchParams } from 'react-router-dom' function TechnologyPage({ technologies }) { const { slug } = useParams() + const [searchParams] = useSearchParams() + const company = searchParams.get('company') const tech = technologies.find((t) => t.slug === slug) + console.log(searchParams) return (

    Technology Details

    @@ -16,6 +19,9 @@ function TechnologyPage({ technologies }) {

    {tech.description}

    + + +
  • ) }