diff --git a/badges_engagement/app.js b/badges_engagement/app.js new file mode 100644 index 0000000..cb00214 --- /dev/null +++ b/badges_engagement/app.js @@ -0,0 +1,39 @@ +const express = require('express'); +const mysql = require('mysql2'); +const path = require('path'); +const dotenv = require('dotenv'); + +dotenv.config(); + +const app = express(); + +// Set view engine to EJS +app.set('view engine', 'ejs'); +app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); + +// MySQL database connection +const db = mysql.createConnection({ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASS, + database: process.env.DB_NAME +}); + +db.connect((err) => { + if (err) throw err; + console.log('MySQL connected...'); +}); + +// Routes +const badgesRouter = require('./routes/badges'); +app.use('/badges', badgesRouter); + +// Home route +app.get('/', (req, res) => { + res.render('layout', { page: 'profile' }); +}); + +const PORT = process.env.PORT || 3000; +app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); diff --git a/badges_engagement/config/db.js b/badges_engagement/config/db.js new file mode 100644 index 0000000..b2c9976 --- /dev/null +++ b/badges_engagement/config/db.js @@ -0,0 +1,20 @@ +const mysql = require('mysql'); + +// MySQL connection pool setup +const db = mysql.createConnection({ + host: 'localhost', // or your DB host if remote + user: 'root', // MySQL username + password: '', // MySQL password + database: 'research_nexas' // Database name you created +}); + +// Connect to MySQL +db.connect((err) => { + if (err) { + console.error('Error connecting to the database:', err.stack); + return; + } + console.log('Connected to the MySQL database'); +}); + +module.exports = db; diff --git a/badges_engagement/controller/badgeController.js b/badges_engagement/controller/badgeController.js new file mode 100644 index 0000000..2e6875a --- /dev/null +++ b/badges_engagement/controller/badgeController.js @@ -0,0 +1,21 @@ +const db = require('../config/db'); + +// Get all badges +exports.getBadges = (req, res) => { + const sql = 'SELECT * FROM badges'; + db.query(sql, (err, result) => { + if (err) throw err; + res.json(result); + }); +}; + +// Award a badge to a user +exports.awardBadge = (req, res) => { + const { user_id, badge_id } = req.body; + + const sql = 'INSERT INTO user_badges (user_id, badge_id) VALUES (?, ?)'; + db.query(sql, [user_id, badge_id], (err, result) => { + if (err) throw err; + res.json({ message: 'Badge awarded successfully!' }); + }); +}; diff --git a/badges_engagement/models/badge.js b/badges_engagement/models/badge.js new file mode 100644 index 0000000..8e4e358 --- /dev/null +++ b/badges_engagement/models/badge.js @@ -0,0 +1,43 @@ +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/db'); // Adjust the path as necessary + +const Badge = sequelize.define('Badge', { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + allowNull: false, + unique: true, + }, + criteria: { + type: DataTypes.STRING, + allowNull: false, + }, + createdAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + }, + updatedAt: { + type: DataTypes.DATE, + defaultValue: DataTypes.NOW, + } +}, { + tableName: 'badges', // The name of the table in the database +}); + +// Sync the model with the database +const syncBadges = async () => { + try { + await Badge.sync(); // Creates the table if it doesn't exist + console.log("Badge table has been synced."); + } catch (error) { + console.error("Error syncing Badge table: ", error); + } +}; + +syncBadges(); + +module.exports = Badge; diff --git a/badges_engagement/package.json b/badges_engagement/package.json new file mode 100644 index 0000000..8ca3852 --- /dev/null +++ b/badges_engagement/package.json @@ -0,0 +1,25 @@ +{ + "name": "research-nexas", + "version": "1.0.0", + "description": "Profile Badges and Achievements system for Research-Nexas", + "main": "app.js", + "scripts": { + "start": "node app.js", + "dev": "nodemon app.js" + }, + "dependencies": { + "express": "^4.17.1", + "mysql": "^2.18.1", + "dotenv": "^16.0.0", + "body-parser": "^1.19.0" + }, + "devDependencies": { + "nodemon": "^2.0.20", + "eslint": "^8.0.0", + "jest": "^29.0.0", + "prettier": "^2.5.0" + }, + "author": "Your Name", + "license": "MIT" + } + \ No newline at end of file diff --git a/badges_engagement/public/scripts.js b/badges_engagement/public/scripts.js new file mode 100644 index 0000000..9c2e535 --- /dev/null +++ b/badges_engagement/public/scripts.js @@ -0,0 +1,25 @@ +// Fetch user's badges +function fetchBadges(userId) { + fetch(`/badges/${userId}`) + .then(response => response.json()) + .then(badges => { + const badgeContainer = document.getElementById('badge-container'); + badgeContainer.innerHTML = ''; + + badges.forEach(badge => { + const badgeElement = document.createElement('div'); + badgeElement.classList.add('badge'); + badgeElement.innerHTML = ` +

${badge.name}

+

${badge.description}

+ Earned on: ${new Date(badge.earned_at).toLocaleDateString()} + `; + badgeContainer.appendChild(badgeElement); + }); + }) + .catch(error => console.error('Error fetching badges:', error)); + } + + // Replace with actual userId + fetchBadges(1); + \ No newline at end of file diff --git a/badges_engagement/public/styles.css b/badges_engagement/public/styles.css new file mode 100644 index 0000000..af14da2 --- /dev/null +++ b/badges_engagement/public/styles.css @@ -0,0 +1,39 @@ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + } + + h1, h2 { + text-align: center; + } + + #badge-container { + display: flex; + flex-wrap: wrap; + justify-content: center; + } + + .badge { + background-color: #fff; + border: 1px solid #ddd; + border-radius: 5px; + padding: 10px; + margin: 10px; + width: 200px; + text-align: center; + } + + .badge h3 { + margin: 10px 0; + } + + .badge p { + font-size: 0.9em; + } + + .badge small { + display: block; + margin-top: 5px; + color: #888; + } + \ No newline at end of file diff --git a/badges_engagement/routes/badges.js b/badges_engagement/routes/badges.js new file mode 100644 index 0000000..b6e395c --- /dev/null +++ b/badges_engagement/routes/badges.js @@ -0,0 +1,31 @@ +const express = require('express'); +const router = express.Router(); +const db = require('../db'); // Assuming db.js has your MySQL config + +// Get all badges for a user +router.get('/:userId', (req, res) => { + const { userId } = req.params; + const sql = ` + SELECT badges.name, badges.description, user_badges.earned_at + FROM badges + JOIN user_badges ON badges.id = user_badges.badge_id + WHERE user_badges.user_id = ?`; + + db.query(sql, [userId], (err, results) => { + if (err) throw err; + res.json(results); + }); +}); + +// Award a new badge to a user +router.post('/award', (req, res) => { + const { userId, badgeId } = req.body; + const sql = `INSERT INTO user_badges (user_id, badge_id) VALUES (?, ?)`; + + db.query(sql, [userId, badgeId], (err, result) => { + if (err) throw err; + res.json({ message: 'Badge awarded successfully' }); + }); +}); + +module.exports = router; diff --git a/badges_engagement/sql script b/badges_engagement/sql script new file mode 100644 index 0000000..910fce1 --- /dev/null +++ b/badges_engagement/sql script @@ -0,0 +1,43 @@ +-- Create the database +CREATE DATABASE research_nexas; + +-- Select the database to use +USE research_nexas; + +-- Create the 'student' table +CREATE TABLE student ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + email VARCHAR(255) NOT NULL, + badge_count INT DEFAULT 0 +); + +-- Create the 'badges' table +CREATE TABLE badges ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT NOT NULL, + criteria VARCHAR(255) +); + +-- Create the 'student_badges' table (stores which student earned which badge) +CREATE TABLE student_badges ( + id INT AUTO_INCREMENT PRIMARY KEY, + student_id INT NOT NULL, + badge_id INT NOT NULL, + awarded_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE, + FOREIGN KEY (badge_id) REFERENCES badges(id) ON DELETE CASCADE +); + + +-- Insert some example data into 'student' table +INSERT INTO student (name, email) VALUES ('Alice', 'alice@example.com'); + +-- Insert example badges into 'badges' table +INSERT INTO badges (name, description, criteria) VALUES +('Research Contributor', 'Awarded for submitting 5 research papers', 'Submit 5 papers'), +('Peer Reviewer', 'Awarded for completing 10 peer reviews', 'Complete 10 reviews'); + +-- Award badges to student (student_badges table) +INSERT INTO student_badges (user_id, badge_id) VALUES (1, 1), (1, 2); diff --git a/badges_engagement/views/layout.html b/badges_engagement/views/layout.html new file mode 100644 index 0000000..efdd57e --- /dev/null +++ b/badges_engagement/views/layout.html @@ -0,0 +1,37 @@ + + + + + + Research-Nexas | Profile Badges + + + + + +
+ +
+ +
+

Profile Badges and Achievements

+
+ <%- body %> +
+
+ + + + diff --git a/badges_engagement/views/profile.html b/badges_engagement/views/profile.html new file mode 100644 index 0000000..1b8df91 --- /dev/null +++ b/badges_engagement/views/profile.html @@ -0,0 +1,22 @@ + + + + + + + + User Profile + + +
+

User Profile

+
+ +
+

Your Achievements

+
+
+ + + +