Add admin dashboard pages and restructure admin route
Introduces new admin dashboard pages for alerts, bans, invites, orders, settings, status, and vendors under app/dashboard/admin/. Moves the main admin page to the new dashboard structure and adds a shared admin layout. Updates sidebar configuration and adds supporting components and hooks for admin features.
This commit is contained in:
280
app/dashboard/admin/ban/page.tsx
Normal file
280
app/dashboard/admin/ban/page.tsx
Normal file
@@ -0,0 +1,280 @@
|
||||
import React from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
||||
import { UserX, Shield, Search, Ban, Unlock } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function AdminBanPage() {
|
||||
const [banData, setBanData] = useState({
|
||||
username: "",
|
||||
reason: "",
|
||||
duration: "",
|
||||
description: ""
|
||||
});
|
||||
|
||||
// Mock data for banned users
|
||||
const bannedUsers = [
|
||||
{
|
||||
id: "1",
|
||||
username: "spam_user",
|
||||
email: "spam@example.com",
|
||||
reason: "Spam",
|
||||
bannedBy: "admin1",
|
||||
banDate: "2024-01-15",
|
||||
duration: "Permanent",
|
||||
status: "active"
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
username: "fraud_vendor",
|
||||
email: "fraud@example.com",
|
||||
reason: "Fraud",
|
||||
bannedBy: "admin1",
|
||||
banDate: "2024-01-20",
|
||||
duration: "30 days",
|
||||
status: "active"
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
username: "policy_violator",
|
||||
email: "violator@example.com",
|
||||
reason: "Policy Violation",
|
||||
bannedBy: "admin1",
|
||||
banDate: "2024-01-25",
|
||||
duration: "7 days",
|
||||
status: "expired"
|
||||
}
|
||||
];
|
||||
|
||||
const handleBanUser = () => {
|
||||
// Handle ban user logic
|
||||
console.log("Banning user:", banData);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold tracking-tight">Ban Users</h1>
|
||||
<p className="text-sm text-muted-foreground mt-1">Manage user bans and suspensions</p>
|
||||
</div>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div className="grid gap-4 md:grid-cols-4">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Active Bans</CardTitle>
|
||||
<Shield className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">12</div>
|
||||
<p className="text-xs text-muted-foreground">Currently banned</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Permanent Bans</CardTitle>
|
||||
<UserX className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">3</div>
|
||||
<p className="text-xs text-muted-foreground">Permanent suspensions</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Temporary Bans</CardTitle>
|
||||
<Ban className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">9</div>
|
||||
<p className="text-xs text-muted-foreground">Time-limited bans</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Appeals Pending</CardTitle>
|
||||
<Unlock className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">2</div>
|
||||
<p className="text-xs text-muted-foreground">Awaiting review</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
{/* Ban User Form */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center">
|
||||
<UserX className="h-5 w-5 mr-2" />
|
||||
Ban User
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Enter user details and reason for banning
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="username">Username</Label>
|
||||
<Input
|
||||
id="username"
|
||||
placeholder="Enter username to ban"
|
||||
value={banData.username}
|
||||
onChange={(e) => setBanData({...banData, username: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reason">Reason</Label>
|
||||
<Select value={banData.reason} onValueChange={(value) => setBanData({...banData, reason: value})}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select ban reason" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="spam">Spam</SelectItem>
|
||||
<SelectItem value="fraud">Fraud</SelectItem>
|
||||
<SelectItem value="harassment">Harassment</SelectItem>
|
||||
<SelectItem value="policy_violation">Policy Violation</SelectItem>
|
||||
<SelectItem value="suspicious_activity">Suspicious Activity</SelectItem>
|
||||
<SelectItem value="other">Other</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="duration">Duration</Label>
|
||||
<Select value={banData.duration} onValueChange={(value) => setBanData({...banData, duration: value})}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select ban duration" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="1_day">1 Day</SelectItem>
|
||||
<SelectItem value="7_days">7 Days</SelectItem>
|
||||
<SelectItem value="30_days">30 Days</SelectItem>
|
||||
<SelectItem value="90_days">90 Days</SelectItem>
|
||||
<SelectItem value="permanent">Permanent</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="description">Additional Details</Label>
|
||||
<Textarea
|
||||
id="description"
|
||||
placeholder="Provide additional context for the ban..."
|
||||
value={banData.description}
|
||||
onChange={(e) => setBanData({...banData, description: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive" className="w-full">
|
||||
<Ban className="h-4 w-4 mr-2" />
|
||||
Ban User
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Confirm Ban</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to ban user "{banData.username}"? This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleBanUser}>
|
||||
Confirm Ban
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Search Banned Users */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Search Banned Users</CardTitle>
|
||||
<CardDescription>Look up existing bans and their status</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input placeholder="Search by username or email..." className="pl-8" />
|
||||
</div>
|
||||
<Button variant="outline" className="w-full">
|
||||
Search Bans
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Banned Users Table */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Recent Bans</CardTitle>
|
||||
<CardDescription>View and manage current and past bans</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>User</TableHead>
|
||||
<TableHead>Reason</TableHead>
|
||||
<TableHead>Duration</TableHead>
|
||||
<TableHead>Banned By</TableHead>
|
||||
<TableHead>Date</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead className="text-right">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{bannedUsers.map((user) => (
|
||||
<TableRow key={user.id}>
|
||||
<TableCell>
|
||||
<div>
|
||||
<div className="font-medium">{user.username}</div>
|
||||
<div className="text-sm text-muted-foreground">{user.email}</div>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{user.reason}</TableCell>
|
||||
<TableCell>{user.duration}</TableCell>
|
||||
<TableCell>{user.bannedBy}</TableCell>
|
||||
<TableCell>{user.banDate}</TableCell>
|
||||
<TableCell>
|
||||
<Badge
|
||||
variant={user.status === "active" ? "destructive" : "secondary"}
|
||||
>
|
||||
{user.status}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="flex items-center justify-end space-x-2">
|
||||
{user.status === "active" && (
|
||||
<Button variant="outline" size="sm">
|
||||
<Unlock className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
<Button variant="outline" size="sm">
|
||||
View Details
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user