Skip to content
This repository was archived by the owner on Aug 17, 2024. It is now read-only.
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
Binary file added2-exercises/entity-relation-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
411 changes: 407 additions & 4 deletions 2-exercises/task.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions 3-projects/cyf-ecommerce-api/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
node_modules
package-lock.json
20 changes: 20 additions & 0 deletions 3-projects/cyf-ecommerce-api/package.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
{
"name": "cyf-ecommerce-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"pg": "^8.10.0"
},
"devDependencies": {
"nodemon": "^2.0.22"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions 3-projects/cyf-ecommerce-api/public/index.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>PostgreSQL API - Ecommerce</title>
</head>
<body>
<header>
<img src="elephant.png" alt="" />
<h1>PostgreSQL API - Ecommerce</h1>
</header>
<div>
<h2>Links to API Routes :</h2>
<nav id="nav-links"></nav>
</div>
<div>
<h2>Buttons to Formatted Output :</h2>
<nav id="nav-buttons"></nav>
</div>
<div id="output-container"></div>
<script src="script.js"></script>
</body>
</html>
33 changes: 33 additions & 0 deletions 3-projects/cyf-ecommerce-api/public/script.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
const paths = ["customers", "suppliers", "products"];

paths.forEach((path) => {
const navLinks = document.getElementById("nav-links");
const link = document.createElement("a");
link.href = `/${path}`;
link.innerText = `/${path}`;
navLinks.appendChild(link);

const navButtons = document.getElementById("nav-buttons");
const button = document.createElement("button");
button.id = `${path}`;
button.innerText = `/${path}`;
button.addEventListener("click", (event) => fetchAndFormat(event.target.id));
navButtons.appendChild(button);
});

async function fetchAndFormat(path) {
try {
const response = await fetch(`/${path}`);
const data = await response.json();
const outputContainer = document.getElementById("output-container");
outputContainer.innerText = "";
const pre = document.createElement("pre");
const code = document.createElement("code");
code.id = "output-json";
code.innerText = JSON.stringify(data, null, 2);
pre.appendChild(code);
outputContainer.appendChild(pre);
} catch (error) {
console.log(error);
}
}
70 changes: 70 additions & 0 deletions 3-projects/cyf-ecommerce-api/public/style.css
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
* {
box-sizing: border-box;
font-family: system-ui, sans-serif;
color: black;
font-size: 16px;
font-weight: 400;
}

body {
display: grid;
background-color: hsl(0, 0%, 92%);
max-width: 500px;
margin: 0 auto;
row-gap: 10px;
}

header {
display: flex;
align-items: center;
gap: 20px;
border-bottom: 1px solid hsl(207, 47%, 39%);
padding: 5px;
}

header > img {
max-width: 40px;
max-height: 40px;
}

header > h1 {
margin: 0;
font-size: 24px;
font-weight: 600;
}

h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
}

nav {
display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 5px;
}

button {
background-color: hsl(207, 47%, 39%);
color: hsl(0, 0%, 90%);
border: none;
border-radius: 2px;
padding: 5px 8px;
cursor: pointer;
}

button:hover {
background-color: hsl(207, 47%, 49%);
}

#output-container {
background-color: hsl(0, 0%, 95%);
border: 1px solid darkgray;
padding: 0 10px;
}

#output-json {
font-family: monospace;
}
28 changes: 28 additions & 0 deletions 3-projects/cyf-ecommerce-api/readme.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
# PostgreSQL Ecommerce API

## Screenshot:

![](project-screenshot.png)

## Instructions:

1. clone this repo
2. install [postgresql](https://www.postgresql.org/)
3. inside the root of the repository, open a terminal:
4. move into the `2-exercises` folder:
`cd 2-exercises`
5. create the database
`createdb cyf_ecommerce`
6. populate the database
`createdb -d cyf_ecommerce -f cyf-cyf_ecommerce.sql`
7. move to the api directory:
`cd ../3-projects/cyf-ecommerce-api`
8. install the project dependencies:
`npm install`
9. start the server in develoment mode:
`npm run dev`
10. visit http://localhost:3000

**Note: this project assumes you are connecting to the database with:**
`username: postgres`
`password: password`
63 changes: 63 additions & 0 deletions 3-projects/cyf-ecommerce-api/server.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
const express = require("express");
const app = express();

app.use(express.static("public"));

const { Pool } = require("pg");

const db = new Pool({
user: "postgres",
host: "localhost",
database: "cyf_ecommerce",
password: "password",
port: 5432,
});

app.get("/customers", (req, res) => {
db.query("SELECT * FROM customers")
.then((result) => {
res.json(result.rows);
})
.catch((error) => {
console.log(error);
});
});

app.get("/suppliers", (req, res) => {
db.query("SELECT * FROM suppliers")
.then((result) => {
res.json(result.rows);
})
.catch((error) => {
console.log(error);
});
});

app.get("/products", (req, res) => {
db.query(
`SELECT
p.product_name,
pa.unit_price,
s.supplier_name
FROM product_availability pa
INNER JOIN products p
ON (pa.prod_id = p.id)
INNER JOIN suppliers s
ON (pa.supp_id = s.id)
ORDER BY p.product_name, pa.unit_price;`
)
.then((result) => {
res.json(result.rows);
})
.catch((error) => {
console.log(error);
});
});

app.get("/", (req, res) => {
res.sendFile(__dirname + "./public/index.html");
});

app.listen(3000, () => {
console.log("The server is running on port 3000");
});