create-bus-project 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/PUBLISHING.md +35 -0
  3. package/README.md +51 -0
  4. package/bin/create-bus-project.js +113 -0
  5. package/package.json +31 -0
  6. package/template/README.md +35 -0
  7. package/template/backend/.env +8 -0
  8. package/template/backend/.env.example +8 -0
  9. package/template/backend/README.md +29 -0
  10. package/template/backend/config/db.js +21 -0
  11. package/template/backend/controllers/authController.js +109 -0
  12. package/template/backend/controllers/bookingController.js +99 -0
  13. package/template/backend/controllers/busController.js +34 -0
  14. package/template/backend/controllers/scheduleController.js +52 -0
  15. package/template/backend/controllers/userController.js +39 -0
  16. package/template/backend/index.js +39 -0
  17. package/template/backend/package.json +22 -0
  18. package/template/backend/routes/authRoutes.js +17 -0
  19. package/template/backend/routes/bookingRoutes.js +20 -0
  20. package/template/backend/routes/busRoutes.js +10 -0
  21. package/template/backend/routes/scheduleRoutes.js +10 -0
  22. package/template/backend/routes/userRoutes.js +10 -0
  23. package/template/backend/schema.sql +59 -0
  24. package/template/backend/seeders/seedUsers.js +35 -0
  25. package/template/frontend/.env +1 -0
  26. package/template/frontend/.env.example +1 -0
  27. package/template/frontend/README.md +14 -0
  28. package/template/frontend/index.html +12 -0
  29. package/template/frontend/package.json +21 -0
  30. package/template/frontend/src/App.jsx +55 -0
  31. package/template/frontend/src/api.js +1 -0
  32. package/template/frontend/src/main.jsx +10 -0
  33. package/template/frontend/src/pages/Bookings.jsx +129 -0
  34. package/template/frontend/src/pages/Buses.jsx +100 -0
  35. package/template/frontend/src/pages/Dashboard.jsx +10 -0
  36. package/template/frontend/src/pages/Login.jsx +141 -0
  37. package/template/frontend/src/pages/ManagerDashboard.jsx +39 -0
  38. package/template/frontend/src/pages/PassengerDashboard.jsx +248 -0
  39. package/template/frontend/src/pages/Report.jsx +158 -0
  40. package/template/frontend/src/pages/Schedules.jsx +142 -0
  41. package/template/frontend/src/pages/Users.jsx +105 -0
  42. package/template/frontend/src/style.css +236 -0
  43. package/template/frontend/vite.config.js +10 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Umwali Christa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/PUBLISHING.md ADDED
@@ -0,0 +1,35 @@
1
+ # Publishing `create-bus-project` to npm
2
+
3
+ 1. Create or log in to your npm account:
4
+
5
+ ```bash
6
+ npm login
7
+ ```
8
+
9
+ 2. From this package folder, test the package locally:
10
+
11
+ ```bash
12
+ npm pack
13
+ npm install -g ./create-bus-project-1.0.0.tgz
14
+ create-bus-project
15
+ ```
16
+
17
+ 3. Check the package name is available:
18
+
19
+ ```bash
20
+ npm view create-bus-project
21
+ ```
22
+
23
+ If npm returns a 404, the name is available. If it already exists, rename the package in `package.json`, for example `@your-username/create-bus-project`.
24
+
25
+ 4. Publish:
26
+
27
+ ```bash
28
+ npm publish --access public
29
+ ```
30
+
31
+ 5. Use it after publishing:
32
+
33
+ ```bash
34
+ npx create-bus-project
35
+ ```
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # create-bus-project
2
+
3
+ Create a full-stack Bus Booking System with React + Vite frontend, Express backend, and MySQL.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npx create-bus-project
9
+ ```
10
+
11
+ The CLI asks for:
12
+
13
+ - Project name
14
+ - Backend port
15
+ - Frontend port
16
+ - MySQL database name
17
+
18
+ ## Generated app
19
+
20
+ ```text
21
+ my-bus-app/
22
+ ├── backend/
23
+ │ ├── config/
24
+ │ ├── controllers/
25
+ │ ├── routes/
26
+ │ ├── seeders/
27
+ │ ├── schema.sql
28
+ │ ├── .env
29
+ │ └── package.json
30
+ └── frontend/
31
+ ├── src/
32
+ ├── .env
33
+ ├── vite.config.js
34
+ └── package.json
35
+ ```
36
+
37
+ ## Run generated project
38
+
39
+ ```bash
40
+ cd my-bus-app/backend
41
+ npm install
42
+ mysql -u root -p < schema.sql
43
+ npm run seed
44
+ npm run dev
45
+ ```
46
+
47
+ ```bash
48
+ cd my-bus-app/frontend
49
+ npm install
50
+ npm run dev
51
+ ```
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import readline from "node:readline/promises";
5
+ import { stdin as input, stdout as output } from "node:process";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ const packageRoot = path.resolve(__dirname, "..");
11
+ const templateDir = path.join(packageRoot, "template");
12
+
13
+ const pipedAnswers = !process.stdin.isTTY ? fs.readFileSync(0, "utf8").split(/\r?\n/) : [];
14
+ let pipedIndex = 0;
15
+ const rl = process.stdin.isTTY ? readline.createInterface({ input, output }) : null;
16
+
17
+ const slugify = (value) =>
18
+ value
19
+ .trim()
20
+ .toLowerCase()
21
+ .replace(/[^a-z0-9-_]+/g, "-")
22
+ .replace(/^-+|-+$/g, "") || "bus-project";
23
+
24
+ const sanitizeDbName = (value) =>
25
+ value.trim().replace(/[^a-zA-Z0-9_]/g, "_") || "bus_booking";
26
+
27
+ const ask = async (question, defaultValue, validator) => {
28
+ while (true) {
29
+ const raw = rl
30
+ ? await rl.question(`${question} (${defaultValue}): `)
31
+ : (pipedAnswers[pipedIndex++] ?? "");
32
+ const answer = raw.trim() || defaultValue;
33
+ if (!validator || validator(answer)) return answer;
34
+ console.log("Please enter a valid value.");
35
+ }
36
+ };
37
+
38
+ const copyRecursive = (source, destination) => {
39
+ const stat = fs.statSync(source);
40
+ if (stat.isDirectory()) {
41
+ fs.mkdirSync(destination, { recursive: true });
42
+ for (const item of fs.readdirSync(source)) {
43
+ copyRecursive(path.join(source, item), path.join(destination, item));
44
+ }
45
+ return;
46
+ }
47
+ fs.copyFileSync(source, destination);
48
+ };
49
+
50
+ const replaceInFiles = (dir, replacements) => {
51
+ for (const item of fs.readdirSync(dir)) {
52
+ const fullPath = path.join(dir, item);
53
+ const stat = fs.statSync(fullPath);
54
+ if (stat.isDirectory()) {
55
+ replaceInFiles(fullPath, replacements);
56
+ continue;
57
+ }
58
+ const binaryExt = new Set([".png", ".jpg", ".jpeg", ".gif", ".ico", ".pdf", ".zip"]);
59
+ if (binaryExt.has(path.extname(fullPath).toLowerCase())) continue;
60
+ let content = fs.readFileSync(fullPath, "utf8");
61
+ for (const [key, value] of Object.entries(replacements)) {
62
+ content = content.split(key).join(value);
63
+ }
64
+ fs.writeFileSync(fullPath, content);
65
+ }
66
+ };
67
+
68
+ const main = async () => {
69
+ console.log("\nCreate Bus Project\n");
70
+
71
+ const defaultProjectName = process.argv[2] ? slugify(process.argv[2]) : "bus-project";
72
+ const projectName = slugify(await ask("Project name", defaultProjectName));
73
+ const backendPort = await ask("Backend port", "5000", (v) => /^\d+$/.test(v));
74
+ const frontendPort = await ask("Frontend port", "5173", (v) => /^\d+$/.test(v));
75
+ const dbName = sanitizeDbName(await ask("MySQL database name", "bus_booking"));
76
+
77
+ const destination = path.resolve(process.cwd(), projectName);
78
+ if (fs.existsSync(destination) && fs.readdirSync(destination).length > 0) {
79
+ console.error(`\nCannot create project. Folder already exists and is not empty: ${destination}`);
80
+ process.exit(1);
81
+ }
82
+
83
+ copyRecursive(templateDir, destination);
84
+
85
+ replaceInFiles(destination, {
86
+ "__PROJECT_NAME__": projectName,
87
+ "__PROJECT_TITLE__": projectName.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
88
+ "__BACKEND_PORT__": backendPort,
89
+ "__FRONTEND_PORT__": frontendPort,
90
+ "__DB_NAME__": dbName
91
+ });
92
+
93
+ console.log(`\nSuccess! Created ${projectName}.`);
94
+ console.log("\nNext steps:");
95
+ console.log(` cd ${projectName}/backend`);
96
+ console.log(" npm install");
97
+ console.log(` mysql -u root -p < schema.sql`);
98
+ console.log(" npm run seed");
99
+ console.log(" npm run dev");
100
+ console.log("\nIn a second terminal:");
101
+ console.log(` cd ${projectName}/frontend`);
102
+ console.log(" npm install");
103
+ console.log(" npm run dev");
104
+ console.log(`\nFrontend: http://localhost:${frontendPort}`);
105
+ console.log(`Backend: http://localhost:${backendPort}\n`);
106
+ };
107
+
108
+ main()
109
+ .catch((error) => {
110
+ console.error(error);
111
+ process.exit(1);
112
+ })
113
+ .finally(() => rl?.close());
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "create-bus-project",
3
+ "version": "1.0.0",
4
+ "description": "CLI generator for a full-stack Bus Booking System using React, Vite, Express, and MySQL.",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-bus-project": "bin/create-bus-project.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "template",
12
+ "README.md",
13
+ "PUBLISHING.md",
14
+ "LICENSE"
15
+ ],
16
+ "keywords": [
17
+ "bus",
18
+ "booking",
19
+ "react",
20
+ "vite",
21
+ "express",
22
+ "mysql",
23
+ "starter",
24
+ "scaffold"
25
+ ],
26
+ "author": "Umwali Christa",
27
+ "license": "MIT",
28
+ "engines": {
29
+ "node": ">=18"
30
+ }
31
+ }
@@ -0,0 +1,35 @@
1
+ # __PROJECT_TITLE__
2
+
3
+ Full-stack Bus Booking System generated with `create-bus-project`.
4
+
5
+ ## Included
6
+ - React + Vite frontend
7
+ - Node.js + Express backend
8
+ - MySQL database schema
9
+ - Manager and passenger workflows
10
+
11
+ ## Setup
12
+
13
+ ```bash
14
+ cd backend
15
+ npm install
16
+ cp .env.example .env
17
+ # create the database in MySQL, then import schema.sql
18
+ npm run seed
19
+ npm run dev
20
+ ```
21
+
22
+ Open a second terminal:
23
+
24
+ ```bash
25
+ cd frontend
26
+ npm install
27
+ npm run dev
28
+ ```
29
+
30
+ Backend: http://localhost:__BACKEND_PORT__
31
+ Frontend: http://localhost:__FRONTEND_PORT__
32
+ Database: `__DB_NAME__`
33
+
34
+ ## Default users
35
+ Run `npm run seed` in the backend folder to create starter users.
@@ -0,0 +1,8 @@
1
+ PORT=__BACKEND_PORT__
2
+ FRONTEND_URL=http://localhost:__FRONTEND_PORT__
3
+ DB_HOST=localhost
4
+ DB_USER=root
5
+ DB_PASSWORD=
6
+ DB_NAME=__DB_NAME__
7
+ SESSION_SECRET=change_this_secret
8
+ NODE_ENV=development
@@ -0,0 +1,8 @@
1
+ PORT=__BACKEND_PORT__
2
+ FRONTEND_URL=http://localhost:__FRONTEND_PORT__
3
+ DB_HOST=localhost
4
+ DB_USER=root
5
+ DB_PASSWORD=
6
+ DB_NAME=__DB_NAME__
7
+ SESSION_SECRET=change_this_secret
8
+ NODE_ENV=development
@@ -0,0 +1,29 @@
1
+ # Backend Project
2
+
3
+ ## Steps
4
+
5
+ 1. Open MySQL Workbench or phpMyAdmin.
6
+ 2. Run `schema.sql`.
7
+ 3. Install dependencies:
8
+
9
+ ```bash
10
+ npm install
11
+ ```
12
+
13
+ 4. Seed users:
14
+
15
+ ```bash
16
+ npm run seed
17
+ ```
18
+
19
+ 5. Start backend:
20
+
21
+ ```bash
22
+ npm start
23
+ ```
24
+
25
+ Default users:
26
+
27
+ - manager1 / 123456
28
+ - driver1 / 123456
29
+ - passenger1 / 123456
@@ -0,0 +1,21 @@
1
+ import mysql from "mysql2";
2
+ import dotenv from "dotenv";
3
+
4
+ dotenv.config();
5
+
6
+ const db = mysql.createConnection({
7
+ host: process.env.DB_HOST || "localhost",
8
+ user: process.env.DB_USER || "root",
9
+ password: process.env.DB_PASSWORD || "",
10
+ database: process.env.DB_NAME || "__DB_NAME__"
11
+ });
12
+
13
+ db.connect((err) => {
14
+ if (err) {
15
+ console.log("Database connection failed:", err.message);
16
+ } else {
17
+ console.log("Database connected successfully");
18
+ }
19
+ });
20
+
21
+ export default db;
@@ -0,0 +1,109 @@
1
+ import bcrypt from "bcryptjs";
2
+ import db from "../config/db.js";
3
+
4
+ export const register = async (req, res) => {
5
+ const { username, password, userRole } = req.body;
6
+
7
+ if (!username || !password || !userRole) {
8
+ return res.status(400).json({
9
+ message: "Username and password are required"
10
+ });
11
+ }
12
+
13
+ const allowedRoles = ["passenger", "manager"];
14
+
15
+ if (!allowedRoles.includes(userRole)) {
16
+ return res.status(400).json({
17
+ message: "Only passenger and manager registration is allowed"
18
+ });
19
+ }
20
+
21
+ const checkSql = "SELECT * FROM yk_users WHERE username=?";
22
+
23
+ db.query(checkSql, [username], async (err, result) => {
24
+ if (err) return res.status(500).json(err);
25
+
26
+ if (result.length > 0) {
27
+ return res.status(409).json({
28
+ message: "Username already exists"
29
+ });
30
+ }
31
+
32
+ const hashedPassword = await bcrypt.hash(password, 10);
33
+
34
+ const sql = `
35
+ INSERT INTO yk_users(username, password, userRole)
36
+ VALUES(?,?,?)
37
+ `;
38
+
39
+ db.query(sql, [username, hashedPassword, userRole], (err, result) => {
40
+ if (err) return res.status(500).json(err);
41
+
42
+ res.status(201).json({
43
+ message: `${userRole} registered successfully`,
44
+ userid: result.insertId
45
+ });
46
+ });
47
+ });
48
+ };
49
+
50
+ export const login = (req, res) => {
51
+ const { username, password, userRole } = req.body;
52
+
53
+ if (!username || !password || !userRole) {
54
+ return res.status(400).json({
55
+ message: "Username and password are required"
56
+ });
57
+ }
58
+
59
+ const sql = "SELECT * FROM yk_users WHERE username=? AND userRole=?";
60
+
61
+ db.query(sql, [username, userRole], async (err, result) => {
62
+ if (err) return res.status(500).json(err);
63
+
64
+ if (result.length === 0) {
65
+ return res.status(404).json({
66
+ message: `No ${userRole} account found with that username`
67
+ });
68
+ }
69
+
70
+ const user = result[0];
71
+
72
+ const isMatch = await bcrypt.compare(password, user.password);
73
+
74
+ if (!isMatch) {
75
+ return res.status(400).json({
76
+ message: "Wrong password"
77
+ });
78
+ }
79
+
80
+ req.session.user = {
81
+ userid: user.userid,
82
+ username: user.username,
83
+ userRole: user.userRole
84
+ };
85
+
86
+ res.json({
87
+ message: "Login successful",
88
+ user: req.session.user
89
+ });
90
+ });
91
+ };
92
+
93
+ export const logout = (req, res) => {
94
+ req.session.destroy(() => {
95
+ res.json({
96
+ message: "Logged out successfully"
97
+ });
98
+ });
99
+ };
100
+
101
+ export const me = (req, res) => {
102
+ if (!req.session.user) {
103
+ return res.status(401).json({
104
+ message: "Not logged in"
105
+ });
106
+ }
107
+
108
+ res.json(req.session.user);
109
+ };
@@ -0,0 +1,99 @@
1
+ import db from "../config/db.js";
2
+
3
+ export const getBookings = (req, res) => {
4
+ const sql = `SELECT yk_bookings.*, yk_schedules.routename, yk_schedules.departurepoint, yk_schedules.destination FROM yk_bookings INNER JOIN yk_schedules ON yk_bookings.scheduleid = yk_schedules.scheduleid ORDER BY bookingid DESC`;
5
+
6
+ db.query(sql, (err, result) => {
7
+ if (err) {
8
+ res.status(500).json(err);
9
+ }
10
+ res.json(result);
11
+ });
12
+ };
13
+
14
+ export const getMyBookings = (req, res) => {
15
+ const { userid } = req.params;
16
+
17
+ const sql = `
18
+ SELECT yk_bookings.*, yk_schedules.routename, yk_schedules.departurepoint, yk_schedules.destination, yk_schedules.departuretime, yk_schedules.ticketprice FROM yk_bookings INNER JOIN yk_schedules ON yk_bookings.scheduleid = yk_schedules.scheduleid WHERE yk_bookings.userid = ? ORDER BY bookingid DESC`;
19
+
20
+ db.query(sql, [userid], (err, result) => {
21
+ if (err) {
22
+ res.status(500).json(err);
23
+ }
24
+ res.json(result);
25
+ });
26
+ };
27
+
28
+ export const getBookedSeats = (req, res) => {
29
+ const { scheduleid } = req.params;
30
+
31
+ const sql = "SELECT seatnumber FROM yk_bookings WHERE scheduleid=?";
32
+
33
+ db.query(sql, [scheduleid], (err, result) => {
34
+ if (err) {
35
+ res.status(500).json(err);
36
+ }
37
+ res.json(result.map((row) => row.seatnumber));
38
+ });
39
+ };
40
+
41
+ export const createBooking = (req, res) => {
42
+ const { scheduleid,userid,passengername,passengergender,passengerphone,seatnumber,paymentstatus} = req.body;
43
+
44
+ if (!scheduleid || !userid || !passengername || !passengergender || !passengerphone || !seatnumber) {
45
+ return res.status(400).json({ message: "All booking fields are required" });
46
+ }
47
+
48
+ const sql = `INSERT INTO yk_bookings(scheduleid, userid, passengername, passengergender, passengerphone, seatnumber, paymentstatus)VALUES(?,?,?,?,?,?,?)`;
49
+
50
+ db.query(
51
+ sql,
52
+ [scheduleid, userid, passengername, passengergender, passengerphone, seatnumber, paymentstatus || "pending"],
53
+ (err) => {
54
+ if (err) {
55
+ if (err.code === "ER_DUP_ENTRY") {
56
+ return res.status(409).json({ message: "This seat is already booked. Choose another seat." });
57
+ }
58
+ return res.status(500).json(err);
59
+ }
60
+
61
+ res.json({ message: "Booking created successfully" });
62
+ }
63
+ );
64
+ };
65
+
66
+ export const deleteBooking = (req, res) => {
67
+ const { id } = req.params;
68
+
69
+ db.query("DELETE FROM yk_bookings WHERE bookingid=?", [id], (err) => {
70
+ if (err) {
71
+ res.status(500).json(err);
72
+ }
73
+ res.json({ message: "Booking deleted successfully" });
74
+ });
75
+ };
76
+
77
+ export const bookingReport = (req, res) => {
78
+ const sql = `
79
+ SELECT
80
+ yk_schedules.scheduleid,
81
+ yk_schedules.routename,
82
+ yk_schedules.departurepoint,
83
+ yk_schedules.destination,
84
+ yk_schedules.departuretime,
85
+ yk_bookings.passengername,
86
+ yk_bookings.passengergender,
87
+ yk_bookings.passengerphone,
88
+ yk_bookings.seatnumber,
89
+ yk_bookings.paymentstatus
90
+ FROM yk_bookings
91
+ INNER JOIN yk_schedules ON yk_bookings.scheduleid = yk_schedules.scheduleid
92
+ ORDER BY yk_schedules.routename, yk_bookings.seatnumber
93
+ `;
94
+
95
+ db.query(sql, (err, result) => {
96
+ if (err) return res.status(500).json(err);
97
+ res.json(result);
98
+ });
99
+ };
@@ -0,0 +1,34 @@
1
+ import db from "../config/db.js";
2
+
3
+ export const getBuses = (req, res) => {
4
+ db.query("SELECT * FROM yk_buses ORDER BY busid DESC", (err, result) => {
5
+ if (err) {
6
+ res.status(500).json(err);
7
+ }
8
+ res.json(result);
9
+ });
10
+ };
11
+
12
+ export const createBus = (req, res) => {
13
+ const { platenumber, totalseats, bustype } = req.body;
14
+
15
+ const sql = "INSERT INTO yk_buses(platenumber, totalseats, bustype) VALUES(?,?,?)";
16
+
17
+ db.query(sql, [platenumber, totalseats, bustype], (err) => {
18
+ if (err) {
19
+ res.status(500).json(err);
20
+ }
21
+ res.json({ message: "Bus added successfully" });
22
+ });
23
+ };
24
+
25
+ export const deleteBus = (req, res) => {
26
+ const { id } = req.params;
27
+
28
+ db.query("DELETE FROM yk_buses WHERE busid=?", [id], (err) => {
29
+ if (err) {
30
+ res.status(500).json(err);
31
+ }
32
+ res.json({ message: "Bus deleted successfully" });
33
+ });
34
+ };
@@ -0,0 +1,52 @@
1
+ import db from "../config/db.js";
2
+
3
+ export const getSchedules = (req, res) => {
4
+ const sql = `
5
+ SELECT yk_schedules.*, yk_buses.platenumber, yk_buses.totalseats
6
+ FROM yk_schedules
7
+ INNER JOIN yk_buses ON yk_schedules.busid = yk_buses.busid
8
+ ORDER BY scheduleid DESC
9
+ `;
10
+
11
+ db.query(sql, (err, result) => {
12
+ if (err) return res.status(500).json(err);
13
+ res.json(result);
14
+ });
15
+ };
16
+
17
+ export const createSchedule = (req, res) => {
18
+ const {
19
+ busid,
20
+ routename,
21
+ departurepoint,
22
+ destination,
23
+ departuretime,
24
+ estimatedarrivaltime,
25
+ ticketprice,
26
+ scheduleStatus
27
+ } = req.body;
28
+
29
+ const sql = `
30
+ INSERT INTO yk_schedules
31
+ (busid, routename, departurepoint, destination, departuretime, estimatedarrivaltime, ticketprice, scheduleStatus)
32
+ VALUES(?,?,?,?,?,?,?,?)
33
+ `;
34
+
35
+ db.query(
36
+ sql,
37
+ [busid, routename, departurepoint, destination, departuretime, estimatedarrivaltime, ticketprice, scheduleStatus],
38
+ (err) => {
39
+ if (err) return res.status(500).json(err);
40
+ res.json({ message: "Schedule added successfully" });
41
+ }
42
+ );
43
+ };
44
+
45
+ export const deleteSchedule = (req, res) => {
46
+ const { id } = req.params;
47
+
48
+ db.query("DELETE FROM yk_schedules WHERE scheduleid=?", [id], (err) => {
49
+ if (err) return res.status(500).json(err);
50
+ res.json({ message: "Schedule deleted successfully" });
51
+ });
52
+ };
@@ -0,0 +1,39 @@
1
+ import bcrypt from "bcryptjs";
2
+ import db from "../config/db.js";
3
+
4
+ export const getUsers = (req, res) => {
5
+ const sql = "SELECT userid, username, userRole FROM yk_users ORDER BY userid DESC";
6
+
7
+ db.query(sql, (err, result) => {
8
+ if (err) return res.status(500).json(err);
9
+ res.json(result);
10
+ });
11
+ };
12
+
13
+ export const createUser = async (req, res) => {
14
+ const { username, password, userRole } = req.body;
15
+
16
+ if (!username || !password || !userRole) {
17
+ return res.status(400).json({ message: "All fields are required" });
18
+ }
19
+
20
+ const hashedPassword = await bcrypt.hash(password, 10);
21
+
22
+ const sql = "INSERT INTO yk_users(username, password, userRole) VALUES(?,?,?)";
23
+
24
+ db.query(sql, [username, hashedPassword, userRole], (err, result) => {
25
+ if (err) return res.status(500).json(err);
26
+
27
+ res.json({ message: "User created successfully" });
28
+ });
29
+ };
30
+
31
+ export const deleteUser = (req, res) => {
32
+ const { id } = req.params;
33
+
34
+ db.query("DELETE FROM yk_users WHERE userid=?", [id], (err) => {
35
+ if (err) return res.status(500).json(err);
36
+
37
+ res.json({ message: "User deleted successfully" });
38
+ });
39
+ };