Files
tt-booking/lib/activity-logger.ts
mikicvi 40c56770a2 feat: implement admin blocks management feature
- Added AdminBlocksManagement component for managing court blocks.
- Implemented functionality to create, edit, and delete blocks.
- Integrated fetching of courts and blocks from the API.
- Added validation for block creation and editing forms.
- Enhanced UI with responsive design for mobile and desktop views.
- Created database migration for court_blocks table and updated users table with theme_preference.
2025-12-29 17:04:16 +00:00

108 lines
2.6 KiB
TypeScript

import { db } from '@/lib/db';
import { activityLogs } from '@/lib/db/schema';
import { NextRequest } from 'next/server';
export interface ActivityLogData {
userId?: string | null;
action: string;
entityType: string;
entityId?: string;
details?: any;
request?: NextRequest;
}
export async function logActivity({ userId, action, entityType, entityId, details, request }: ActivityLogData) {
try {
// Extract IP and User Agent from request if provided
let ipAddress: string | null = null;
let userAgent: string | null = null;
if (request) {
// Try to get real IP address
ipAddress =
request.headers.get('x-forwarded-for')?.split(',')[0] ||
request.headers.get('x-real-ip') ||
request.headers.get('cf-connecting-ip') ||
'127.0.0.1';
userAgent = request.headers.get('user-agent');
}
await db.insert(activityLogs).values({
id: crypto.randomUUID(),
userId,
action,
entityType,
entityId,
details: details ? JSON.stringify(details) : null,
ipAddress,
userAgent,
createdAt: new Date(),
});
console.log(
`Activity logged: ${action} on ${entityType}${entityId ? ` (${entityId})` : ''} by user ${
userId || 'anonymous'
}`
);
} catch (error) {
console.error('Failed to log activity:', error);
// Don't throw error to avoid breaking the main request
}
}
// Predefined action types for consistency
export const ACTIONS = {
// User actions
USER_LOGIN: 'login',
USER_LOGOUT: 'logout',
USER_REGISTER: 'register',
USER_CREATE: 'create_user',
USER_UPDATE: 'update_user',
USER_DELETE: 'delete_user',
// Booking actions
BOOKING_CREATE: 'create_booking',
BOOKING_UPDATE: 'update_booking',
BOOKING_CANCEL: 'cancel_booking',
BOOKING_DELETE: 'delete_booking',
// Court actions
COURT_CREATE: 'create_court',
COURT_UPDATE: 'update_court',
COURT_DELETE: 'delete_court',
// Announcement actions
ANNOUNCEMENT_CREATE: 'create_announcement',
ANNOUNCEMENT_UPDATE: 'update_announcement',
ANNOUNCEMENT_DELETE: 'delete_announcement',
// Settings actions
SETTINGS_UPDATE: 'update_settings',
// Time slot actions
TIME_SLOT_CREATE: 'create_time_slot',
TIME_SLOT_UPDATE: 'update_time_slot',
TIME_SLOT_DELETE: 'delete_time_slot',
// Court block actions
BLOCK_CREATE: 'create_block',
BLOCK_UPDATE: 'update_block',
BLOCK_DELETE: 'delete_block',
// System actions
SYSTEM_START: 'system_start',
SYSTEM_ERROR: 'system_error',
} as const;
export const ENTITY_TYPES = {
USER: 'user',
BOOKING: 'booking',
COURT: 'court',
ANNOUNCEMENT: 'announcement',
SETTINGS: 'settings',
TIME_SLOT: 'time_slot',
COURT_BLOCK: 'court_block',
SYSTEM: 'system',
} as const;