Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
bb815c3
install project dependencies
acl13 Mar 18, 2025
74a611a
create product schema
acl13 Mar 18, 2025
fa5d78d
set up server and connect to database
acl13 Mar 18, 2025
c17d4f6
create route to poulate database with fake products
acl13 Mar 18, 2025
b39f0ac
populate database with product data
acl13 Mar 18, 2025
ce44de6
set up pagination - limit to 9 products per page
acl13 Mar 18, 2025
8b8296e
create review schema and collection
acl13 Mar 19, 2025
feebe1f
write routes to GET products and reviews
acl13 Mar 20, 2025
478290e
create routes to add products and reviews
acl13 Mar 20, 2025
46ee48e
create routes to delete products and reviews
acl13 Mar 20, 2025
a464e5c
add querying and sorting to GET /products endpoint
acl13 Mar 21, 2025
c33fcc3
set up next.js frontend
acl13 Mar 21, 2025
9079696
separate review and product schema into separate files
acl13 Mar 26, 2025
ea68a87
create components to search and sort products
acl13 Mar 26, 2025
dceaddf
install/uninstall react-bootstrap
acl13 Mar 26, 2025
bf0a822
display mock products
acl13 Mar 27, 2025
d7e970d
set up redux store
acl13 Mar 28, 2025
deece89
display product data on frontend
acl13 Apr 3, 2025
72025b7
get product count
acl13 Apr 3, 2025
f2c1818
add pagination
acl13 Apr 8, 2025
f63d454
sort by category & persist pagination
acl13 Apr 9, 2025
8b83832
sort products by price
acl13 Apr 9, 2025
47859b8
allow user to search products
acl13 Apr 9, 2025
84e8761
ensure sort and search features work concurrently
acl13 Apr 9, 2025
e91f9e6
clean up console logs/comments
acl13 Apr 9, 2025
7073e88
add project description to README
acl13 Apr 9, 2025
69585f9
add instructions to README
acl13 Apr 15, 2025
dcc0c09
add instructions for populating data to README
acl13 Apr 15, 2025
f855e25
update frontend build instructions in README
acl13 Apr 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
77 changes: 76 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,80 @@
## Product List
# Product List

This project is a full-stack e-commerce site built using MongoDB, Node.js, React, and Redux.

## Data

The data was generated using [faker](https://fakerjs.dev/) and is stored locally using MongoDB Community

## Server

The following routes are supported:

```
GET /products
GET /products/count
GET /products/:productId
GET /products/:productId/reviews
POST /products
POST /products/:productId/reviews
DELETE /products/:productId
DELETE /reviews/:reviewId
```

## Frontend

The frontend currently supports the /products route, which includes options for filtering, sorting, and searching products.

## Getting Started

### Prerequisites

- Node.js (version 14 or above)
- npm
- MongoDB Community Edition - follow installation guidelines for your system [here](https://www.mongodb.com/docs/manual/administration/install-community/#std-label-install-mdb-community-edition)
- MongoDB Compass GUI - follow download instructions [here](https://www.mongodb.com/docs/compass/current/install/)

### Installation

1. Clone the repository:

```bash
git clone https://github.com/acl13/product-list.git
cd product-list
```

2. Install dependencies:

```bash
npm install
```

### Starting the Server & Populating Data

Start the server and connect to MongoDB

```bash
node server.js
```

- Ensure connection string in server.js matches the connection string in MongoDB Compass
- Navigate to localhost:8000/generate-fake-data to populate the database
(This will add 90 random products to the database - it is recommended to only complete this step once or twice)
- Use MongoDB Compass to check that your data is populating correctly

### Displaying Frontend

While the server is running, open a separate command line tab and run the following code to view the frontend

```bash
cd frontend/product-list
npm run build
npm run start
```

Navigate to http://localhost:3000 to view in browser

---

This project has been created by a student at Parsity, an online software engineering course. The work in this repository is wholly of the student based on a sample starter project that can be accessed by looking at the repository that this project forks.

Expand Down
41 changes: 41 additions & 0 deletions frontend/product-list/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions frontend/product-list/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
26 changes: 26 additions & 0 deletions frontend/product-list/app/components/ProductCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use client";
import Image from "next/image";

const ProductCard = ({ category, name, price, image }) => {
return (
<div className="border p-5 m-2">
<div className="d-flex justify-content-between">
<div>Category: {category}</div>
<div>{price}</div>
</div>
<div className="d-flex flex-column align-items-center">
<Image
src={image}
alt="Product Placeholder Image"
width={200}
height={300}
unoptimized
onError={(e) => (e.target.src = "https://prd.place/400")}
/>
<h1>{name}</h1>
</div>
</div>
);
};

export default ProductCard;
21 changes: 21 additions & 0 deletions frontend/product-list/app/components/SearchBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const SearchBar = ({ onChange, onSearch }) => {
return (
<>
<input
type="text"
placeholder="Search products..."
className="form-control my-2"
onChange={(event) => onChange(event.target.value)}
></input>
<button
type="button"
className="btn btn-outline-primary m-2"
onClick={onSearch}
>
Search
</button>
</>
);
};

export default SearchBar;
20 changes: 20 additions & 0 deletions frontend/product-list/app/components/SortDropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const SortDropdown = ({ name, id, options, onChange }) => {
return (
<select
name={name}
id={id}
className="form-control form-select w-15 m-2"
onChange={(event) => onChange(event.target.value)}
>
{options.map((option) => {
return (
<option value={option.value} key={option.value}>
{option.label}
</option>
);
})}
</select>
);
};

export default SortDropdown;
Binary file added frontend/product-list/app/favicon.ico
Binary file not shown.
42 changes: 42 additions & 0 deletions frontend/product-list/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
:root {
--background: #ffffff;
--foreground: #171717;
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}

html,
body {
max-width: 100vw;
overflow-x: hidden;
}

body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

* {
box-sizing: border-box;
padding: 0;
margin: 0;
}

a {
color: inherit;
text-decoration: none;
}

@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}
26 changes: 26 additions & 0 deletions frontend/product-list/app/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use client";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import "bootstrap/dist/css/bootstrap.css";
import { Provider } from "react-redux";
import store from "./store/configureStore";

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});

export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable}`}>
<Provider store={store}>{children}</Provider>
</body>
</html>
);
}
Loading