diff --git a/api/routes/admin.js b/api/routes/admin.js index 59ea907..82a7c46 100644 --- a/api/routes/admin.js +++ b/api/routes/admin.js @@ -24,6 +24,35 @@ router.get('/users', async (req, res) => { } }); +// Get user details (QR codes, scans) +router.get('/users/:id/details', async (req, res) => { + const { id } = req.params; + try { + // Fetch user info + const userRes = await pgPool.query('SELECT id, email, role, created_at FROM users WHERE id = $1', [id]); + if (userRes.rows.length === 0) { + return res.status(404).json({ error: 'User not found' }); + } + + // Fetch QR codes and scan counts + const qrRes = await pgPool.query(` + SELECT q.id, q.type, q.data_type, q.destination_url, q.short_url_id, q.created_at, q.design_data->>'name' as name, + (SELECT COUNT(*) FROM qr_scans s WHERE s.qr_code_id = q.id) as scan_count + FROM qr_codes q + WHERE q.user_id = $1 + ORDER BY q.created_at DESC + `, [id]); + + res.json({ + user: userRes.rows[0], + qrCodes: qrRes.rows + }); + } catch (err) { + console.error(err); + res.status(500).json({ error: 'Server Error fetching user details' }); + } +}); + // Update a user's tier router.put('/users/:id/tier', async (req, res) => { const { id } = req.params; diff --git a/client/src/app/admin/page.tsx b/client/src/app/admin/page.tsx index 0dc9e3c..9996282 100644 --- a/client/src/app/admin/page.tsx +++ b/client/src/app/admin/page.tsx @@ -1,6 +1,7 @@ 'use client'; import React, { useEffect, useState } from 'react'; import api from '@/lib/api'; +import UserDetailsModal from '@/components/UserDetailsModal'; interface User { id: string; @@ -12,6 +13,7 @@ interface User { export default function AdminPage() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); + const [selectedUser, setSelectedUser] = useState(null); const fetchUsers = async () => { try { @@ -63,6 +65,7 @@ export default function AdminPage() { Account / Email Status / Tier Joined + Details Admin Action @@ -89,6 +92,14 @@ export default function AdminPage() { {new Date(user.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })} + + +