diff --git a/index.html b/index.html index ba47f90..5e41a42 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - LAB Stack Tracker + LAB | Stack Tracker
diff --git a/package-lock.json b/package-lock.json index eadb7c4..f54dd87 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": "^6.26.2" }, "devDependencies": { "@types/react": "^18.0.37", @@ -911,6 +912,14 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", + "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -3555,6 +3564,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz", + "integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==", + "dependencies": { + "@remix-run/router": "1.19.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz", + "integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==", + "dependencies": { + "@remix-run/router": "1.19.2", + "react-router": "6.26.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", @@ -5017,6 +5056,11 @@ "fastq": "^1.6.0" } }, + "@remix-run/router": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", + "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==" + }, "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -6960,6 +7004,23 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-router": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz", + "integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==", + "requires": { + "@remix-run/router": "1.19.2" + } + }, + "react-router-dom": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz", + "integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==", + "requires": { + "@remix-run/router": "1.19.2", + "react-router": "6.26.2" + } + }, "regexp.prototype.flags": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", diff --git a/package.json b/package.json index 727f1c1..c8efc6a 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": "^6.26.2" }, "devDependencies": { "@types/react": "^18.0.37", diff --git a/src/App.css b/src/App.css index b9d355d..bb8698d 100644 --- a/src/App.css +++ b/src/App.css @@ -1,7 +1,6 @@ #root { max-width: 1280px; margin: 0 auto; - padding: 2rem; text-align: center; } @@ -18,6 +17,66 @@ filter: drop-shadow(0 0 2em #61dafbaa); } +.App { + height: 100vh; +} + +.App nav { + background-color: #b8dbff; + color: rgb(80, 80, 80); + padding: 1rem; + display: flex; + justify-content: space-around; + align-items: center; + margin-top: 0; + padding: 1rem; + font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; + font-size: 1.2rem; + font-weight: 600; +} + +h1 { + font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif; + font-size: 2rem; + padding: 1rem; +} + +ul, li { + list-style: none; +} + +ul { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 2rem; + padding: 2rem; +} + +li { + display: flex; + align-items: center; + justify-content: space-around; + gap: 1rem; + background: #e7e7e7; + border: 1px solid #ffee52; + box-shadow: 0 2px 5px rgba(219, 219, 219, 0.1); + border-radius: 10px; + padding: 2rem; + font-family: 'Courier New', Courier, monospace; + font-size: 1rem; +} + +ul img { + margin-top: 1rem; +} + +.tech-container { + padding: 50px; +} +.tech-container img, .tech-stack-container img { + width: 50px; +} + @keyframes logo-spin { from { transform: rotate(0deg); diff --git a/src/App.jsx b/src/App.jsx index 1b51d87..e5a53a3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,9 +1,44 @@ +import { useState } from "react"; +import { Route, Routes, Link } from 'react-router-dom' import "./App.css"; +import companiesData from './companies.json' +import technologiesData from './technologies.json' +import Navbar from "./components/Navbar"; +import HomePage from "./pages/HomePage"; +import CompanyPage from "./pages/CompanyPage"; +import TechnologyPage from "./pages/TechnologyPage"; function App() { + + const [ companies ] = useState(companiesData) + const [ technologies ] = useState(technologiesData) + return (
-

LAB | React Stack Tracker

+ + {/*
+ {companies.map(company => ( +
{company.name}
+ ))} +
+
+ {technologies.map(technology => ( +
{technology.name}
+ ))} +
*/} + + {/* info showed fine; dynamic parameters needed to work with the data stored in json */} + + + + + + }/> + }/> + }/> + + +
); } diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 09e2806..8e092b8 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,5 +1,17 @@ +import { Link } from "react-router-dom"; + function Navbar() { - return ; + return ( + + + ) } export default Navbar; diff --git a/src/main.jsx b/src/main.jsx index 54b39dd..536ff4f 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -2,9 +2,11 @@ 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( - + + - , + ) diff --git a/src/pages/CompanyPage.jsx b/src/pages/CompanyPage.jsx index cc5903c..1ca9218 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -1,7 +1,38 @@ -function CompanyPage() { +import { useParams, Link } from "react-router-dom"; + +function CompanyPage({ companies }) { + // following feedback steps below + // access url params to get the company slug + const { companySlug } = useParams(); + + // uses find method to get matching company slug + const companyToDisplay = companies.find( + (company) => company.slug === companySlug + ); + + // guard clause in case the company doesn't appear + if (!companyToDisplay) { + return

company not found

; + } + return ( -
-

CompanyPage

+
+ +

{companyToDisplay.name}

+

{companyToDisplay.description}

+ +
); } diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index e97e7de..de6e499 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,7 +1,22 @@ -function HomePage() { +import { Link } from "react-router-dom"; + +function HomePage({ companiesData }) { return (
-

HomePage

+

StackTracker: Discover Tech Stacks Used by Top Companies

+ + +
); } diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 30f9414..3f15cd0 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,7 +1,35 @@ -function TechnologyPage() { +import { useParams, useSearchParams, Link } from "react-router-dom"; + +function TechnologyPage({ technologies }) { + + const { techSlug } = useParams() + // adding the visited company slug from the query param passed from CompanyPage + // using searchParams to get it + const [searchParams] = useSearchParams() + + + const companySlug = searchParams.get("company") + + // console.log(techSlug); + // console.log(technologies) + + const techToDisplay = technologies.find((tech) => tech.slug === techSlug) + + if (!techToDisplay) { + return

tech not foudn

+ } + + return ( -
-

TechnologyPage

+
+ +

{techToDisplay.name}

+

{techToDisplay.description}

+ + {/* back-btn to navigate to the previous company page using the query param shared before */} + + +
); }