├── .gitignore
├── public
├── LLC.jpg
└── script.js
├── routes
├── about.js
├── checkout.js
├── carts.js
├── products.js
└── users.js
├── models
├── carts.js
├── users.js
└── products.js
├── README.md
├── package.json
├── views
├── return.pug
└── about.pug
├── .github
└── workflows
│ └── npm-publish.yml
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
--------------------------------------------------------------------------------
/public/LLC.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WENDYWEN20/CapstoneMongoDB/HEAD/public/LLC.jpg
--------------------------------------------------------------------------------
/routes/about.js:
--------------------------------------------------------------------------------
1 |
2 | import {Router} from 'express'
3 |
4 | const router=new Router
5 |
6 | router.post('/', (req,res)=>{
7 | console.log(req.params)
8 | res.render('about.pug')
9 |
10 | })
11 |
12 |
13 |
14 | export default router
--------------------------------------------------------------------------------
/models/carts.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const cartsSchema = new mongoose.Schema({
4 | name: { type: String, required: true},
5 | images: { type: String },
6 | price: {
7 | type: Number,
8 | required: true,
9 | },
10 |
11 | });
12 |
13 | const cartsModel = mongoose.model("carts", cartsSchema);
14 |
15 | export default cartsModel;
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Technologies used
4 |
5 | 1.Express\
6 | 2.Mongoose\
7 | 3.dotenv \
8 | 4. use MongoDB as the database, pictures and item posted from backend \
9 | 5. add Stripe for payment (under going) \
10 | 6. Youtube Tutorial followed: https://www.youtube.com/watch?v=1r-F3FIONl8 \
11 | 7. Youtube Tutorial followed: https://www.youtube.com/watch?v=4YjsG8u2QFA \
12 | 8.Next Step: add Shopify Hydrogen Link@https://hydrogen.shopify.dev/
13 |
--------------------------------------------------------------------------------
/models/users.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose'
2 |
3 | const usersSchema= new mongoose.Schema({
4 | username:{ type: String,
5 | required: true,
6 | minLength: 3,
7 | maxLength: 50,
8 | },
9 | email:{ type: String,
10 | required: true,
11 | minLength: 8,
12 | maxLength: 1200,
13 | },
14 |
15 | address:{
16 | type: String,
17 | },
18 | orderHistory:[]
19 | })
20 |
21 | const usersModel=mongoose.model('users', usersSchema)
22 |
23 | export default usersModel
--------------------------------------------------------------------------------
/public/script.js:
--------------------------------------------------------------------------------
1 | const button=document.querySelector('button')
2 | button.addEventListener('click', ()=>{
3 | fetch('http:localhost:3000/create-checkout-session',{
4 | method: 'POST',
5 | headers:{
6 | 'Content-Type': 'application/json'
7 | },
8 | body:JSON.stringify({})
9 | }).then(res=>{
10 | if (res.ok) return res.json()
11 | return res.json().then(json=>Promise.reject(json))
12 | }).then(({url})=>{
13 | window.location=url
14 | }).catch(e=>{console.error(e.error)})
15 | })
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mongodb",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "description": "",
13 | "dependencies": {
14 | "body-parser": "^1.20.3",
15 | "cors": "^2.8.5",
16 | "dotenv": "^16.4.5",
17 | "express": "^4.21.1",
18 | "mongoose": "^8.7.2",
19 | "morgan": "^1.10.0",
20 | "pug": "^3.0.3",
21 | "stripe": "^17.3.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/views/return.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | h1 Returning an item
5 |
6 | p="You can return an item for free within 30 days after receiving your order. It's also possible to return something to one of our stores if your order didn't have a delivery fee."
7 | p="Eligible online orders from October 24th, 2024 until January 23th, 2025 can be returned or exchanged within 60 days of receipt with our holiday extended return period."
8 | hr
9 | img(src='LLC.jpg')
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/models/products.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const productsSchema = new mongoose.Schema({
4 | name: { type: String, required: true, minLength: 3, maxLength: 50 },
5 | description: { type: String, minLength: 12, maxLength: 1200 },
6 | images: { type: String },
7 | size: {
8 | type: String,
9 | Enum: ["S", "M", "L", "NA"],
10 | },
11 | price: {
12 | type: Number,
13 | required: true,
14 | minLength: 1,
15 | maxLength: 10,
16 | },
17 | gender: {
18 | type: String,
19 | Enum: ["man", "woman", "children"],
20 | },
21 | });
22 |
23 | const productsModel = mongoose.model("products", productsSchema);
24 |
25 | export default productsModel;
26 |
--------------------------------------------------------------------------------
/routes/checkout.js:
--------------------------------------------------------------------------------
1 | import { Router } from "express";
2 | import {Stripe} from "stripe"
3 |
4 |
5 | const router=new Router()
6 | router.post('/create-checkout-session', async(req,res)=>{
7 | const stripe = new Stripe(process.env.STRIPE_PRIVATE_KEY);
8 | console.log(process.env.STRIPE_PRIVATE_KEY)
9 | try{const session =await stripe.checkout.sessions.create({
10 | payment_method_types:['card'],
11 | mode: 'payment',
12 | line_items:[{price: 50,
13 | // '{{PRICE_ID}}',
14 | quantity: 1,}],
15 | // success_url: 'http://localhost:3000/success.html',
16 | // cancel_url: 'http://localhost:3000/cancel.html '
17 | success_url: '${process.env.SERVER_URL}/success.html',
18 | cancel_url: '${process.env.SERVER_URL}/cancel.html ',
19 |
20 | })
21 |
22 | }catch(e){res.status(500).json({error:e.message})}
23 | res.json({url: session.url})
24 | console.log(session)
25 | })
26 | export default router
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3 |
4 | name: Node.js Package
5 |
6 | on:
7 | release:
8 | types: [created]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v4
15 | - uses: actions/setup-node@v4
16 | with:
17 | node-version: 20
18 | - run: npm ci
19 | - run: npm test
20 |
21 | publish-npm:
22 | needs: build
23 | runs-on: ubuntu-latest
24 | steps:
25 | - uses: actions/checkout@v4
26 | - uses: actions/setup-node@v4
27 | with:
28 | node-version: 20
29 | registry-url: https://registry.npmjs.org/
30 | - run: npm ci
31 | - run: npm publish
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34 |
--------------------------------------------------------------------------------
/views/about.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title='Company'
5 | link(rel="stylesheet", href="style.css")
6 | script(src='/myscript.js')
7 | body
8 |
9 | h1 CapStone Fullstack using Pug
10 | h2 Contact US
11 |
12 | p Everything we do is rooted in sport. Sport plays an increasingly important role in more and more people’s lives, on and off the field of play. It is central to every culture and society, and is core to our health and happiness.
13 | form(action='/create', method='post')
14 | a(href='/download') Download Our Catalog
15 | input(type='text')
16 |
17 |
18 | form(role='form' method='POST')
19 | div.form-group
20 | label(for='name') Name:
21 | input#name.form-control(type='text', placeholder='name' name='name')
22 | div.form-group
23 | label(for='email') Email:
24 | input#email.form-control(type='email', placeholder='name@email.com' name='email')
25 | button.btn.btn-primary(type="submit", name="asdf") Contact Customer Service
26 | h3 ADIDAS AG World of Sports
27 | h3 Adi-Dassler-Straße 1
28 | h3 91074 Herzogenaurach
29 | h3 Germany
30 |
31 |
--------------------------------------------------------------------------------
/routes/carts.js:
--------------------------------------------------------------------------------
1 | import { Router } from "express";
2 | import Cart from "../models/carts.js";
3 | // In-memory cart storage for simplicity (use database for production)
4 |
5 |
6 | const router=new Router()
7 | router.get('/', async(req,res, next)=>{
8 |
9 | try {
10 | const carts = await Cart.find();
11 |
12 | if (carts) {
13 | res.json({ carts });
14 | console.log(carts)
15 | } else {
16 | res.json({ message: "No products in cart" });
17 | }
18 | } catch (error) {
19 | next(error);
20 | }
21 | }
22 | );
23 |
24 |
25 | router.post("/", async (req, res, next) => {
26 | console.log(req.body);
27 | const newCart = await Cart.create(req.body);
28 | if (newCart) {
29 | res.status(201).json({ carts: newCart });
30 | } else {
31 | res.status(400).json({ message: "Error adding new product" });
32 | }
33 |
34 | });
35 |
36 |
37 | router.delete('/:id', async (req,res)=>{
38 | try{
39 | const deleteProduct= await Cart.findByIdAndDelete(req.params.id)
40 | if (!deleteCart){
41 | return res.send(`User not fund ${id}`)}
42 | else{res.send(
43 | {
44 | deletedCart: deleteProduct,
45 | message: "Product Deleted!"
46 | }
47 | )
48 | }}
49 | catch(error){console.log(error)}
50 | })
51 |
52 | router.put('/:id', async (req,res)=>{
53 | try{
54 | const updateCart=await Cart.findByIdAndUpdate(req.params.id, req.body, {new:true})
55 | res.send(updateCart)
56 | console.log(updateCart)
57 | }
58 | catch(error){console.log(error)}
59 | })
60 |
61 | export default router
--------------------------------------------------------------------------------
/routes/products.js:
--------------------------------------------------------------------------------
1 | import { Router } from "express";
2 | import Product from "../models/products.js";
3 |
4 |
5 | const router=new Router()
6 | router.get('/', async(req,res, next)=>{
7 |
8 | try {
9 | const products = await Product.find();
10 |
11 | if (products) {
12 | res.json({ products });
13 | console.log(Product)
14 | } else {
15 | res.json({ message: "No products found" });
16 | }
17 | } catch (error) {
18 | next(error);
19 | }
20 | }
21 | );
22 |
23 |
24 | router.get('/:id',async (req,res)=>{
25 | try{
26 | const product=await Product.findById(req.params.id)
27 | if (product) {
28 | res.json({product});
29 | }else{
30 | res.json({message:`No product found ${req.params.id}`})
31 | }
32 |
33 | }catch(error){
34 | console.log(error)
35 | }
36 |
37 | })
38 |
39 | router.post("/", async (req, res, next) => {
40 | console.log(req.body);
41 | try {
42 | const newProduct = await Product.create(req.body);
43 | if (newProduct) {
44 | res.status(201).json({ product: newProduct });
45 | } else {
46 | res.status(400).json({ message: "Error creating new product" });
47 | }
48 | } catch (error) {
49 | next(error);
50 | }
51 | });
52 |
53 |
54 | router.delete('/:id', async (req,res)=>{
55 | try{
56 | const deleteProduct= await Product.findByIdAndDelete(req.params.id)
57 | if (!deleteProduct){
58 | return res.send(`User not fund ${id}`)}
59 | else{res.send(
60 | {
61 | deletedUser: deleteProduct,
62 | message: "Product Deleted!"
63 | }
64 | )
65 | }}
66 | catch(error){console.log(error)}
67 | })
68 |
69 | router.put('/:id', async (req,res)=>{
70 | try{
71 | const updateProduct=await Product.findByIdAndUpdate(req.params.id, req.body, {new:true})
72 | res.send(updateProduct)
73 | console.log(updateProduct)
74 | }
75 | catch(error){console.log(error)}
76 | })
77 |
78 | export default router
--------------------------------------------------------------------------------
/routes/users.js:
--------------------------------------------------------------------------------
1 | import User from "../models/users.js";
2 |
3 | import {Router} from 'express'
4 |
5 | const router=new Router
6 |
7 | const data=[
8 | {username:'user1',
9 | emailaddress:'user1@gmail.com',
10 | },
11 |
12 | {username:'user2',
13 | emailaddress:'user2@gmail.com',
14 | },
15 |
16 | {username:'user3',
17 | emailaddress:'user3@gmail.com',
18 | },
19 | ]
20 |
21 |
22 |
23 | router.get('/', async(req,res, next)=>{
24 |
25 | try {
26 | const Users = await User.find();
27 |
28 | if (Users) {
29 | res.json({ Users });
30 | console.log(Users)
31 | } else {
32 | res.json({ message: "No users found" });
33 | }
34 | } catch (error) {
35 | next(error);
36 | }
37 | }
38 | );
39 |
40 |
41 | router.get('/:id',async (req,res)=>{
42 | try{
43 | const user=await User.findById(req.params.id)
44 | if (user) {
45 | res.json({user});
46 | }else{
47 | res.json({message:`No user found ${req.params.id}`})
48 | }
49 | }catch(error){
50 | console.log(error)
51 | }
52 |
53 | })
54 |
55 | router.post("/", async (req, res, next) => {
56 | console.log(req.body);
57 | try {
58 | const newUser = await User.create(req.body);
59 | if (newUser) {
60 | res.status(201).json({ user: newUser });
61 | } else {
62 | res.status(400).json({ message: "Error creating new user" });
63 | }
64 | } catch (error) {
65 | next(error);
66 | }
67 | });
68 |
69 |
70 | router.delete('/:id', async (req,res)=>{
71 | try{
72 | const deleteUser= await User.findByIdAndDelete(req.params.id)
73 | if (!deleteUser){
74 | return res.send(`User not fund ${id}`)}
75 | else{res.send(
76 | {
77 | deletedUser: deleteUser,
78 | message: "User Deleted!"
79 | }
80 | )
81 | }}
82 | catch(error){console.log(error)}
83 | })
84 |
85 | router.put('/:id', async (req,res)=>{
86 | try{
87 | const updateUser=await User.findByIdAndUpdate(req.params.id, req.body, {new:true})
88 | res.send(updateUser)
89 | console.log(updateUser)
90 | }
91 | catch(error){console.log(error)}
92 | })
93 |
94 | export default router
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import ProductsRouter from "./routes/products.js";
3 | import UsersRouter from "./routes/users.js";
4 | import CartRouter from "./routes/carts.js";
5 | import StripeRouter from "./routes/checkout.js";
6 | import mongoose from "mongoose";
7 | import dotenv from "dotenv";
8 | import morgan from "morgan";
9 | import cors from "cors";
10 | import { Stripe } from "stripe";
11 | import Cart from "./models/carts.js";
12 | dotenv.config();
13 | const app = express();
14 | const PORT = process.env.PORT || 3000;
15 | // =======connect to DataBase ===========
16 | try {
17 | await mongoose.connect(process.env.MONGODB_URI);
18 | console.log(`Connected to MONGODB`);
19 | } catch (error) {
20 | console.error(error);
21 | }
22 |
23 | // In-memory cart storage for simplicity (use database for production)
24 | app.set("view engine", "pug");
25 | app.set("views", "./views");
26 |
27 | app.use(express.json());
28 | app.use(morgan("dev")); //logger
29 | app.use(cors());
30 | app.use(express.urlencoded({ extended: true }));
31 | app.use(express.static("public"));
32 | app.use(express.urlencoded({ extended: true }));
33 | app.get("/", (req, res) => {
34 | res.send(`welcome to my API`);
35 | });
36 |
37 | // app.get('/about', (req, res) =>{
38 | // res.render('about.pug')})
39 | // app.get('/return', (req, res) =>{
40 | // res.render('return.pug')})
41 |
42 | app.use("/users", UsersRouter);
43 | app.use("/carts", CartRouter);
44 | app.use("/products", ProductsRouter);
45 |
46 | app.post("/create-checkout-session", async (req, res,next) => {
47 |
48 |
49 | // res.json({url:"apple"})
50 | // console.log(req.body)
51 | // const storeItems = new Map([
52 | // [1, { priceInCents: 10000, name: "Learn React Today" }],
53 | // [2, { priceInCents: 20000, name: "CSS HTML" }],
54 | // ]);
55 | const stripe = new Stripe(process.env.STRIPE_PRIVATE_KEY);
56 | // console.log(process.env.STRIPE_PRIVATE_KEY);
57 | // try{ const cartsItem = await Cart.find();
58 | // if (cartsItem){
59 | // console.log(cartsItem);
60 | // } else {
61 | // res.json({message:" No item in cart"});
62 | // }
63 | // }catch (error){next(error)}
64 | try {
65 | const cartsItem = await Cart.find();
66 | console.log(req.body)
67 | const session = await stripe.checkout.sessions.create({
68 | payment_method_types: ["card"],
69 | mode: "payment",
70 | // line_items: req.body.items?.map(item=>{const storeItem=storeItems.get(item.id)
71 | // return{
72 | // price_data:{
73 | // product_data:{
74 | // name:storeItem.name
75 | // },
76 | // unit_amount: storeItem.priceIncents
77 | // },
78 | // quantity:item.quantity
79 | // }
80 | // }),
81 |
82 | line_items: [
83 | // cartsItem?.map(item => {
84 | // const cartItem = cartsItem.get(item);
85 | // console.log(req.body.items)
86 | // return
87 | {
88 | price_data: {
89 | currency: "usd",
90 | product_data: {name: cartsItem[1].name},
91 | unit_amount: cartsItem[1].price*100,
92 | },
93 | quantity: 1,
94 | },
95 | ],
96 | // }),
97 |
98 | success_url: 'http://localhost:3000/success.html',
99 | cancel_url: 'http://localhost:3000/cancel.html',
100 | // success_url: "${process.env.SERVER_URL}/success.html",
101 | // cancel_url: "${process.env.SERVER_URL}/cancel.html ",
102 |
103 | })
104 | res.json({ url: session.url });
105 | } catch (e) {
106 | res.status(500).json({ error: e.message });
107 | }
108 | });
109 |
110 | //=========Error Middleware======
111 | app.use((e, req, res, next) => {
112 | console.error(e);
113 | res.status(500).json({ message: e.message, error: e });
114 | });
115 |
116 | app.listen(PORT, () => console.log(`Server at ${PORT}`));
117 |
--------------------------------------------------------------------------------