diff --git a/client/.babelrc b/client/.babelrc new file mode 100644 index 0000000..071414f --- /dev/null +++ b/client/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + ["latest", { + "es2015": { "modules": false } + }] + ], + "plugins": ["transform-object-rest-spread"] +} diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..c369a4d --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log +yarn-error.log diff --git a/client/README.md b/client/README.md new file mode 100644 index 0000000..83154e7 --- /dev/null +++ b/client/README.md @@ -0,0 +1,18 @@ +# client + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build +``` + +For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/client/index.html b/client/index.html new file mode 100644 index 0000000..84d5b5d --- /dev/null +++ b/client/index.html @@ -0,0 +1,11 @@ + + + + + client + + +
+ + + diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..5f072ba --- /dev/null +++ b/client/package.json @@ -0,0 +1,30 @@ +{ + "name": "client", + "description": "A Vue.js project", + "version": "1.0.0", + "author": "zidane9 ", + "private": true, + "scripts": { + "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", + "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" + }, + "dependencies": { + "axios": "^0.16.1", + "vue": "^2.2.1", + "vue-router": "^2.4.0", + "vuex": "^2.3.1" + }, + "devDependencies": { + "babel-core": "^6.0.0", + "babel-loader": "^6.0.0", + "babel-plugin-transform-object-rest-spread": "^6.23.0", + "babel-preset-latest": "^6.0.0", + "cross-env": "^3.0.0", + "css-loader": "^0.25.0", + "file-loader": "^0.9.0", + "vue-loader": "^11.1.4", + "vue-template-compiler": "^2.2.1", + "webpack": "^2.2.0", + "webpack-dev-server": "^2.2.0" + } +} diff --git a/client/src/App.vue b/client/src/App.vue new file mode 100644 index 0000000..2a2a8d2 --- /dev/null +++ b/client/src/App.vue @@ -0,0 +1,49 @@ + + + diff --git a/client/src/assets/logo.png b/client/src/assets/logo.png new file mode 100644 index 0000000..f3d2503 Binary files /dev/null and b/client/src/assets/logo.png differ diff --git a/client/src/components/AddHouse.vue b/client/src/components/AddHouse.vue new file mode 100644 index 0000000..c919591 --- /dev/null +++ b/client/src/components/AddHouse.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/client/src/components/DetailHouse.vue b/client/src/components/DetailHouse.vue new file mode 100644 index 0000000..c3b808c --- /dev/null +++ b/client/src/components/DetailHouse.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/client/src/components/House.vue b/client/src/components/House.vue new file mode 100644 index 0000000..eed917d --- /dev/null +++ b/client/src/components/House.vue @@ -0,0 +1,55 @@ + + + diff --git a/client/src/components/ListHouse.vue b/client/src/components/ListHouse.vue new file mode 100644 index 0000000..016849d --- /dev/null +++ b/client/src/components/ListHouse.vue @@ -0,0 +1,24 @@ + + + diff --git a/client/src/constants.js b/client/src/constants.js new file mode 100644 index 0000000..b76efbe --- /dev/null +++ b/client/src/constants.js @@ -0,0 +1,3 @@ +const serverUrl = 'http://localhost:3000'; + +module.exports = serverUrl diff --git a/client/src/main.js b/client/src/main.js new file mode 100644 index 0000000..70f3f6f --- /dev/null +++ b/client/src/main.js @@ -0,0 +1,41 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' +import App from './App.vue' +import store from './store' + +import AddHouse from './components/AddHouse.vue' +import ListHouse from './components/ListHouse.vue' +import DetailHouse from './components/ListHouse.vue' + +// import store from './store' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/' + }, + { + path: '/houses/new', + component: AddHouse + }, + { + path: '/houses', + component: ListHouse + }, + { + path: '/houses/show', + component: DetailHouse + } +] + +const router = new VueRouter({ + routes +}) + +new Vue({ + el: '#app', + router, + store, + render: h => h(App) +}) diff --git a/client/src/store/actions.js b/client/src/store/actions.js new file mode 100644 index 0000000..25cde00 --- /dev/null +++ b/client/src/store/actions.js @@ -0,0 +1,58 @@ +import * as types from './mutation-types' +import axios from 'axios' +import serverUrl from '../constants' + + +export const initHouses = ({commit}) => { + // console.log('-----------x'); + axios.get(`${serverUrl}/houses`) + .then(function (response) { + console.log(response.data); + commit(types.INIT_HOUSES, response.data); + }) + .catch(function (error) { + console.log(error); + alert(error.message); + }); +} + +export const addHouse = ({commit}, house) => { + // console.log('----x'); + axios.post(`${serverUrl}/houses`, house) + .then(function (response) { + console.log(response.data); + commit(types.ADD_HOUSE, response.data) + }) + .catch(function (error) { + console.log(error); + alert(error.message); + }); +} + +export const updateHouse = ({commit}, house) => { + // console.log('----x'); + axios.put(`${serverUrl}/houses/${house._id}`, house) + .then(function (response) { + console.log(response.data); + commit(types.UPDATE_HOUSE, response.data) + }) + .catch(function (error) { + console.log(error); + alert(error.message); + }); +} + +export const removeHouse = ({commit}, id) => { + let isSure = confirm('Are you sure?') + if(isSure){ + axios.delete(`${serverUrl}/houses/${id}`) + .then(function (response) { + console.log(response.data); + commit(types.REMOVE_HOUSE, id) + }) + .catch(function (error) { + console.log(error); + alert(error.message); + }); + } +} diff --git a/client/src/store/index.js b/client/src/store/index.js new file mode 100644 index 0000000..966e32d --- /dev/null +++ b/client/src/store/index.js @@ -0,0 +1,31 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import { mutations } from './mutations' +import * as actions from './actions' + +Vue.use(Vuex) + +const state = { + houses: [] + // newHouse: { + // title: '', + // description: '', + // price: '', + // image: '', + // owner: '', + // phone: '', + // address: '' + // } +} + +// const getters = { +// getNewHouse: state => state.newHouse, +// getHouses: state => state.houses +// } + +export default new Vuex.Store({ + state, + mutations, + actions + // getters +}) diff --git a/client/src/store/mutation-types.js b/client/src/store/mutation-types.js new file mode 100644 index 0000000..90b70fd --- /dev/null +++ b/client/src/store/mutation-types.js @@ -0,0 +1,4 @@ +export const INIT_HOUSES = 'INIT_HOUSES' +export const ADD_HOUSE = 'ADD_HOUSE' +export const UPDATE_HOUSE = 'UPDATE_HOUSE' +export const REMOVE_HOUSE = 'REMOVE_HOUSE' diff --git a/client/src/store/mutations.js b/client/src/store/mutations.js new file mode 100644 index 0000000..97aaa75 --- /dev/null +++ b/client/src/store/mutations.js @@ -0,0 +1,17 @@ +import * as types from './mutation-types' + +export const mutations = { + [types.INIT_HOUSES] (state, payload){ + state.houses = []; + state.houses.push(...payload) + }, + [types.ADD_HOUSE] (state, payload){ + state.houses.push(payload) + }, + [types.UPDATE_HOUSE] (state, payload){ + state.houses = state.houses.map(house => house._id == payload._id ? payload : house) + }, + [types.REMOVE_HOUSE] (state, payload){ + state.houses = state.houses.filter(house => house._id != payload._id) + } +} diff --git a/client/webpack.config.js b/client/webpack.config.js new file mode 100644 index 0000000..beb773d --- /dev/null +++ b/client/webpack.config.js @@ -0,0 +1,70 @@ +var path = require('path') +var webpack = require('webpack') + +module.exports = { + entry: './src/main.js', + output: { + path: path.resolve(__dirname, './dist'), + publicPath: '/dist/', + filename: 'build.js' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + loaders: { + } + // other vue-loader options go here + } + }, + { + test: /\.js$/, + loader: 'babel-loader', + exclude: /node_modules/ + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: 'file-loader', + options: { + name: '[name].[ext]?[hash]' + } + } + ] + }, + resolve: { + alias: { + 'vue$': 'vue/dist/vue.esm.js' + } + }, + devServer: { + historyApiFallback: true, + noInfo: true + }, + performance: { + hints: false + }, + devtool: '#eval-source-map' +} + +if (process.env.NODE_ENV === 'production') { + module.exports.devtool = '#source-map' + // http://vue-loader.vuejs.org/en/workflow/production.html + module.exports.plugins = (module.exports.plugins || []).concat([ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"' + } + }), + new webpack.optimize.UglifyJsPlugin({ + sourceMap: true, + compress: { + warnings: false + } + }), + new webpack.LoaderOptionsPlugin({ + minimize: true + }) + ]) +} diff --git a/server/.env b/server/.env new file mode 100644 index 0000000..e69de29 diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/server/app.js b/server/app.js new file mode 100644 index 0000000..30a46ef --- /dev/null +++ b/server/app.js @@ -0,0 +1,75 @@ +'use strict' +//All Dependencies +const express = require('express'), + path = require('path'), + logger = require('morgan'), + bodyParser = require('body-parser'), + mongoose = require('mongoose'), + cors = require('cors'), + + + //All Route Files + routes = require('./routes/index'), + houses = require('./routes/houses'), + + //Express Instance + app = express(); + +//load environment variables with dotenv +require('dotenv').config() + +//Database connection +mongoose.Promise = global.Promise; +mongoose.connect('mongodb://localhost/houseselling', (err) => { + if (err) { + console.log(err); + } else { + console.log('Database connected!'); + } +}); + +app.use(cors()); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); +// app.use(cookieParser()); + + +app.use('/', routes); +app.use('/houses', houses); + +app.listen(3000); + +// catch 404 and forward to error handler +app.use((req, res, next) => { + let err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handlers + +// development error handler +// will print stacktrace +if (app.get('env') === 'development') { + app.use((err, req, res, next) => { + res.status(err.status || 500); + res.send({ + message: err.message, + error: err + }); + }); +} + +// production error handler +// no stacktraces leaked to user +app.use((err, req, res, next) => { + res.status(err.status || 500); + res.send({ + message: err.message, + error: {} + }); +}); + + +module.exports = app; diff --git a/server/controllers/houseController.js b/server/controllers/houseController.js new file mode 100644 index 0000000..db84435 --- /dev/null +++ b/server/controllers/houseController.js @@ -0,0 +1,75 @@ +'use strict' + +const House = require('../models/house'); + +let getAll = function (req, res, next) { + House.find() + .exec(function (err, houses) { + if (err) return res.send(err); + res.send(houses); + }) +}; + +let getOne = function (req, res, next) { + House.findOne({_id: req.params.id}) + .exec(function (err, house){ + if(err){ + res.json({error: err}); + } else { + res.json(house); + } + }) +}; + +let createOne = function (req, res, next) { + House.create({ + title : req.body.title, + description: req.body.description, + price: req.body.price, + image: req.body.image, + owner: req.body.owner, + phone: req.body.phone, + address: req.body.address + }, function (error, house){ + if(error) res.send(error); + res.send(house); + }) +}; + +let update = function (req, res, next) { + House.findOne({_id: req.params.id}, function (err, house) { + if (err) res.send(err); + else if(!house) res.send({errors: 'House not found'}) + else { + if(req.body.title) house.title = req.body.title; + if(req.body.description) house.description = req.body.description; + if(req.body.price) house.price = req.body.price; + if(req.body.image) house.image = req.body.image; + if(req.body.owner) house.owner = req.body.owner; + if(req.body.phone) house.phone = req.body.phone + if(req.body.address) house.address = req.body.address; + house.save(function (err, updatedHouse) { + if (err) res.send(err); + else res.send(updatedHouse); + }); + } + }); +}; + + +let deleteOne = function (req, res, next) { + House.findOne({_id: req.params.id}) + .remove(function(err, respond){ + if(err) res.send(err); + else res.send(respond); + }) +}; + + +module.exports = { + getAll, + getOne, + createOne, + update, + deleteOne +} diff --git a/server/models/house.js b/server/models/house.js new file mode 100644 index 0000000..0acf2bc --- /dev/null +++ b/server/models/house.js @@ -0,0 +1,29 @@ +'use strict' + +const mongoose = require('mongoose'); +const mongooseStamp = require('mongoose-stamp'); +let Schema = mongoose.Schema; + +//create a Schema +let houseSchema = new Schema({ + title: String, + description: String, + price: Number, + image: String, + owner: String, + phone: String, + address: String, + location: { + lat: Number, + lon: Number + } + +}); + +//the schema is useless so far +//we need to create a model using it +houseSchema.plugin(mongooseStamp); +let House = mongoose.model('House', houseSchema); + +//make this available to our users in our Node Applications +module.exports = House; diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..0ba6d33 --- /dev/null +++ b/server/package.json @@ -0,0 +1,22 @@ +{ + "name": "server", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "nodemon app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "body-parser": "^1.17.1", + "cors": "^2.8.3", + "dotenv": "^4.0.0", + "express": "^4.15.2", + "mongoose": "^4.9.5", + "mongoose-stamp": "0.0.3", + "morgan": "^1.8.1", + "nodemon": "^1.11.0" + } +} diff --git a/server/routes/houses.js b/server/routes/houses.js new file mode 100644 index 0000000..5a926ac --- /dev/null +++ b/server/routes/houses.js @@ -0,0 +1,17 @@ +'use strict' + +const express = require('express'); +const router = express.Router(); +const controller = require('../controllers/houseController'); + + router.get('/', controller.getAll) + + .get('/:id', controller.getOne) + + .post('/', controller.createOne) + + .put('/:id', controller.update) + + .delete('/:id', controller.deleteOne) + +module.exports = router; diff --git a/server/routes/index.js b/server/routes/index.js new file mode 100644 index 0000000..4a3d471 --- /dev/null +++ b/server/routes/index.js @@ -0,0 +1,10 @@ +'use strict' +const express = require('express'); +const router = express.Router(); + +/* GET main endpoint. */ +router.get('/', (req, res, next) => { + res.send({ message: 'Welcome Buddy!' }); +}); + +module.exports = router; diff --git a/src/components/AddHouse.vue b/src/components/AddHouse.vue new file mode 100644 index 0000000..82af078 --- /dev/null +++ b/src/components/AddHouse.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/src/components/App.vue b/src/components/App.vue new file mode 100644 index 0000000..1489aef --- /dev/null +++ b/src/components/App.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..1ad4cc2 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,3 @@ +const localUrl = 'http://localhost:3000'; + +module.exports = localUrl diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..22e2bb3 --- /dev/null +++ b/src/main.js @@ -0,0 +1,30 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +import App from './components/App.vue' +import AddHouse from './components/AddHouse.vue' + +// import store from './store' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/', + component: App + }, + { + path: '/houses/new', + component: AddHouse + } +] + +const router = new VueRouter({ + routes +}) + +new Vue({ + el: '#app', + // store, + render: h => h(App) +}) diff --git a/src/store/actions.js b/src/store/actions.js new file mode 100644 index 0000000..e69de29 diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..e69de29 diff --git a/src/store/mutation-types.js b/src/store/mutation-types.js new file mode 100644 index 0000000..e69de29 diff --git a/src/store/mutations.js b/src/store/mutations.js new file mode 100644 index 0000000..e69de29