The SkillXchange reporting system allows users to report inappropriate content, spam, harassment, and policy violations across the platform. The system is fully integrated into the existing MVC structure and follows the project's vanilla PHP, HTML, CSS, and JavaScript architecture.
- User Profiles - Report fake profiles, spam accounts, or harassment
- Project Members - Report members within a project context
- Community Posts - Report inappropriate forum posts
- Project Chat Messages - Report offensive or spam messages
- Spam
- Harassment
- Hate speech
- Fake profile
- Inappropriate content
- Other
- ✅ Users cannot report themselves
- ✅ Duplicate report prevention (one report per user per content)
- ✅ Login required to submit reports
- ✅ Content ownership verification
- ✅ AJAX-based submission (no page refresh)
CREATE TABLE content_reports (
id INT AUTO_INCREMENT PRIMARY KEY,
reporter_id INT NOT NULL,
content_type ENUM('post','chat_message') NOT NULL,
content_id INT NOT NULL,
reason VARCHAR(255) NOT NULL,
description TEXT DEFAULT NULL,
status ENUM('pending','reviewed','dismissed') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE reports (
id INT AUTO_INCREMENT PRIMARY KEY,
reporter_id INT NOT NULL,
reported_user_id INT NOT NULL,
reason VARCHAR(255) NOT NULL,
description TEXT DEFAULT NULL,
status ENUM('pending','reviewed','dismissed') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE user_reports (
id INT AUTO_INCREMENT PRIMARY KEY,
reporter_id INT NOT NULL,
reported_user_id INT NOT NULL,
project_id INT NOT NULL,
reason VARCHAR(255) NOT NULL,
description TEXT DEFAULT NULL,
status ENUM('pending','reviewed','dismissed') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);- File:
app/controllers/ReportController.php - Methods:
reportUser()- POST /report/reportUserreportProjectUser()- POST /report/reportProjectUserreportContent()- POST /report/reportContent
- Modal Component:
app/views/components/report_button.php - Integrated into:
- User profiles (
app/views/users/view_profile.php) - Community posts (
app/views/community/view.php) - Project members (
app/views/projects/view.php) - Project chat (
app/views/organization/chats.php)
- User profiles (
- CSS:
public/assets/css/reporting.css - JavaScript:
public/assets/js/reporting.js
# Run the migration to create all tables
& "C:\xampp\mysql\bin\mysql.exe" -u root skillxchange < database/migrations/setup_reporting_system.sql<button class="report-btn report-user-btn" data-user-id="<?= $user->id ?>">
<span class="report-btn-icon">⚠</span>
Report Profile
</button><button class="report-btn-small report-project-member-btn"
data-user-id="<?= $member->user_id ?>"
data-project-id="<?= $project->id ?>"
title="Report this member">
<span>⚠</span>
</button><?php if (isset($_SESSION['user_id']) && $_SESSION['user_id'] != $post->user_id): ?>
<button class="report-btn-small report-content-btn"
data-content-type="post"
data-content-id="<?= $post->id ?>"
title="Report this post">
<span>⚠</span>
</button>
<?php endif; ?>// In JavaScript for dynamically rendered messages
if (!isMine) {
const reportBtn = document.createElement('button');
reportBtn.className = 'report-btn-small report-content-btn';
reportBtn.setAttribute('data-content-type', 'chat_message');
reportBtn.setAttribute('data-content-id', messageId);
reportBtn.title = 'Report this message';
reportBtn.innerHTML = '<span>⚠</span>';
messageElement.appendChild(reportBtn);
}<!-- Add CSS -->
<link rel="stylesheet" href="<?= URLROOT ?>/assets/css/reporting.css">
<!-- Add JavaScript -->
<script>window.URLROOT = '<?= URLROOT ?>';</script>
<script src="<?= URLROOT ?>/assets/js/reporting.js"></script>Report a user profile.
Parameters:
reported_user_id(int) - ID of the user being reportedreason(string) - Reason for reportdescription(text, optional) - Additional details
Response:
{
"success": true,
"message": "Your report has been submitted successfully."
}Report a project member.
Parameters:
reported_user_id(int) - ID of the member being reportedproject_id(int) - ID of the projectreason(string) - Reason for reportdescription(text, optional) - Additional details
Response:
{
"success": true,
"message": "Your report has been submitted successfully."
}Report a post or chat message.
Parameters:
content_type(enum: 'post', 'chat_message')content_id(int) - ID of the contentreason(string) - Reason for reportdescription(text, optional) - Additional details
Response:
{
"success": true,
"message": "Your report has been submitted successfully."
}- Background: Soft white (#FFFFFF)
- Header: Blue gradient (matching project palette)
- Rounded corners: 12px
- Shadow: Subtle drop shadow for depth
- Backdrop: Blurred overlay (rgba + backdrop-filter)
- Regular Button: Grey background with icon and text
- Small Button: Icon-only, transparent, 32x32px
- Hover: Darker grey background
- Colors: Matches existing project design system
- Success: Green gradient (#10b981 to #059669)
- Error: Red gradient (#ef4444 to #dc2626)
- Position: Top-right corner
- Auto-dismiss: 3 seconds
- Animation: Slide in from right
-
Report User Profile
- Go to any user profile
- Click "Report Profile" button
- Fill out modal with reason
- Submit and verify success toast
- Try submitting duplicate (should fail)
-
Report Community Post
- Navigate to a community
- Find a post from another user
- Click small ⚠ icon
- Submit report
- Verify toast confirmation
-
Report Project Member
- Open a project detail page
- Find team members section
- Click ⚠ on a member card
- Submit report with project context
-
Report Chat Message
- Open project chat
- Find message from another user
- Click ⚠ button on message bubble
- Submit report
- ✅ Cannot report own profile/content
- ✅ Cannot submit duplicate reports
- ✅ Must be logged in to report
- ✅ All fields validated before submission
- ✅ Modal closes automatically on success
app/controllers/ReportController.phpapp/views/components/report_button.phppublic/assets/css/reporting.csspublic/assets/js/reporting.jsdatabase/migrations/create_content_reports_table.sqldatabase/migrations/setup_reporting_system.sql
app/views/users/view_profile.php- Added report button to user profilesapp/views/community/view.php- Added report buttons to postsapp/views/users/community_forum.php- Added report buttons to forum postsapp/views/projects/view.php- Added report buttons to project membersapp/views/organization/chats.php- Added report buttons to chat messagespublic/assets/js/community_forum.js- Added report buttons to dynamic posts
The system is ready for admin reporting dashboard implementation:
- Reports Overview - All pending reports
- Filter by Type - User/Content/Project reports
- Bulk Actions - Approve/Dismiss multiple reports
- Report Details - View reporter, reported user, content, reason
- Actions - Mark as reviewed, dismiss, ban user, remove content
-- Get all pending reports
SELECT * FROM content_reports WHERE status = 'pending' ORDER BY created_at DESC;
-- Get reports for a specific user
SELECT * FROM reports WHERE reported_user_id = ? ORDER BY created_at DESC;
-- Get content reports with user details
SELECT cr.*, u1.username as reporter_name, u2.username as content_author
FROM content_reports cr
JOIN users u1 ON cr.reporter_id = u1.id
LEFT JOIN posts p ON cr.content_id = p.id AND cr.content_type = 'post'
LEFT JOIN users u2 ON p.user_id = u2.id
WHERE cr.status = 'pending';- Review Reports - Check pending reports daily
- Database Cleanup - Archive old reviewed reports monthly
- Analytics - Track report patterns to identify problematic users
- Policy Updates - Update report reasons as needed
- Indexes added on frequently queried columns (status, content_type, content_id)
- Foreign keys ensure referential integrity
- Soft cascading on user deletion maintains report history
For issues or enhancements:
- Check that all migrations have been run
- Verify URLROOT is defined in views
- Ensure user is logged in before testing
- Check browser console for JavaScript errors
- Verify database tables exist and have correct schema
v1.0.0 - Initial Release
- User profile reporting
- Content reporting (posts & chat messages)
- Project member reporting
- Unified modal interface
- AJAX submission
- Success/error notifications
- Duplicate prevention
- Self-reporting prevention
Built with pure PHP, HTML, CSS, and JavaScript - No frameworks required!