Skip to content
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?

#added
package-lock.json
6 changes: 5 additions & 1 deletion client/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ function App() {
handleClick={handleClick}
data={databaseData}
nextPage="/server"
prevPage="/bundler"
/>
}
/>
Expand All @@ -130,6 +131,7 @@ function App() {
handleClick={handleClick}
data={serverData}
nextPage="/frameworks"
prevPage="/database"
/>
}
/>
Expand All @@ -142,6 +144,7 @@ function App() {
handleClick={handleClick}
data={frameworksData}
nextPage="/styling"
prevPage="/server"
/>
}
/>
Expand All @@ -154,13 +157,14 @@ function App() {
handleClick={handleClick}
data={stylingData}
nextPage="/results"
prevPage="/frameworks"
/>
}
/>

<Route
path="/results"
element={<ResultsPage stackChoices={stackChoices} />}
element={<ResultsPage stackChoices={stackChoices} prevPage="/" />}
/>
</Routes>
);
Expand Down
16 changes: 16 additions & 0 deletions client/components/Card/Card.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ function Card({ option, handleClick, data }) {
<span>{val}</span>
</div>
);
}
if ({ key }.key === "links") {
return (
<div key={i} className={styles.infoBlock}>
<h4>{key}: </h4>
<ul className={styles.list}>
{val.map((point, i) => {
return (
<li key={i}>
<a href={point}>{option.name}</a>
</li>
);
})}
</ul>
</div>
);
} else {
return (
<div key={i} className={styles.infoBlock}>
Expand Down
30 changes: 26 additions & 4 deletions client/components/Card/Card.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,27 @@
}

.mainCard {
background: rgba(255, 255, 255, 0.9);
background: rgba(251, 251, 251, 0.9);
/* background: rgba(253, 253, 253, 0.91); */
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
backdrop-filter: blur(15px);
-webkit-backdrop-filter: blur(15px);
border-radius: 10px;
border-radius: 5px;
border: 1px solid rgba(255, 255, 255, 0.18);
overflow-y: scroll;
width: 200px;
width: 300px;
overflow-wrap: break-word;
hyphens: auto;
max-height: 500px;
height: 500px;
/* min-height: 500px;
max-height: 500px; */
}

::-webkit-scrollbar {
width: 0.5rem;
background-color: white;
border-radius: 20px;

/* left: 0; */
}

Expand Down Expand Up @@ -72,8 +77,25 @@
padding-bottom: 1rem;
list-style: square;
}
.infoBlock h3,
.infoBlock h4 {
text-transform: uppercase;
/* background: linear-gradient(45deg, #a5b4fc 0%, #38bdf8 100%); */
margin-right: 2em;
color: linear-gradient(45deg, #a5b4fc 0%, #38bdf8 100%);
background: -webkit-linear-gradient(#38bdf8, rgb(60 74 88));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}

.list {
list-style: square;
padding-left: 1rem;
}

li a:hover {
color: linear-gradient(45deg, #a5b4fc 0%, #38bdf8 100%);
background: -webkit-linear-gradient(#38bdf8, rgb(60 74 88));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
48 changes: 48 additions & 0 deletions client/components/Card/Card.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import Card from './Card';

describe('Card Tests', () => {

const handleClick = vi.fn()

const props = {
data: {
name: 'Framework Name',
type: 'Bundler/front/back/db',
description: 'a description of this choice',
gitHubStars: 100,
pros: [
'a pro',
'another pro',
'third pro',
],
cons: ['a con', 'another con'],
links: ['https://google.com']

},
handleClick: handleClick,
option: 'placeholder',
}

test("Should render two elements", () => {
render(<Card {...props}/>);
// const cc = screen.getAllByRole('generic');
// expect(cc).toHaveLength(2);
})

// test('Should render passed in text', () => {
// const textProp = "display this";
// render(<Card text={textProp}/>);

// const cc = screen.getByText('display this');
// expect(cc).toBeInTheDocument();
// })

// test('Passed in text should match displayed text', () => {
// const textProp = "display this";
// render(<Card text={textProp}/>);
// const cc = screen.getByText('display this');
// expect(cc).toHaveTextContent('display this');
// })
})
27 changes: 27 additions & 0 deletions client/components/CarouselCard/CarouselCard.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import CarouselCard from './CarouselCard';

describe('Carousel Card Tests', () => {
test("Should render two elements", () => {

render(<CarouselCard />);
const cc = screen.getAllByRole('generic');
expect(cc).toHaveLength(2);
})

test('Should render passed in text', () => {
const textProp = "display this";
render(<CarouselCard text={textProp}/>);

const cc = screen.getByText('display this');
expect(cc).toBeInTheDocument();
})

test('Passed in text should match displayed text', () => {
const textProp = "display this";
render(<CarouselCard text={textProp}/>);
const cc = screen.getByText('display this');
expect(cc).toHaveTextContent('display this');
})
})
126 changes: 126 additions & 0 deletions client/components/Graph/NpmGraph.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import React, {useState, useEffect} from "react";
import { Line } from 'react-chartjs-2'
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from 'chart.js/auto';
import styles from "./NpmGraph.module.css"

const frequency = 7;
function NpmGraph({packageNames, setNpmStats, npmStats}) {
// const [npmStats, setNpmStats] = useState({});
// const fetchData = () => {
// //Join all package packageNames with a ','
// console.log(packageNames)
// let packageNameString = packageNames.join(',');
// console.log(packageNameString)
// //Fetch npm download data over a year range for all package
// fetch(`https://api.npmjs.org/downloads/range/last-year/${packageNameString}`)
// .then(res=>res.json())
// .then(downloadData => {
// setNpmStats(downloadData);
// })
// .catch(err => console.log({err}))
// }

const fetchData = ()=> {
//Join all package packageNames with a ','
// console.log("These are the packageNames: ", packageNames);
let packageNameString = packageNames.join(',');
console.log("This is the packageNameString: ", packageNameString);
//Fetch npm download data over a year range for all package
fetch(`https://api.npmjs.org/downloads/range/last-year/${packageNameString}`)
.then(res=>res.json())
.then(downloadData => {
for (let fw in downloadData) {
// downloadData[fw].downloads = downloadData[fw].downloads.filter((_,i) => i%10==0);
let total = 0;
const {downloads} = downloadData[fw];
const averageDownload = [];
for (let i = 0; i < downloads.length; i++){
if ((i+1)%frequency){
total+=downloads[i].downloads;
}
else{
averageDownload.push({
day: downloads[i].day,
downloads: Math.round(total/frequency*100)/100
});
total = 0;
}
}
console.log({averageDownload})
downloadData[fw].downloads = averageDownload;
}
setNpmStats(downloadData);
console.log("This is the downloadData: ", downloadData)
})
.catch(err => console.log({err}))
};

useEffect(()=> {
console.log("This is the npmStats: ",npmStats)
},[npmStats])


// const testData = [
// {downloads: 12, day:0},
// {downloads: 20, day:1},
// {downloads: 100, day:2},
// {downloads: 2, day:3},
// {downloads: 50, day:4},
// ]

const lineColors = ['blue', 'red', 'green', 'purple', 'orange', 'pink', 'cyan', 'yellow'];
// fill ds with datasets objects
// each line(framework) has to have its own dataset object with label, data, borderColor, and backgroundColor
const ds = [];
let data = {};
// then set datasets within data to ds
if (Object.keys(npmStats).length) {
for (let i = 0; i < packageNames.length; i++) {
ds.push(
{
label: packageNames[i],
data: npmStats[packageNames[i]].downloads.map(({downloads})=>downloads),
borderColor: lineColors[i],
backgroundColor: lineColors[i],
}
)
}

data = {
labels: npmStats[packageNames[0]].downloads.map(({day})=>day), // X-axis columns
datasets: ds
}
}



if (!Object.keys(npmStats).length) return (
<button onClick={()=> fetchData()}>Create Graph</button>
// <div>Waiting for data to fetch</div>
)

if (Object.keys(npmStats).length) {
return(
// <div className={styles.graphContainer}>
<div className="flex justify-center w-3/5 bg-gray-50 opacity-85 rounded-xl my-8 ">
<Line
data={data}
// options={{
// responsive: false
// }}
/>
</div>
);
}
};

export default NpmGraph
3 changes: 3 additions & 0 deletions client/components/Graph/NpmGraph.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.graphContainer {
width: 100%;
}
31 changes: 31 additions & 0 deletions client/components/Home/Home.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import Home from './Home';
// import { describe, test } from 'vitest';
import { getRoles } from '@testing-library/react';

describe('Home Page tests', () => {
test("Should render", () => {

render(
<MemoryRouter>
<Home nextPage={'/next'}/>
</MemoryRouter>
);
const home = screen.getByText('Build Your Tech Stack');
expect(home).toBeInTheDocument();
})

test('Home page should be visible', () => {
render(
<MemoryRouter>
<Home nextPage={'/next'}/>
</MemoryRouter>
);

const home = screen.getByText('Build Your Tech Stack');
expect(home).toBeVisible()


})
})
12 changes: 12 additions & 0 deletions client/components/ProgressBar/ProgressBar.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { render, screen } from '@testing-library/react';
import ProgressBar from './ProgressBar';
// import { describe, test } from 'vitest';

describe('Progress Bar test', () => {
test("Progress bar should display with passed percentage", () => {

render(<ProgressBar completed={20}/>);
const progressBar = screen.getByText('20%');
expect(progressBar).toBeInTheDocument();
})
});
Loading