diff --git a/controllers/categories.js b/controllers/categories.js new file mode 100644 index 00000000..26c2471c --- /dev/null +++ b/controllers/categories.js @@ -0,0 +1,29 @@ +let express = require('express') +let db = require('../models') +let router = express.Router() + +router.get('/', (req, res) => { + db.category.findAll() + .then((category) => { + res.render('categories/categories', {category: category}) + }) + .catch((error) => { + console.log('Error in GET /', error) + res.status(400).render('main/404') + }) + }) + + router.get('/:id', async (req, res) => { + try { + const category = await db.category.findByPk(req.params.id, { + include: [db.project] + }) + res.render('categories/show', { category: category }) + } catch (error) { + console.log('Error in GET /categories/:id', error) + res.status(400).render('main/404') + } + }) + + +module.exports = router \ No newline at end of file diff --git a/controllers/projects.js b/controllers/projects.js index 3d878a8a..9b04778b 100644 --- a/controllers/projects.js +++ b/controllers/projects.js @@ -3,20 +3,29 @@ let db = require('../models') let router = express.Router() // POST /projects - create a new project -router.post('/', (req, res) => { - db.project.create({ - name: req.body.name, - githubLink: req.body.githubLink, - deployLink: req.body.deployedLink, - description: req.body.description - }) - .then((project) => { - res.redirect('/') - }) - .catch((error) => { - res.status(400).render('main/404') - }) -}) +router.post('/', async (req, res) => { + try { + const [project, category] = await Promise.all([ + db.project.create({ + name: req.body.name, + githubLink: req.body.githubLink, + deployLink: req.body.deployedLink, + description: req.body.description + }), + db.category.findOrCreate({ + where: { + name: req.body.category + } + }) + ]); + + await project.addCategory(category[0]); + + res.redirect('/'); + } catch (error) { + res.status(400).render('main/404'); + } +}); // GET /projects/new - display form for creating a new project router.get('/new', (req, res) => { @@ -37,4 +46,28 @@ router.get('/:id', (req, res) => { }) }) +router.put('/:id', async (req, res) => { + try { + const project = await db.project.findByPk(req.params.id) + + if (!project) { + res.status(404).render('main/404') + return + } + + const category = await db.category.findOrCreate({ + where: { + name: req.body.category + } + }) + + await project.addCategory(category) + + res.redirect(`/projects/${project.id}`) + } catch (error) { + console.log(error) + res.status(400).render('main/404') + } +}) + module.exports = router diff --git a/dbTest.js b/dbTest.js new file mode 100644 index 00000000..887092ec --- /dev/null +++ b/dbTest.js @@ -0,0 +1,16 @@ +const db = require('./models') + +db.project.findOne({ + where: { id: 1 }, + include: [db.category] + }) + .then(project => { + // by using eager loading, the project model should have a categories key + console.log(project.categories) + + // createCategory function should be available to this model - it will create the category then add it to the project + project.createCategory({ name: 'express' }) + .then(category => { + console.log(category.id) + }) + }) \ No newline at end of file diff --git a/index.js b/index.js index f404f83d..34cc24c4 100644 --- a/index.js +++ b/index.js @@ -23,7 +23,19 @@ app.get('/', (req, res) => { }) }) +app.get('/', (req, res) => { + db.category.findAll() + .then((category) => { + res.render('categories/categories', {category: category}) + }) + .catch((error) => { + console.log('Error in GET /', error) + res.status(400).render('main/404') + }) + }) + app.use('/projects', require('./controllers/projects')) +app.use('/categories', require('./controllers/categories')) app.get('*', (req, res) => { res.render('main/404') diff --git a/migrations/20230406133809-create-category.js b/migrations/20230406133809-create-category.js new file mode 100644 index 00000000..8e52fd79 --- /dev/null +++ b/migrations/20230406133809-create-category.js @@ -0,0 +1,28 @@ +'use strict'; +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('categories', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + async down(queryInterface, Sequelize) { + await queryInterface.dropTable('categories'); + } +}; \ No newline at end of file diff --git a/migrations/20230406134316-create-category-project.js b/migrations/20230406134316-create-category-project.js new file mode 100644 index 00000000..b0907470 --- /dev/null +++ b/migrations/20230406134316-create-category-project.js @@ -0,0 +1,31 @@ +'use strict'; +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('category_projects', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + categoryId: { + type: Sequelize.INTEGER + }, + projectId: { + type: Sequelize.INTEGER + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + async down(queryInterface, Sequelize) { + await queryInterface.dropTable('category_projects'); + } +}; \ No newline at end of file diff --git a/models/category.js b/models/category.js new file mode 100644 index 00000000..328b1eda --- /dev/null +++ b/models/category.js @@ -0,0 +1,24 @@ +'use strict'; +const { + Model +} = require('sequelize'); +module.exports = (sequelize, DataTypes) => { + class category extends Model { + /** + * Helper method for defining associations. + * This method is not a part of Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + // define association here + models.category.belongsToMany(models.project, {through: 'category_project'}) + } + } + category.init({ + name: DataTypes.STRING + }, { + sequelize, + modelName: 'category', + }); + return category; +}; \ No newline at end of file diff --git a/models/category_project.js b/models/category_project.js new file mode 100644 index 00000000..776c9234 --- /dev/null +++ b/models/category_project.js @@ -0,0 +1,24 @@ +'use strict'; +const { + Model +} = require('sequelize'); +module.exports = (sequelize, DataTypes) => { + class category_project extends Model { + /** + * Helper method for defining associations. + * This method is not a part of Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + // define association here + } + } + category_project.init({ + categoryId: DataTypes.INTEGER, + projectId: DataTypes.INTEGER + }, { + sequelize, + modelName: 'category_project', + }); + return category_project; +}; \ No newline at end of file diff --git a/models/project.js b/models/project.js index 735a0a47..9fac4968 100644 --- a/models/project.js +++ b/models/project.js @@ -11,6 +11,7 @@ module.exports = (sequelize, DataTypes) => { */ static associate(models) { // define association here + models.project.belongsToMany(models.category, {through: 'category_project'}) } } project.init({ diff --git a/package.json b/package.json index cbce809b..3479837f 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "license": "ISC", "dependencies": { "async": "^2.6.2", + "bootstrap": "^5.2.3", "ejs": "^2.4.2", "express": "^4.16.4", "express-ejs-layouts": "^2.1.0", diff --git a/views/categories/categories.ejs b/views/categories/categories.ejs new file mode 100644 index 00000000..f2cd01fd --- /dev/null +++ b/views/categories/categories.ejs @@ -0,0 +1,10 @@ +

Categories

+ + +<% category.forEach(function(category) { %> +
+

+ <%= category.name %> +

+
+<% }); %> \ No newline at end of file diff --git a/views/categories/show.ejs b/views/categories/show.ejs new file mode 100644 index 00000000..b7399281 --- /dev/null +++ b/views/categories/show.ejs @@ -0,0 +1,9 @@ +

<%= category.name %>

+ + + +Back to Categories \ No newline at end of file diff --git a/views/partials/navbar.ejs b/views/partials/navbar.ejs index 081dee3b..883c2e2a 100644 --- a/views/partials/navbar.ejs +++ b/views/partials/navbar.ejs @@ -15,6 +15,7 @@ diff --git a/views/projects/new.ejs b/views/projects/new.ejs index 3342d3ee..77869f97 100644 --- a/views/projects/new.ejs +++ b/views/projects/new.ejs @@ -21,5 +21,10 @@ +
+ + +
+ diff --git a/views/projects/show.ejs b/views/projects/show.ejs index aea2f8cb..4ef02c53 100644 --- a/views/projects/show.ejs +++ b/views/projects/show.ejs @@ -14,4 +14,14 @@
+
+ +
+ + +
+ + +
+ ← Back Home