Skip to content
Open

done #122

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import "./App.css";
import { useState } from 'react';
import './App.css';
import { Routes, Route } from 'react-router-dom';
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);
Comment on lines +12 to +13

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using useState for static JSON data is unnecessary. The data from JSON imports is already immutable and doesn't need to be stored in state. Remove useState and use the imported data directly: pass companiesData and technologiesData as props instead of companies and technologies.

Copilot uses AI. Check for mistakes.

return (
<div className="App">
<h1>LAB | React Stack Tracker</h1>
<Navbar />

<Routes>
<Route path="/" element={<HomePage companies={companies} />} />
<Route path="/company/:companySlug" element={<CompanyPage companies={companies} />} />
<Route path="/tech/:slug" element={<TechnologyPage technologies={technologies} />} />
</Routes>
</div>
);
}
Expand Down
10 changes: 9 additions & 1 deletion src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Link } from 'react-router-dom';

function Navbar() {
return <nav>Navbar</nav>;
return (
<nav>
<Link to="/">
<h3>StackTracker</h3>
</Link>
</nav>
);
}

export default Navbar;
13 changes: 8 additions & 5 deletions src/main.jsx
Original file line number Diff line number Diff line change
@@ -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 as Router } from 'react-router-dom';

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
<Router>
<App />
</Router>
</React.StrictMode>,
)
43 changes: 40 additions & 3 deletions src/pages/CompanyPage.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
function CompanyPage() {
import { useParams, Link } from 'react-router-dom';

function CompanyPage({ companies }) {
const { companySlug } = useParams();

const company = companies && companies.find((c) => c.slug === companySlug);

if (!company) {
return (
<div className="CompanyPage">
<h1>Company Profile</h1>
<p>Company not found.</p>
<Link to="/">Back to Home</Link>
</div>
);
}

return (
<div>
<h1>CompanyPage</h1>
<div className="CompanyPage">
<h1>Company Profile</h1>

<div className="company-details" style={{ padding: '16px' }}>
<img src={company.logo} alt={company.companyName} style={{ width: '100px', height: '100px', objectFit: 'contain' }} />
<h2>{company.companyName}</h2>
Comment on lines +23 to +24

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The company data uses 'name' property, but the code references 'companyName' which doesn't exist in the JSON structure. This will result in empty alt text and no company name being displayed. Change 'company.companyName' to 'company.name'.

Suggested change
<img src={company.logo} alt={company.companyName} style={{ width: '100px', height: '100px', objectFit: 'contain' }} />
<h2>{company.companyName}</h2>
<img src={company.logo} alt={company.name} style={{ width: '100px', height: '100px', objectFit: 'contain' }} />
<h2>{company.name}</h2>

Copilot uses AI. Check for mistakes.
<p>Website: <a href={`https://${company.website}`} target="_blank" rel="noreferrer">{company.website}</a></p>

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The website URL is directly interpolated without validation. If the website field contains a malicious protocol (e.g., 'javascript:alert(1)'), this could lead to XSS. Consider validating that the website starts with 'www.' or using URL validation before constructing the href.

Copilot uses AI. Check for mistakes.
{company.description && <p>{company.description}</p>}

<h3>Tech Stack</h3>
<div className="tech-stack" style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}>
{company.techStack && company.techStack.map((tech) => (
<Link key={tech.slug} to={`/tech/${tech.slug}?company=${companySlug}`}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: '8px', border: '1px solid #ccc', borderRadius: '8px', width: '80px' }}>
<img src={tech.image} alt={tech.name} style={{ width: '40px', height: '40px', objectFit: 'contain' }} />
<span style={{ marginTop: '4px', fontSize: '12px' }}>{tech.name}</span>
</div>
</Link>
))}
</div>

<Link to="/"><button style={{ marginTop: '16px' }}>Back to Home</button></Link>

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping a button inside a Link creates nested interactive elements, which can cause accessibility and usability issues. Remove the button wrapper and style the Link directly, or use navigate from useNavigate hook instead.

Suggested change
<Link to="/"><button style={{ marginTop: '16px' }}>Back to Home</button></Link>
<Link
to="/"
style={{
display: 'inline-block',
marginTop: '16px',
padding: '8px 16px',
borderRadius: '4px',
border: '1px solid #ccc',
backgroundColor: '#f0f0f0',
textDecoration: 'none',
color: 'inherit',
cursor: 'pointer',
}}
>
Back to Home
</Link>

Copilot uses AI. Check for mistakes.
</div>
</div>
);
}
Expand Down
19 changes: 16 additions & 3 deletions src/pages/HomePage.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
function HomePage() {
import { Link } from 'react-router-dom';

function HomePage({ companies }) {
return (
<div>
<h1>HomePage</h1>
<div className="HomePage">
<h1>StackTracker: Discover Tech Stacks Used by Top Companies</h1>

<div className="company-list">
{companies && companies.map((company) => (
<Link key={company.id} to={`/company/${company.slug}`}>
<div className="company-card" style={{ display: 'flex', alignItems: 'center', gap: '16px', margin: '8px 0', padding: '8px', border: '1px solid #ccc', borderRadius: '8px' }}>
<img src={company.logo} alt={company.companyName} style={{ width: '50px', height: '50px', objectFit: 'contain' }} />
<span>{company.companyName}</span>
Comment on lines +12 to +13

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The company data uses 'name' property, but the code references 'companyName' which doesn't exist in the JSON structure. This will result in empty alt text and no company name being displayed. Change 'company.companyName' to 'company.name'.

Suggested change
<img src={company.logo} alt={company.companyName} style={{ width: '50px', height: '50px', objectFit: 'contain' }} />
<span>{company.companyName}</span>
<img src={company.logo} alt={company.name} style={{ width: '50px', height: '50px', objectFit: 'contain' }} />
<span>{company.name}</span>

Copilot uses AI. Check for mistakes.
</div>
Comment on lines +11 to +14

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extensive inline styles make the code harder to maintain and reuse. Consider moving these styles to CSS classes in a stylesheet, especially for repeated patterns like the card components.

Copilot uses AI. Check for mistakes.
</Link>
))}
</div>
</div>
);
}
Expand Down
40 changes: 37 additions & 3 deletions src/pages/TechnologyPage.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
function TechnologyPage() {
import { useParams, useSearchParams, Link } from 'react-router-dom';

function TechnologyPage({ technologies }) {
const { slug } = useParams();
const [searchParams] = useSearchParams();
const companySlug = searchParams.get('company');

const technology = technologies && technologies.find((t) => t.slug === slug);

if (!technology) {
return (
<div className="TechnologyPage">
<h1>Technology Details</h1>
<p>Technology not found.</p>
<Link to="/">Back to Home</Link>
</div>
);
}

return (
<div>
<h1>TechnologyPage</h1>
<div className="TechnologyPage">
<h1>Technology Details</h1>

<div className="technology-details" style={{ padding: '16px' }}>
<img src={technology.image} alt={technology.name} style={{ width: '100px', height: '100px', objectFit: 'contain' }} />
<h2>{technology.name}</h2>
<p>{technology.description}</p>

{companySlug ? (
<Link to={`/company/${companySlug}`}>
<button style={{ marginTop: '16px' }}>Back to Company</button>
</Link>
) : (
<Link to="/">
<button style={{ marginTop: '16px' }}>Back to Home</button>
Comment on lines +30 to +35

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping a button inside a Link creates nested interactive elements, which can cause accessibility and usability issues. Remove the button wrapper and style the Link directly, or use navigate from useNavigate hook instead.

Suggested change
<Link to={`/company/${companySlug}`}>
<button style={{ marginTop: '16px' }}>Back to Company</button>
</Link>
) : (
<Link to="/">
<button style={{ marginTop: '16px' }}>Back to Home</button>
<Link to={`/company/${companySlug}`} style={{ marginTop: '16px', display: 'inline-block' }}>
Back to Company
</Link>
) : (
<Link to="/" style={{ marginTop: '16px', display: 'inline-block' }}>
Back to Home

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +35

Copilot AI Feb 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping a button inside a Link creates nested interactive elements, which can cause accessibility and usability issues. Remove the button wrapper and style the Link directly, or use navigate from useNavigate hook instead.

Suggested change
<Link to={`/company/${companySlug}`}>
<button style={{ marginTop: '16px' }}>Back to Company</button>
</Link>
) : (
<Link to="/">
<button style={{ marginTop: '16px' }}>Back to Home</button>
<Link
to={`/company/${companySlug}`}
style={{ marginTop: '16px', display: 'inline-block' }}
>
Back to Company
</Link>
) : (
<Link
to="/"
style={{ marginTop: '16px', display: 'inline-block' }}
>
Back to Home

Copilot uses AI. Check for mistakes.
</Link>
)}
</div>
</div>
);
}
Expand Down
Loading