diff --git a/.eslintrc.cjs b/.eslintrc.cjs index ec601b2..a4d3303 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -11,5 +11,6 @@ module.exports = { plugins: ['react-refresh'], rules: { 'react-refresh/only-export-components': 'warn', + "react/prop-types": 0 }, } diff --git a/package-lock.json b/package-lock.json index eadb7c4..523db35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,10 @@ "name": "lab-react-stack-tracker", "version": "0.0.0", "dependencies": { + "prop-types": "^15.8.1", "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 +913,15 @@ "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==", + "license": "MIT", + "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", @@ -3149,7 +3160,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3469,7 +3479,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -3543,8 +3553,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-refresh": { "version": "0.14.0", @@ -3555,6 +3564,38 @@ "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==", + "license": "MIT", + "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==", + "license": "MIT", + "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 +5058,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", @@ -6672,8 +6718,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.3", @@ -6900,7 +6945,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -6951,8 +6995,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-refresh": { "version": "0.14.0", @@ -6960,6 +7003,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..bfef9d9 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ "test": "vitest --ui" }, "dependencies": { + "prop-types": "^15.8.1", "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..106be49 100644 --- a/src/App.css +++ b/src/App.css @@ -1,8 +1,22 @@ #root { max-width: 1280px; margin: 0 auto; - padding: 2rem; + padding: 4rem 2rem 2rem 2rem; text-align: center; + position: relative; + height: 100vh; + overflow: hidden; +} + +.navbar { + background-color: rgb(226, 169, 226); + padding: 20px; + font-size: 20px; + display: flex; + position: fixed; + width: 100vw; + top: 0; + left: 0; } .logo { @@ -18,6 +32,25 @@ filter: drop-shadow(0 0 2em #61dafbaa); } +.lista-bottom{ + display: flex; + list-style: none; + overflow-x: auto; + padding: 10px; + margin-top: 20px; + border: 1px solid #ccc; +} + +.lista-bottom li { + display: inline-block; + min-width: 200px; + margin-right: 20px; + padding: 10px; + background-color: #f0f0f0; + border: 1px solid #ddd; +} + + @keyframes logo-spin { from { transform: rotate(0deg); @@ -33,8 +66,28 @@ } } -.card { +.list { padding: 2em; + +} + +.list ul { + list-style: none; + justify-content: center; + display: flex; + flex-wrap: wrap; + gap: 20px; +} + +.card{ + border: 2px solid black; + padding: 30px; + box-sizing: border-box; + width: 40%; +} + +.card p { + color: black; } .read-the-docs { diff --git a/src/App.jsx b/src/App.jsx index 1b51d87..efd67a1 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,10 +1,33 @@ +import { useState } from "react"; import "./App.css"; +import companiesData from "./companies.json" +import technologiesData 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 [companies, setCompanies] = useState(companiesData) + const [technologies, setTechnologies] = useState(technologiesData) + return ( -
+ <> + + {/*

LAB | React Stack Tracker

-
+
*/} + + + } /> + } /> + } /> + + + + ); } diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 09e2806..a0bd771 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,5 +1,7 @@ +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..37a9f53 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,10 +1,12 @@ -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..dff980e 100644 --- a/src/pages/CompanyPage.jsx +++ b/src/pages/CompanyPage.jsx @@ -1,8 +1,42 @@ -function CompanyPage() { +import { useParams } from "react-router-dom"; +import { Link } from "react-router-dom"; + +function CompanyPage({companies}) { + + let {company} = useParams() + + const companyData = companies.find((eachCompany) => { + return eachCompany.slug === company + }) + return ( + <>
-

CompanyPage

+

Company Profile

+
+

{companyData.name}

+ logo +

{companyData.description}

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

HomePage

+
+

StackTracker: Discover Tech Stacks Used by Top Companies

+
); } diff --git a/src/pages/TechnologyPage.jsx b/src/pages/TechnologyPage.jsx index 30f9414..60c4bbc 100644 --- a/src/pages/TechnologyPage.jsx +++ b/src/pages/TechnologyPage.jsx @@ -1,7 +1,31 @@ -function TechnologyPage() { +import { useParams } from "react-router-dom" +import { Link } from "react-router-dom"; +import { useSearchParams } from "react-router-dom"; + +function TechnologyPage({technologies}) { + let {tech} = useParams() + let [searchParams] = useSearchParams(); + + const companySlug = searchParams.get('company'); + + const techData = technologies.find((eachTech) => { + return eachTech.slug === tech + }) + return ( +
-

TechnologyPage

+

Technology Details

+ +
+

{techData.name}

+ logo +

{techData.description}

+
+ + + +
); }