Skip to content

Commit

Permalink
Merge pull request #21 from Justkant/product-enhancements
Browse files Browse the repository at this point in the history
Product enhancements
  • Loading branch information
Justkant committed Nov 1, 2015
2 parents 558f162 + 3ca068a commit 968a67d
Show file tree
Hide file tree
Showing 30 changed files with 664 additions and 163 deletions.
16 changes: 9 additions & 7 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
],
"extra": {
"react-transform": {
"transforms": [{
"transform": "react-transform-catch-errors",
"imports": [
"react",
"redbox-react"
]
}]
"transforms": [
{
"transform": "react-transform-catch-errors",
"imports": [
"react",
"redbox-react"
]
}
]
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ node_modules/
dist/
*.iml
webpack-stats.json
webpack-stats.debug.json
npm-debug.log
/rethinkdb_data
rethinkdb_data/
uploads/
doc/
32 changes: 26 additions & 6 deletions api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@ import cookieParser from 'cookie-parser';
import config from '../src/config';
import { users, products } from './functions';
import PrettyError from 'pretty-error';
import Thinky from 'thinky';
import multer from 'multer';
import mimetypes from 'mimetypes';

const pretty = new PrettyError();
var storage = multer.diskStorage({
destination: 'uploads',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + '.' + mimetypes.detectExtension(file.mimetype));
}
});
const upload = multer({ storage: storage });
const app = express();

app.use(cookieParser());
app.use(bodyParser.json());

const staticOptions = {};
if (config.isProduction) {
staticOptions.maxAge = '60 days';
}
app.use('/uploads', require('serve-static')('uploads/', staticOptions));

app.get('/load', users.load);
app.post('/login', users.login);
app.get('/logout', users.logout);
Expand All @@ -28,16 +42,22 @@ app.route('/users/:id')
.delete(users.auth, users.isOwner, users.deleteUser);

app.route('/products')
.get(products.getProducts)
.post(products.addProduct);
.get(users.auth, users.isAdmin, products.getProducts)
.post(users.auth, users.isAdmin, products.addProduct);

app.route('/products/:id')
.get(products.getProduct)
.put(products.updateProduct)
.delete(products.deleteProduct);
.get(users.auth, products.getProduct)
.put(users.auth, users.isAdmin, products.updateProduct)
.delete(users.auth, users.isAdmin, products.deleteProduct);

app.get('/market', users.auth, products.getMarket);

app.get('/search/:text', products.search);

app.post('/picture', users.auth, upload.single('picture'), (req, res) => {
res.json({url: req.file.path});
});

if (config.apiPort) {
app.listen(config.apiPort, (err) => {
if (err) {
Expand Down
93 changes: 35 additions & 58 deletions api/functions/products.js
Original file line number Diff line number Diff line change
@@ -1,103 +1,80 @@
import { Product } from '../models';
import { shuffle } from '../utils/functions';

function getProducts(req, res) {
res.json([{
title: 'Title',
description: 'Nike shoes',
imageUrl: 'product.jpg',
price: '125$'
}]);
Product.orderBy('-createdAt').run().then((result) => {
res.json(result);
});
}

function getProduct(req, res) {
/* pourquoi product pop en orange ? */
res.json(req.product.getPublic());
Product.get(req.params.id).run().then((product) => {
res.json(product);
}, (error) => {
res.status(404).json({msg: 'Product not found'});
});
}

function addProduct(req, res) {

const product = new Product({
title: req.body.title,
description: req.body.description,
imageUrl: req.body.imageUrl,
price: req.body.price
price: 0
});

product.save().then(() => {
res.json(product);
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
});
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
});
}

function updateProduct(req, res) {
const product = {};
const promises = [];

if (req.body.title && req.body.title != req.product.title) {
promises.push(new Promise((resolve, reject) => {
product.title = req.body.title;
resolve();
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
reject();
}));
}

if (req.body.price && req.body.price !== req.product.price) {
promises.push(new Promise((resolve) => {
product.price = req.body.price;
resolve();
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
reject();
}));
}

if (req.body.description && req.body.description !== req.product.description) {
promises.push(new Promise((resolve) => {
product.description = req.body.description;
resolve();
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
reject();
}));
}

Promise.all(promises).then(() => {
req.product.merge(product).save().then((result) => {
res.json(req.product.getPublic());
Product.get(req.params.id).run().then((product) => {
product.merge(req.body).save().then((result) => {
res.json(product);
}, (error) => {
console.error(error);
res.status(400).json({msg: 'Something went wrong', err: error});
});
}, (error) => {
res.status(404).json({msg: 'Product not found'});
});
}

function deleteProduct(req, res) {
req.product.delete().then(() => {
res.json({msg: 'Account deleted'});
Product.get(req.params.id).run().then((product) => {
product.delete().then(() => {
res.json({msg: 'Product deleted'});
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
});
}, (error) => {
console.error(error);
res.status(500).json({msg: 'Contact an administrator', err: error});
res.status(404).json({msg: 'Product not found'});
});
}

function search(req, res) {

}

function getMarket(req, res) {
Product.run().then((result) => {
res.json(shuffle(result));
});
}

const products = {
getProducts: getProducts,
getProduct: getProduct,
addProduct: addProduct,
updateProduct: updateProduct,
deleteProduct: deleteProduct,
search: search
search: search,
getMarket: getMarket
};

export default products;
33 changes: 32 additions & 1 deletion api/functions/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,41 @@ function logout(req, res) {
res.json(null);
}

/**
* @api {get} /users Request All Users
* @apiName GetUsers
* @apiGroup User
*/
function getUsers(req, res) {
res.json([{username: 'kant'}]);
User.orderBy('-createdAt').run().then((result) => {
res.json(result);
});
}

/**
* @api {get} /users/:id Request User Information
* @apiName GetUser
* @apiGroup User
*
* @apiParam {Number} id Users unique ID.
*
* @apiSuccess {String} username The users name.
* @apiSuccess {String} email The users email.
* @apiSuccess {String} token The users token.
* @apiSuccess {String} pictureUrl The users picture url.
* @apiSuccess {Boolean} admin The users right.
* @apiSuccess {Date} createdAt The users creation date.
*
* @apiSuccessExample Example data on success:
* {
* username: 'Kant',
* email: '[email protected]',
* token: 'IOEJVofz@fohinsmov24azd5niermogunqeprofinzqoe8297',
* pictureUrl: 'uploads/picture-94305067460.png',
* admin: true,
* createdAt: Wed Oct 21 2015 14:33:53 GMT+00:00
* }
*/
function getUser(req, res) {
res.json(req.user.getPublic());
}
Expand Down
3 changes: 2 additions & 1 deletion api/models/Product.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const Product = thinky.createModel('Product', {
title: type.string().required(),
description: type.string().optional(),
imageUrl: type.string().optional(),
price: type.number().required()
price: type.number().required(),
createdAt: type.date().default(thinky.r.now())
});

export default Product;
5 changes: 3 additions & 2 deletions api/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ const User = thinky.createModel('User', {
username: type.string().required(),
email: type.string().email().required(),
password: type.string().required(),
admin: type.boolean().default(false),
admin: type.boolean().default(true),
createdAt: type.date().default(thinky.r.now()),
token: type.string()
token: type.string(),
pictureUrl: type.string()
});

User.define('getPublic', function() {
Expand Down
2 changes: 1 addition & 1 deletion api/models/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export User from './User';
//export Product from './Product';
export Product from './Product';
export Email from './Email';
17 changes: 17 additions & 0 deletions api/utils/functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function shuffle(array) {
var m = array.length, t, i;

// While there remain elements to shuffle…
while (m) {

// Pick a remaining element…
i = Math.floor(Math.random() * m--);

// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}

return array;
}
5 changes: 5 additions & 0 deletions apidoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "WhatAShop API",
"version": "0.1.1",
"description": "API description for WhatAShop"
}
Loading

0 comments on commit 968a67d

Please sign in to comment.