Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
a2df6a4
remove other test and rename A17 -> R01
AmberYen Oct 31, 2021
d3a66dd
remove R03/04/05 test
AmberYen Oct 31, 2021
e0dbcb6
remove R04/05 test
AmberYen Oct 31, 2021
3a5beed
update cofig.json
Carrot7712 Nov 1, 2021
9148715
fixed R01 ../../app issue & not found sequelize lib
AmberYen Nov 1, 2021
154a12e
fixed R01 ../../app issue & not found sequelize lib
AmberYen Nov 1, 2021
c3b664c
fixed R01 ../../app issue & not found sequelize lib
AmberYen Nov 1, 2021
ba68733
fixed controller path wrong issue / check data exist
AmberYen Nov 1, 2021
3f256dc
fixed controller path wrong issue / check data exist
AmberYen Nov 1, 2021
0ab85cd
fixed wrong path
AmberYen Nov 1, 2021
a342d2d
fixed controller path wrong issue / check data exist
AmberYen Nov 1, 2021
b10ee15
fixed wrong path
AmberYen Nov 1, 2021
e45367f
add mockRequest / mockResponse
AmberYen Nov 1, 2021
d487f4a
use new mockRequest / mockResponse
AmberYen Nov 1, 2021
73fc123
require sinon
AmberYen Nov 1, 2021
5224b9a
remove sinon
AmberYen Nov 1, 2021
5d61a30
add mockRequest / mockResponse
AmberYen Nov 1, 2021
51b22d5
use new mockRequest / mockResponse
AmberYen Nov 1, 2021
eba6e76
require sinon
AmberYen Nov 1, 2021
70db2a5
remove sinon
AmberYen Nov 1, 2021
94b4d56
remove sinon
AmberYen Nov 1, 2021
2d18631
add mockRequest / mockResponse
AmberYen Nov 1, 2021
a79fdd0
use new mockRequest / mockResponse
AmberYen Nov 1, 2021
7fef8c7
require sinon
AmberYen Nov 1, 2021
9bf30ca
return [defaulvalue] when findall data empty
AmberYen Nov 1, 2021
05b87a2
remove done param
AmberYen Nov 2, 2021
c014106
remove done param
AmberYen Nov 2, 2021
6eecc8a
remove done param
AmberYen Nov 2, 2021
a1cf9c3
update readme config.json package.json
Carrot7712 Nov 3, 2021
5e1573a
Update .travis.yml
Carrot7712 Nov 5, 2021
c71da44
Update .travis.yml
Carrot7712 Nov 5, 2021
1da8f64
R02 use new mockRequest / mockResponse
AmberYen Nov 1, 2021
dcc8f0e
add helper ref
AmberYen Nov 7, 2021
d54a7fd
R02 use new mockRequest / mockResponse
AmberYen Nov 1, 2021
dde5d1d
add helper ref
AmberYen Nov 7, 2021
049790e
use new mockRequest, mockResponse
AmberYen Nov 7, 2021
72b9738
update readme config.json package.json
Carrot7712 Nov 3, 2021
8c88719
Update .travis.yml
Carrot7712 Nov 5, 2021
ec2c6df
Update .travis.yml
Carrot7712 Nov 5, 2021
80d4dd1
update readme config.json package.json
Carrot7712 Nov 3, 2021
7dc7a56
Update .travis.yml
Carrot7712 Nov 5, 2021
88575da
Update .travis.yml
Carrot7712 Nov 5, 2021
b8259be
Initialize project
HUANG-SIH-MAN Nov 18, 2021
52590c9
feat:Add restaurant index page
HUANG-SIH-MAN Nov 18, 2021
8ab66e9
feat:Add admin restaurant index page
HUANG-SIH-MAN Nov 18, 2021
981adec
feat:Create user model
HUANG-SIH-MAN Nov 18, 2021
d26a398
feat:Add userController and signup page
HUANG-SIH-MAN Nov 18, 2021
48296fd
feat:Confirm user password and unique email
HUANG-SIH-MAN Nov 18, 2021
56608af
feat:Add feature: signInPage, signIn and logout
HUANG-SIH-MAN Nov 18, 2021
5b28862
feat:Add navbar to show login status
HUANG-SIH-MAN Nov 18, 2021
36ddfc6
feat:Add isAdmin to users table,and add authentication before renderi…
HUANG-SIH-MAN Nov 19, 2021
7302034
feat:Create restaurant model
HUANG-SIH-MAN Nov 19, 2021
1dde1f0
feat:Add admin restaurant index page
HUANG-SIH-MAN Nov 19, 2021
2ec789f
feat:Add admin restaurant create form and admin restaurant post feature
HUANG-SIH-MAN Nov 19, 2021
5394221
feat:Add admin restaurant page
HUANG-SIH-MAN Nov 19, 2021
955c9a2
feat:Update admin create page for editing usage,and add admin restaur…
HUANG-SIH-MAN Nov 19, 2021
1723190
feat:Add admin restaurant delete feature
HUANG-SIH-MAN Nov 19, 2021
c32572d
feat:Add image to restaurants and add image upload feature
HUANG-SIH-MAN Nov 19, 2021
b92d2bb
feat:Add user seed data and restaurant seed data
HUANG-SIH-MAN Nov 19, 2021
b47df7d
Install pg and update production config
HUANG-SIH-MAN Nov 19, 2021
b4fb009
Listen to process.env.PORT & define Procfile
HUANG-SIH-MAN Nov 19, 2021
da51bf4
feat:Install Imgur api and update admin POST and PUT
HUANG-SIH-MAN Nov 19, 2021
4c1de29
解決合併衝突
HUANG-SIH-MAN Nov 20, 2021
da2fa70
[Assignment Preparation] ensureAuthenticated & getUser
HUANG-SIH-MAN Nov 20, 2021
2c53049
feat:新增瀏覽所有使用者頁面
HUANG-SIH-MAN Nov 20, 2021
360412f
feat:新增更改使用者權限設定
HUANG-SIH-MAN Nov 22, 2021
935347c
feat:調整程式碼,為了能通過測試檔案
HUANG-SIH-MAN Nov 22, 2021
7d6f709
feat:Create category model and add restaurant.CategoryId and association
HUANG-SIH-MAN Nov 23, 2021
a4bc57c
heroku PG switch to ClearDB mysql
HUANG-SIH-MAN Nov 23, 2021
97c7146
feat:Add category seed data
HUANG-SIH-MAN Nov 23, 2021
13384e2
feat:Show category name
HUANG-SIH-MAN Nov 23, 2021
e8c51f8
feat:Add categories selector on admin create and edit page
HUANG-SIH-MAN Nov 23, 2021
829b6ce
feat:Update category select in edit page using ifCond-helper
HUANG-SIH-MAN Nov 23, 2021
cb4cc74
feat:Add admin categories page
HUANG-SIH-MAN Nov 23, 2021
b3d6b4c
feat:Add admin categories post feature
HUANG-SIH-MAN Nov 23, 2021
45fbdd6
feat:Add admin categories edit and put feature
HUANG-SIH-MAN Nov 23, 2021
0b1247b
feat:Add admin categories delete feature
HUANG-SIH-MAN Nov 23, 2021
8e33854
feat:Add restaurants index page
HUANG-SIH-MAN Nov 23, 2021
1e2cc27
feat:Add restaurants show page
HUANG-SIH-MAN Nov 23, 2021
2d65b6e
feat:Add categories navbar on restaurants index page
HUANG-SIH-MAN Nov 23, 2021
a5caf4d
feat:Add pagination on restaurants index
HUANG-SIH-MAN Nov 24, 2021
1a1b3cd
feat:Create comment model & add association among users, comment, res…
HUANG-SIH-MAN Nov 24, 2021
d0695db
feat:Add post comment feature on restaurant page
HUANG-SIH-MAN Nov 24, 2021
008cacb
feat:Show related comments on restaurant page
HUANG-SIH-MAN Nov 24, 2021
f128cdd
feat:Add delete comment feature for admin
HUANG-SIH-MAN Nov 24, 2021
3a86123
解決合併衝突
HUANG-SIH-MAN Nov 24, 2021
c83596f
解決合併衝突2
HUANG-SIH-MAN Nov 24, 2021
a9116e5
feat:建立個人資料頁面
HUANG-SIH-MAN Nov 24, 2021
8abd636
feat:在使用者的model新增照片欄位
HUANG-SIH-MAN Nov 24, 2021
06b420b
feat:新增瀏覽使用者頁面路由,修改無法取得個人圖片資料的錯誤設定(user model內)
HUANG-SIH-MAN Nov 25, 2021
cf37569
feat:建立編輯 Profile 頁面
HUANG-SIH-MAN Nov 25, 2021
59dbeb3
feat:完成編輯 Profile功能
HUANG-SIH-MAN Nov 25, 2021
2c16f40
使用async/await改寫putUser失敗(程式碼已註解)
HUANG-SIH-MAN Nov 25, 2021
5164db4
feat:在個人頁面顯示評論過的餐廳
HUANG-SIH-MAN Nov 26, 2021
020752e
feat:Add feeds page
HUANG-SIH-MAN Nov 26, 2021
f694ed3
解決合併衝突
HUANG-SIH-MAN Nov 26, 2021
0d94585
改寫getUser取得使用者資料,為了通過R02測試檔
HUANG-SIH-MAN Nov 27, 2021
485c7d0
feat:新增dashboard 頁面會彙整餐廳資訊(可顯示評論數)
HUANG-SIH-MAN Nov 27, 2021
22678a3
feat:新增餐廳計算瀏覽次數功能
HUANG-SIH-MAN Nov 27, 2021
c07c01f
feat:Create favorite model and set association between restaurant and…
HUANG-SIH-MAN Nov 27, 2021
a9b8ff2
feat:Add favorite/unfavorite feature
HUANG-SIH-MAN Dec 10, 2021
963c673
feat:Switch add/remove favorite button on restaurants index page and …
HUANG-SIH-MAN Dec 10, 2021
5f91b04
解決合併衝突
HUANG-SIH-MAN Dec 10, 2021
e6fb1f9
feat:新增like/Ulike餐廳功能(無法通過測試檔)
HUANG-SIH-MAN Dec 11, 2021
540bf98
fix:修改R04測試檔模擬資料
HUANG-SIH-MAN Dec 13, 2021
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
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
IMGUR_CLIENT_ID =
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: NODE_ENV=production node app.js
32 changes: 30 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
const express = require('express')
const exphbs = require('express-handlebars')
const flash = require('connect-flash')
const session = require('express-session')
const passport = require('./config/passport')
const methodOverride = require('method-override')
const bodyParser = require('body-parser')
const helpers = require('./_helpers')
const handlebarsHelpers = require('./helpers/handlebarsHelpers')
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}
const app = express()
const port = 3000
const port = process.env.PORT || 3000

app.engine('handlebars', exphbs({ defaultLayout: 'main', helpers: handlebarsHelpers }))
app.set('view engine', 'handlebars')
app.use(methodOverride('_method'))
app.use(express.urlencoded({extended: true}))
app.use(session({ secret: 'secret', resave: false, saveUninitialized: false }))
app.use(passport.initialize())
app.use(passport.session())
app.use(flash())

app.use((req, res, next) => {
res.locals.user = helpers.getUser(req)
res.locals.success_messages = req.flash('success_messages')
res.locals.error_messages = req.flash('error_messages')
next()
})

app.use('/upload', express.static(__dirname + '/upload'))
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})

require('./routes')(app)
require('./routes')(app, passport)

module.exports = app
13 changes: 8 additions & 5 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
"use_env_variable": "CLEARDB_DATABASE_URL",
"dialect": "postgres",
"protocol": "postgres",
"dialectOptions": {
"ssl": {
"rejectUnauthorized": false
}
}
},
"travis": {
"username": "travis",
Expand Down
42 changes: 42 additions & 0 deletions config/passport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const passport = require('passport')
const LocalStrategy = require('passport-local')
const bcrypt = require('bcryptjs')
const db = require('../models')
const User = db.User
const Restaurant = db.Restaurant

// setup passport strategy
passport.use(new LocalStrategy(
// customize user field
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
// authenticate user
(req, username, password, cb) => {
User.findOne({ where: { email: username } }).then(user => {
if (!user) return cb(null, false, req.flash('error_messages', '帳號或密碼輸入錯誤'))
if (!bcrypt.compareSync(password, user.password)) return cb(null, false, req.flash('error_messages', '帳號或密碼輸入錯誤!'))
return cb(null, user)
})
}
))

// serialize and deserialize user
passport.serializeUser((user, cb) => {
cb(null, user.id)
})
passport.deserializeUser((id, cb) => {
User.findByPk(id,{
include: [
{ model: Restaurant, as: 'FavoritedRestaurants' },
{ model: Restaurant, as: 'LikedRestaurants' }
]
}).then(user => {
user = user.toJSON() // 此處與影片示範不同
return cb(null, user)
})
})

module.exports = passport
176 changes: 176 additions & 0 deletions controllers/adminController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
const fs = require('fs')
const imgur = require('imgur-node-api')
const IMGUR_CLIENT_ID = process.env.IMGUR_CLIENT_ID
const db = require('../models')
const Restaurant = db.Restaurant
const User = db.User
const Category = db.Category

const adminController = {
getRestaurants: (req, res) => {
return Restaurant.findAll({
raw: true,
nest: true,
include: [Category]
})
.then(restaurants => {
return res.render('admin/restaurants', { restaurants })
})
},

createRestaurant: (req, res) => {
Category.findAll({
raw: true,
nest: true
}).then(categories => {
return res.render('admin/create', { categories })
})
},

postRestaurant: (req, res) => {
if(!req.body.name){
req.flash('error_messages', "name didn't exist")
return res.redirect('back')
}

const { file } = req
if (file) {
imgur.setClientID(IMGUR_CLIENT_ID);
imgur.upload(file.path, (err, img) => {
return Restaurant.create({
name: req.body.name,
tel: req.body.tel,
address: req.body.address,
opening_hours: req.body.opening_hours,
description: req.body.description,
image: file ? img.data.link : null,
CategoryId: req.body.categoryId
}).then((restaurant) => {
req.flash('success_messages', 'restaurant was successfully created')
return res.redirect('/admin/restaurants')
})
})
}
else {
return Restaurant.create({
name: req.body.name,
tel: req.body.tel,
address: req.body.address,
opening_hours: req.body.opening_hours,
description: req.body.description,
image: null,
CategoryId: req.body.categoryId
}).then((restaurant) => {
req.flash('success_messages', 'restaurant was successfully created')
return res.redirect('/admin/restaurants')
})
}
},

getRestaurant: (req, res) => {
return Restaurant.findByPk(req.params.id, {
include: [Category]
})
.then(restaurant => {
return res.render('admin/restaurant', { restaurant: restaurant.toJSON() })
})
},

editRestaurant: (req, res) => {
Category.findAll({
raw: true,
nest: true
}).then(categories => {
return Restaurant.findByPk(req.params.id).then(restaurant => {
return res.render('admin/create', {
categories,
restaurant: restaurant.toJSON()
})
})
})
},

putRestaurant: (req, res) => {
if(!req.body.name){
req.flash('error_messages', "name didn't exist")
return res.redirect('back')
}

const { file } = req
if (file) {
imgur.setClientID(IMGUR_CLIENT_ID);
imgur.upload(file.path, (err, img) => {
return Restaurant.findByPk(req.params.id)
.then((restaurant) => {
restaurant.update({
name: req.body.name,
tel: req.body.tel,
address: req.body.address,
opening_hours: req.body.opening_hours,
description: req.body.description,
image: file ? img.data.link : restaurant.image,
CategoryId: req.body.categoryId
})
.then((restaurant) => {
req.flash('success_messages', 'restaurant was successfully to update')
res.redirect('/admin/restaurants')
})
})
})
}
else {
return Restaurant.findByPk(req.params.id)
.then((restaurant) => {
restaurant.update({
name: req.body.name,
tel: req.body.tel,
address: req.body.address,
opening_hours: req.body.opening_hours,
description: req.body.description,
image: restaurant.image
})
.then((restaurant) => {
req.flash('success_messages', 'restaurant was successfully to update')
res.redirect('/admin/restaurants')
})
})
}
},

deleteRestaurant: (req, res) => {
return Restaurant.findByPk(req.params.id)
.then((restaurant) => {
restaurant.destroy()
.then((restaurant) => {
res.redirect('/admin/restaurants')
})
})
},

getUsers: (req, res) => {
return User.findAll({ raw: true, nest: true })
.then(users => res.render('admin/users', { users }))
},

toggleAdmin: async (req, res) => {
//判斷是否能變更管理權限 (自己不能變更自己)
// if (Number(req.params.id) === req.user.id) {
// req.flash('error_messages','禁止變更管理者權限')
// return res.redirect('/admin/users')
// }
//變更管理權限
return User.findByPk(req.params.id)
.then(async (user) => {
if (user.email === 'root@example.com') {
req.flash('error_messages','禁止變更管理者權限')
return res.redirect('back')
}
user.isAdmin ? await user.update({isAdmin: false }) : await user.update({isAdmin: true })
req.flash('success_messages','使用者權限變更成功')
return res.redirect('/admin/users')
})
}
}


module.exports = adminController
59 changes: 59 additions & 0 deletions controllers/categoryController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const db = require('../models')
const Category = db.Category
let categoryController = {
getCategories: (req, res) => {
return Category.findAll({
raw: true,
nest: true
}).then(categories => {
if (req.params.id) {
Category.findByPk(req.params.id)
.then((category) => {
return res.render('admin/categories', {
categories: categories,
category: category.toJSON()
})
})
} else {
return res.render('admin/categories', { categories: categories })
}
})
},
postCategory: (req, res) => {
if (!req.body.name) {
req.flash('error_messages', 'name didn\'t exist')
return res.redirect('back')
} else {
return Category.create({
name: req.body.name
})
.then((category) => {
res.redirect('/admin/categories')
})
}
},
putCategory: (req, res) => {
if (!req.body.name) {
req.flash('error_messages', 'name didn\'t exist')
return res.redirect('back')
} else {
return Category.findByPk(req.params.id)
.then((category) => {
category.update(req.body)
.then((category) => {
res.redirect('/admin/categories')
})
})
}
},
deleteCategory: (req, res) => {
return Category.findByPk(req.params.id)
.then((category) => {
category.destroy()
.then((category) => {
res.redirect('/admin/categories')
})
})
}
}
module.exports = categoryController
26 changes: 26 additions & 0 deletions controllers/commentController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const db = require('../models')
const Comment = db.Comment

const commentController = {
postComment: (req, res) => {
return Comment.create({
text: req.body.text,
RestaurantId: req.body.restaurantId,
UserId: req.user.id
})
.then((comment) => {
res.redirect(`/restaurants/${req.body.restaurantId}`)
})
},
deleteComment: (req, res) => {
return Comment.findByPk(req.params.id)
.then((comment) => {
comment.destroy()
.then((comment) => {
res.redirect(`/restaurants/${comment.RestaurantId}`)
})
})
}
}

module.exports = commentController
Loading