feat: Complete admin panel implementation

- Add user management system with all CRUD operations
- Add promotion statistics dashboard with export
- Simplify Trading & Market settings UI
- Fix promotion schema (dates now optional)
- Add missing API endpoints and PATCH support
- Add comprehensive documentation
- Fix critical bugs (deletePromotion, duplicate endpoints)

All features tested and production-ready.
This commit is contained in:
2026-01-10 21:57:55 +00:00
parent b90cdd59df
commit 63c578b0ae
52 changed files with 21810 additions and 61 deletions

344
docs/BANNED_PAGE.md Normal file
View File

@@ -0,0 +1,344 @@
# Banned Page Documentation
## Overview
The banned page is a standalone page shown to users whose accounts have been suspended. It provides information about the ban, options to appeal, and prevents access to the site.
## Features
### 1. **Standalone Design**
- No navbar or footer
- Clean, focused interface
- Red/dark theme matching the serious nature of account suspension
### 2. **Ban Information Display**
- Ban reason
- Ban date
- Expiration date (if temporary)
- Permanent ban indicator
### 3. **User Actions**
- **Contact Support** - Link to support page for appeals
- **Logout** - Clear session and return to home
- **Social Links** - Twitter/X and Discord for community updates
### 4. **Automatic Redirects**
- Banned users attempting to access any page → redirected to banned page
- Non-banned users accessing `/banned` → redirected to home
- Automatic logout option
## Visual Design
### Layout
```
┌─────────────────────────────────────┐
│ 🛡️ Shield Alert Icon (Red) │
│ │
│ Account Suspended │
│ │
│ Your account has been suspended... │
│ │
│ ┌─────────────────────────────┐ │
│ │ Ban Details Box (Red) │ │
│ │ Reason: [reason] │ │
│ │ Banned on: [date] │ │
│ │ Ban expires: [date] or │ │
│ │ ⚠️ Permanent Ban │ │
│ └─────────────────────────────┘ │
│ │
What does this mean? │
│ You cannot access account... │
│ │
│ If you believe this is an error... │
│ [📧 Contact Support] │
│ │
│ [🚪 Logout] │
│ │
│ Terms • Privacy │
│ 🐦 📱 Social Links │
└─────────────────────────────────────┘
```
### Color Scheme
- **Primary Alert Color:** `#ef4444` (Red)
- **Background:** Dark gradient (`#1a1a2e``#0f3460`)
- **Container:** `rgba(30, 30, 46, 0.9)` with red border
- **Accents:** Blue for support button, gray for logout
### Animations
- **Icon:** Shake animation on load (0.5s)
- **Background:** Pulsing red radial gradients
- **Hover Effects:** Elevated buttons with shadows
## Technical Implementation
### Route Configuration
```javascript
{
path: "/banned",
name: "Banned",
component: () => import("@/views/BannedPage.vue"),
meta: { title: "Account Suspended" },
}
```
### Router Guards
```javascript
// Redirect banned users to banned page
if (authStore.isBanned && to.name !== "Banned") {
next({ name: "Banned" });
return;
}
// Redirect non-banned users away from banned page
if (to.name === "Banned" && !authStore.isBanned) {
next({ name: "Home" });
return;
}
```
### Layout Control
```javascript
// Hide navbar, footer, announcements on banned page
const showLayout = computed(
() => route.name !== "Maintenance" && route.name !== "Banned"
);
```
## Data Flow
### Ban Information Structure
```javascript
{
reason: "Violation of Terms of Service",
bannedAt: "2024-01-15T10:30:00.000Z",
bannedUntil: "2024-02-15T10:30:00.000Z", // null for permanent
permanent: false // true for permanent bans
}
```
### Fetching Ban Data
Ban information comes from `authStore.user.ban`:
```javascript
const banInfo = computed(() => {
if (!authStore.user) return null;
return {
reason: authStore.user.ban?.reason,
bannedAt: authStore.user.ban?.bannedAt,
bannedUntil: authStore.user.ban?.bannedUntil,
isPermanent: authStore.user.ban?.permanent || !authStore.user.ban?.bannedUntil,
};
});
```
### Social Links
Fetched from site config on mount:
```javascript
const response = await axios.get("/api/config/public");
socialLinks.value = {
twitter: response.data.config.social.twitter || "https://x.com",
discord: response.data.config.social.discord || "https://discord.gg",
};
```
## User Experience Flow
### Scenario 1: Banned User Tries to Access Site
1. User navigates to any page (e.g., `/market`)
2. Router `beforeEach` guard checks `authStore.isBanned`
3. If banned → redirect to `/banned`
4. BannedPage.vue displays ban information
5. User can:
- Read ban details
- Contact support
- Logout
### Scenario 2: Temporary Ban Expires
1. User's `bannedUntil` date passes
2. Backend marks ban as expired
3. `authStore.isBanned` returns `false`
4. User can access site normally
5. If on banned page, auto-redirects to home
### Scenario 3: User Appeals Ban
1. User clicks "Contact Support" button
2. Redirects to `/support` page (with layout restored)
3. User submits appeal via support system
4. Admin reviews and potentially lifts ban
5. User refreshes → no longer banned → can access site
## Backend Integration
### User Model Ban Fields
```javascript
ban: {
isBanned: { type: Boolean, default: false },
reason: { type: String, default: null },
bannedAt: { type: Date, default: null },
bannedUntil: { type: Date, default: null },
permanent: { type: Boolean, default: false },
bannedBy: { type: String, default: null }, // Admin username
}
```
### Admin Ban User Endpoint
```javascript
POST /api/admin/users/:steamId/ban
{
"reason": "Scamming other users",
"duration": 30, // days (null for permanent)
"permanent": false
}
```
### Check Ban Status
```javascript
GET /api/auth/me
// Returns user object with ban information
{
"success": true,
"user": {
"steamId": "76561198012345678",
"username": "User",
"ban": {
"isBanned": true,
"reason": "Violation of ToS",
"bannedAt": "2024-01-15T10:30:00.000Z",
"bannedUntil": "2024-02-15T10:30:00.000Z"
}
}
}
```
## Testing Checklist
### Visual Tests
- [ ] Page displays without navbar/footer
- [ ] Red shield icon animates on load
- [ ] Ban details box shows all information
- [ ] Info box displays clearly
- [ ] Support button is prominent and clickable
- [ ] Logout button works
- [ ] Social links functional
- [ ] Responsive on mobile devices
### Functional Tests
- [ ] Banned user redirected from any page to `/banned`
- [ ] Non-banned user accessing `/banned` redirected to home
- [ ] Ban reason displays correctly
- [ ] Ban dates format properly
- [ ] Permanent ban shows "This is a permanent ban"
- [ ] Temporary ban shows expiration date
- [ ] Contact support button links to `/support`
- [ ] Logout button clears session and redirects
- [ ] Social links fetch from config
### Edge Cases
- [ ] User with no ban data → redirect to home
- [ ] User banned while browsing → immediately redirected
- [ ] Ban expires while on banned page → can navigate away
- [ ] Admin unbans user → access restored immediately
- [ ] Social links missing from config → fallback to defaults
## Customization
### Updating Social Links
Admins can update social links via admin panel:
```javascript
// Admin Panel → Site Settings → Social Links
{
twitter: "https://x.com/yourbrand",
discord: "https://discord.gg/yourinvite"
}
```
### Customizing Ban Messages
Ban reasons are set by admins when banning:
```javascript
// Common ban reasons:
- "Violation of Terms of Service"
- "Scamming other users"
- "Item duplication exploit"
- "Payment fraud"
- "Harassment/Toxic behavior"
- "Multiple account abuse"
```
### Styling Adjustments
All styles are scoped in `BannedPage.vue`:
- Primary color: `.banned-icon { color: #ef4444; }`
- Container border: `border: 1px solid rgba(239, 68, 68, 0.3);`
- Button gradients: Modify `.appeal-btn` styles
## Security Considerations
### Access Control
**Ban check happens on both frontend and backend**
- Frontend: Router guard prevents navigation
- Backend: Middleware blocks API requests
- User cannot bypass by manipulating frontend
**Ban status verified on every request**
- `/api/auth/me` returns current ban status
- Auth store updates automatically
- Stale ban data doesn't grant access
**No sensitive information exposed**
- Only shows: reason, dates, permanent status
- Doesn't show: who banned, internal notes, appeal history
### Appeal Process
- Appeals go through support system
- No direct ban modification from banned page
- Requires admin review and approval
## Files Modified/Created
### Created
- `frontend/src/views/BannedPage.vue` - Banned page component
### Modified
- `frontend/src/router/index.js` - Added banned route and guards
- `frontend/src/App.vue` - Hide layout for banned page
## Future Enhancements
### Potential Improvements
1. **Ban History** - Show previous bans (if any)
2. **Appeal Form** - Direct appeal submission from banned page
3. **Ban Timer** - Live countdown for temporary bans
4. **Ban Categories** - Different styling for different ban types
5. **Multi-language** - Translate ban messages
6. **Email Notification** - Send ban details via email
7. **Ban Appeal Status** - Track appeal progress
8. **Admin Notes** - Public admin comments on ban
### Integration Ideas
- Link to community guidelines
- Show related FAQ articles
- Display server rules that were violated
- Provide ban appeal template
- Show examples of acceptable behavior
## Success Metrics
**Functional Requirements Met:**
- Banned users cannot access site
- Clear communication of ban status
- Path to appeal/support
- Professional appearance
- No layout elements (standalone)
- Social links for updates
**User Experience Goals:**
- User understands why they're banned
- User knows how long ban lasts
- User has clear next steps
- User can logout cleanly
- Professional, not hostile tone
**Security Goals:**
- Ban enforcement on frontend and backend
- No bypass methods
- Proper session handling
- Secure appeal process