Browse Source

BE notfix

master
Wendy Gardiel 1 week ago
parent
commit
6ab79a7812
  1. 2
      .gitignore
  2. 52
      controllers/blogController.js
  3. 5
      index.js
  4. 5
      models/blogModel.js
  5. 23
      package-lock.json
  6. 1
      package.json
  7. 8
      routes/blogRoutes.js
  8. 9
      user.rest

2
.gitignore

@ -115,3 +115,5 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
uploads/

52
controllers/blogController.js

@ -26,20 +26,35 @@ export const getBlogById = async (req, res) => {
}
};
// Get blog by slug
export const getBlogBySlug = async (req, res) => {
try {
const blog = await blogModel.findOne({
where: { slug: req.params.slug },
include: [{ model: blogImage, as: "images" }],
});
if (!blog) return res.status(404).json({ message: "Blog not found" });
res.json(blog);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Create a new blog
export const createBlog = async (req, res) => {
try {
const { title, description } = req.body;
// Pastikan ada file yang diunggah
if (!req.files || req.files.length === 0) {
return res.status(400).json({ message: "Minimal 1 gambar diperlukan!" });
}
// Simpan data blog
const blog = await blogModel.create({ title, description });
const slug = generateSlug(title); // 🔥 generate slug di sini
const blog = await blogModel.create({ title, description, slug });
// Simpan gambar ke database
const imagePaths = req.files.map((file) => ({
blogId: blog.id,
imageUrl: `/uploads/${file.filename}`,
@ -47,9 +62,8 @@ export const createBlog = async (req, res) => {
await blogImage.bulkCreate(imagePaths);
// Ambil data blog beserta gambar setelah disimpan
const newBlog = await blogModel.findByPk(blog.id, {
include: [{ model: blogImage, as: "images" }], // Pastikan alias sesuai
include: [{ model: blogImage, as: "images" }],
});
res.status(201).json({
@ -61,12 +75,36 @@ export const createBlog = async (req, res) => {
}
};
const generateSlug = (title) => {
return title
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^\w-]+/g, "");
};
// Update a blog
export const updateBlog = async (req, res) => {
try {
const blog = await blogModel.findByPk(req.params.id);
if (!blog) return res.status(404).json({ message: "Blog not found" });
await blog.update(req.body);
const { title, description, slug } = req.body;
// Tentukan slug baru (jika ada title baru dan tidak ada slug manual)
let updatedSlug = blog.slug; // default: slug lama
if (title && !slug) {
updatedSlug = generateSlug(title);
} else if (slug) {
updatedSlug = slug;
}
// Update data
await blog.update({
title: title ?? blog.title,
description: description ?? blog.description,
slug: updatedSlug,
});
res.json(blog);
} catch (error) {
res.status(500).json({ message: error.message });

5
index.js

@ -3,11 +3,14 @@ import db from "./config/database.js";
import dotenv from "dotenv";
import router from "./routes/index.js"; // Hanya import 1 router
import cors from "cors";
import cookieParser from "cookie-parser";
import path from "path";
const app = express();
dotenv.config();
const connectToDatabase = async () => {
// await db.sync({ force: true });
try {
await db.authenticate();
console.log("Database connected...");
@ -18,8 +21,10 @@ const connectToDatabase = async () => {
connectToDatabase();
app.use(cookieParser());
app.use(cors());
app.use(express.json());
app.use(router);
app.use("/uploads", express.static(path.join(process.cwd(), "uploads")));
app.listen(5000, () => console.log("server running at port 5000"));

5
models/blogModel.js

@ -13,6 +13,11 @@ const Blog = db.define("blog", {
type: DataTypes.TEXT,
allowNull: false,
},
slug: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
});
// Definisi relasi dengan alias 'images'

23
package-lock.json

@ -10,6 +10,7 @@
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.21.2",
@ -455,6 +456,28 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-parser": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
"integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
"license": "MIT",
"dependencies": {
"cookie": "0.7.2",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",

1
package.json

@ -11,6 +11,7 @@
},
"dependencies": {
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"dotenv": "^16.4.7",
"express": "^4.21.2",

8
routes/blogRoutes.js

@ -2,6 +2,7 @@ import express from "express";
import {
getAllBlogs,
getBlogById,
getBlogBySlug,
createBlog,
updateBlog,
deleteBlog,
@ -13,8 +14,9 @@ const router = express.Router();
router.get("/blog", getAllBlogs);
router.get("/blog/:id", getBlogById);
router.post("/blog", verifyToken, upload.array("images", 5), createBlog);
router.patch("/blog/:id", verifyToken, updateBlog);
router.delete("/blog/:id", verifyToken, deleteBlog);
router.get("/blog/slug/:slug", getBlogBySlug);
router.post("/blog", upload.array("images", 5), createBlog);
router.put("/blog/:id", updateBlog);
router.delete("/blog/:id", deleteBlog);
export default router;

9
user.rest

@ -1,9 +1,9 @@
POST http://localhost:5000/user/register
POST http://localhost:5000/users/register
Content-type: application/json
{
"name" : "admin2",
"email" : "admin2@admin.com",
"name" : "admin",
"email" : "admin@admin.com",
"password" : "admin123",
"confirmPassword" : "admin123"
}
@ -20,6 +20,5 @@ Content-Type: application/json
###
GET http://localhost:5000/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsIm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiaWF0IjoxNzQzMDQ0NDg5LCJleHAiOjE3NDMwNDQ1MDl9.m_tpB5DPpFDIaSWQki8jCKWqCbSzsBaKqh3W35a32XI
GET http://localhost:5000/users/token
|||||||
100:0
Loading…
Cancel
Save