diff --git a/package-lock.json b/package-lock.json index eadb7c4..20d0c71 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.28.0" }, "devDependencies": { "@types/react": "^18.0.37", @@ -911,6 +912,14 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", + "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.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", + "dependencies": { + "@remix-run/router": "1.21.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", + "dependencies": { + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" + }, + "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.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==" + }, "@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.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", + "requires": { + "@remix-run/router": "1.21.0" + } + }, + "react-router-dom": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", + "requires": { + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" + } + }, "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..bdc2eb4 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.28.0" }, "devDependencies": { "@types/react": "^18.0.37", diff --git a/src/App.css b/src/App.css index b9d355d..a96e289 100644 --- a/src/App.css +++ b/src/App.css @@ -40,3 +40,89 @@ .read-the-docs { color: #888; } + +nav { + background-color: aqua; + text-align: start; + padding: 1em; + margin: 0; + border: 0; + color: white; + font-weight: bold; +} + +.company-profile { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; +} + +.company-profile > div:first-child { + display: flex; + justify-content: space around; + align-items: center; + flex-direction: column; + margin: 2em; + padding: 1em; + gap: 1em; + border: 1px solid #ccc; + border-radius: 1em; +} +.company-profile img { + height: 200px; + width: auto; + padding: 3em; +} + +.company-profile-techstack { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + flex-wrap: wrap; + gap: 1em; + margin-top: 1em; + +} +.company-profile-techstack :link { + border: 1px solid #ccc; + border-radius: 1em; + padding: 1em; + color: black; +} + +.company-profile-techstack img { + height: 50px; + min-width: 120px; + max-width: 150px; + object-fit: contain; +} + +.company-list { + display: flex; + justify-content: space-between; + align-items: center; + flex-direction: row; + flex-wrap: wrap; +} + +.company-card { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + gap: 1em; + padding: 1em; + border: 1px solid #ccc; + border-radius: 1em; + margin: 1em; +} + +.company-card img { + height: 100px; + min-width: 120px; + max-width: 150px; + object-fit: contain; +} + diff --git a/src/App.jsx b/src/App.jsx index 1b51d87..d74a52f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,11 +1,42 @@ +import { Route, Routes } from "react-router-dom"; import "./App.css"; +import companiesData from "./companies.json"; +import Navbar from "./components/Navbar"; +import technologiesData from "./technologies.json"; +import { useState } from "react"; +import CompanyPage from "./pages/CompanyPage"; +import HomePage from "./pages/HomePage"; +import TechnologyPage from "./pages/TechnologyPage"; function App() { + const [companies, setCompanies] = useState(companiesData); + const [technologies, setTechnologies] = useState(technologiesData); + return (
-

LAB | React Stack Tracker

+ +
+ + + } + /> + } + /> + + } + /> + +
); } -export default App; +export default App; \ No newline at end of file diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 09e2806..55b6495 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,5 +1,5 @@ function Navbar() { - return ; + return ; } export default Navbar; diff --git a/src/main.jsx b/src/main.jsx index 54b39dd..fc363c2 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -3,8 +3,12 @@ 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..e374b03 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -1,8 +1,56 @@ -function CompanyPage() { +import { useParams, Link } from "react-router-dom"; + +function CompanyPage({ companies, technologies }) { + const { companySlug } = useParams(); + console.log(`Company Slug: ${companySlug}`); + + const company = companies.find((company) => company.slug === companySlug); + console.log("Company:", company); + + if (!company) { + return
Error: Company not found
; + } + + // Ensure techStack is an array of slugs + const techStackSlugs = company.techStack.map((tech) => tech.slug || tech); + const companyTechnologies = technologies.filter((technology) => + techStackSlugs.includes(technology.slug) + ); + console.log("Company Technologies:", companyTechnologies); + return ( -
-

CompanyPage

-
+ <> +
+
+ {company.logo ? ( + {company.name} { + e.target.onerror = null; + e.target.src = "https://via.placeholder.com/150"; + }} + /> + ) : ( +

No logo available

+ )} +
+
+

{company.name}

+

About:

+

{company.description}

+
+
+ +
+ {companyTechnologies.map((technology) => ( + + {technology.name} +

{technology.name}

+ + ))} +
+ ); } diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx index e97e7de..8f9e2be 100644 --- a/src/pages/HomePage.jsx +++ b/src/pages/HomePage.jsx @@ -1,9 +1,29 @@ -function HomePage() { +import React from 'react'; +import { Link } from 'react-router-dom'; + +const HomePage = ({ companies, technologies }) => { + if (!Array.isArray(companies)) { + return
Error: companies is not an array
; + } + return ( -
-

HomePage

-
+ <> +

StackTracker: Discover Tech Stacks Used by Top Companies

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

{company.name}

+ {company.name} +
+ + ))} +
+
+ ); -} +}; export default HomePage; + diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 30f9414..c1e6cd7 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,8 +1,34 @@ -function TechnologyPage() { +import { useParams, Link } from "react-router-dom"; + +function TechnologyPage({ technologies }) { + + const { slug } = useParams(); + const technology = technologies.find((technology) => technology.slug === slug); + console.log("Technology:", technology); + + return ( -
-

TechnologyPage

-
+
+
+ {technology.image ? ( + {technology.name} { + e.target.onerror = null; + e.target.src = "https://via.placeholder.com/150"; + }} + /> + ) : ( +

No logo available

+ )} +
+
+

{technology.name}

+

About:

+

{technology.description}

+
+
); }