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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ package-lock.json
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn-error.log*

.idea
2 changes: 1 addition & 1 deletion client/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="icon" href="/images/favicon.ico" />
<title>MERN Ecommerce Application</title>
<title>Por el comercion local</title>
</head>
<body>
<noscript> You need to enable JavaScript to run this app. </noscript>
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"homepage": "https://github.com/mohamedsamara/mern-ecommerce#readme",
"dependencies": {
"awesome-phonenumber": "^2.29.0",
"axios": "^0.19.0",
"bcryptjs": "^2.4.3",
"bootstrap": "^4.3.1",
Expand All @@ -40,9 +41,11 @@
"cors": "^2.8.5",
"crypto": "^1.0.1",
"dotenv": "^8.0.0",
"email-validator": "^2.0.4",
"express": "^4.17.1",
"font-awesome": "^4.7.0",
"history": "^4.9.0",
"iban": "^0.0.14",
"jsonwebtoken": "^8.5.1",
"mailchimp-v3": "^1.0.5",
"mailgun-js": "^0.22.0",
Expand Down
58 changes: 58 additions & 0 deletions server/controllers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const { login, register } = require("../services/auth");
const { loginValidation, registerValidation } = require("../validations/auth");
const mailgun = require('../config/mailgun');
const template = require('../config/template');

exports.doRegister = async (req, res) => {
try{
const { error } = registerValidation(req);
if (error) return res.status(422).json(error);
const {
email,
password,
firstName,
lastName,
} = req.body;

const { user, token } = await register(email, password, { firstName, lastName });

const message = template.signupEmail(user.profile);
mailgun.sendEmail(user.email, message);

res.status(200).json({
success: true,
token: `Bearer ${token}`,
user,
});
} catch (e) {
res.status(400).json({
error: "Something went wrong"
});
}
};

exports.doLogin = async (req, res) => {
try {
const { error } = loginValidation(req);
if (error) return res.status(422).json(error);

const {
email,
password,
} = req.body;

const { user, token, error: passwordError } = await login(email, password);

if (passwordError) return res.status(404).json({ success: false, error: passwordError});

res.status(200).json({
success: true,
token: `Bearer ${token}`,
user: user,
});
} catch (e) {
res.status(400).json({
error: e.toString()
});
}
};
21 changes: 21 additions & 0 deletions server/controllers/cities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { createCity, updateCity } = require("../services/cities");
const { updateCity } = require("../services/users");

exports.postCity = async (req, res) => {
try {
const {
name,
description
} = req.body;
const { _id: userId } = req.user;

const city = await createCity(userId, name, description);
const updatedUser = await updateCity(userId, city._id);

res.status(200).json({ city, user: updatedUser });
} catch (e) {
res.status(400).json({
error: "Something went wrong"
})
}
};
23 changes: 23 additions & 0 deletions server/controllers/commerces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

const { createCommerce } = require("../services/commerces");
const { generateDefaultCards } = require("../services/gift-cards");

exports.postCommerce = async (req, res) => {
try {
// TODO: validate body
const {
name,
description,
images,
cityId
} = req.body;
const commerce = await createCommerce({ name, description, images }, req.user.id, cityId);
const cards = await generateDefaultCards(commerce.id);

res.status(200).json({ commerce, cards });
} catch (e) {
res.status(400).json({
error: "Something went wrong"
});
}
}
35 changes: 0 additions & 35 deletions server/models/brand.js

This file was deleted.

33 changes: 17 additions & 16 deletions server/models/category.js → server/models/city.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const options = {
Mongoose.plugin(slug, options);

// Category Schema
const CategorySchema = new Schema({
const CitySchema = new Schema({
_id: {
type: Schema.ObjectId,
auto: true
Expand All @@ -21,25 +21,26 @@ const CategorySchema = new Schema({
trim: true
},
slug: { type: String, slug: 'name', unique: true },
image: {
data: Buffer,
contentType: String
},
description: {
type: String,
trim: true
},
products: [
{
type: Schema.Types.ObjectId,
ref: 'Product'
}
],
updated: Date,
created: {
type: Date,
default: Date.now
deleted: {
type: Boolean,
default: false,
},
admin: {
type: Schema.Types.ObjectId,
ref: "User",
required: true,
}
}, {
timestamps: {
createdAt: "created",
updatedAt: "updated",
}
});

module.exports = Mongoose.model('Category', CategorySchema);
CitySchema.index({ name: 'text' });

module.exports = Mongoose.model('City', CitySchema);
84 changes: 84 additions & 0 deletions server/models/commerce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const Mongoose = require('mongoose');
const slug = require('mongoose-slug-generator');
const PhoneNumber = require('awesome-phonenumber');
const IBAN = require('iban');
const { Schema } = Mongoose;

const options = {
separator: '-',
lang: 'en',
truncate: 120
};

Mongoose.plugin(slug, options);

const CommerceSchema = new Schema({
name: {
type: String,
trim: true,
required: true,
},
slug: { type: String, slug: 'name', unique: true },
images: [{
data: Buffer,
contentType: String
}],
description: {
type: String,
trim: true,
required: true,
},
city: {
type: Schema.Types.ObjectId,
ref: "City",
required: true,
},
phoneNumber: {
type: String,
trim: true,
required: true,
validate: {
validator: phone => {
const parsedNumber = PhoneNumber(phone);
return parsedNumber.isMobile() || parsedNumber.isFixedLine();
},
message: props => `${props.value} is not a phone number!`
},
},
bizum: {
type: String,
trim: true,
validate: {
validator: phone => PhoneNumber(phone).isMobile(),
message: props => `${props.value} is not a phone number!`
},
},
bankAccount: {
type: String,
trim: true,
required: true,
validate: {
validator: IBAN.isValid,
message: props => `${props.value} is not a valid IBAN!`
},
},
discount: {
type: Number,
min: 0,
max: 50,
required: true,
},
deleted: {
type: Boolean,
default: false,
},
}, {
timestamps: {
createdAt: "created",
updatedAt: "updated",
}
});

CommerceSchema.index({ name: 'text' });

module.exports = Mongoose.model('Commerce', CommerceSchema);
44 changes: 44 additions & 0 deletions server/models/gift-card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const Mongoose = require('mongoose');
const slug = require('mongoose-slug-generator');
const { Schema } = Mongoose;

const options = {
separator: '-',
lang: 'en',
truncate: 120
};

Mongoose.plugin(slug, options);

const GiftCardSchema = new Schema({
hash: {
type: String,
trim: true,
unique: true,
required: true,
},
quantity: {
type: Number,
required: true,
min: 0,
},
transaction: {
type: Schema.Types.ObjectId,
ref: 'Transaction',
required: true,
},
isConsumed: {
type: Boolean,
default: false,
},
deleted: {
type: Boolean,
default: false,
},
},{
timestamps: {
createdAt: "created",
}
});

module.exports = Mongoose.model('GiftCard', GiftCardSchema);
Loading