style: clean up code with prettier and eslint
This commit is contained in:
1 parent
60278b9e71
commit
fb8e77bb68
378 files changed
+22407
-20689
No files matched your search
@@ -1,22 +1,12 @@
|
||||
'use client'
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Crown,
|
||||
EyeOff,
|
||||
Pencil,
|
||||
Plus,
|
||||
Shield,
|
||||
ShieldCheck,
|
||||
Trash2,
|
||||
UserCheck,
|
||||
Users,
|
||||
} from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { createRank, deleteRank } from '@/actions/permissions'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Crown, EyeOff, Pencil, Plus, Shield, ShieldCheck, Trash2, UserCheck, Users } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { createRank, deleteRank } from "@/actions/permissions";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -24,24 +14,24 @@ import {
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { useServerAction } from '@/hooks/use-server-action'
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useServerAction } from "@/hooks/use-server-action";
|
||||
|
||||
interface RankSummary {
|
||||
id: number
|
||||
rank_name: string
|
||||
badge: string
|
||||
level: number
|
||||
prefix: string
|
||||
prefix_color: string
|
||||
hidden_rank: string
|
||||
userCount: number
|
||||
id: number;
|
||||
rank_name: string;
|
||||
badge: string;
|
||||
level: number;
|
||||
prefix: string;
|
||||
prefix_color: string;
|
||||
hidden_rank: string;
|
||||
userCount: number;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
ranks: RankSummary[]
|
||||
ranks: RankSummary[];
|
||||
}
|
||||
|
||||
const RANK_ICONS: Record<number, React.ReactNode> = {
|
||||
@@ -49,51 +39,51 @@ const RANK_ICONS: Record<number, React.ReactNode> = {
|
||||
6: <ShieldCheck className="h-4 w-4 text-[var(--admin-error)]" />,
|
||||
5: <Shield className="h-4 w-4 text-[var(--admin-info)]" />,
|
||||
4: <UserCheck className="h-4 w-4 text-[var(--admin-success)]" />,
|
||||
}
|
||||
};
|
||||
|
||||
const RANK_COLORS: Record<number, string> = {
|
||||
7: 'border-[var(--admin-warning-border)] bg-[var(--admin-warning-subtle)]',
|
||||
6: 'border-[var(--admin-error-border)] bg-[var(--admin-error-subtle)]',
|
||||
5: 'border-[var(--admin-info-border)] bg-[var(--admin-info-subtle)]',
|
||||
4: 'border-[var(--admin-success-border)] bg-[var(--admin-success-subtle)]',
|
||||
}
|
||||
7: "border-[var(--admin-warning-border)] bg-[var(--admin-warning-subtle)]",
|
||||
6: "border-[var(--admin-error-border)] bg-[var(--admin-error-subtle)]",
|
||||
5: "border-[var(--admin-info-border)] bg-[var(--admin-info-subtle)]",
|
||||
4: "border-[var(--admin-success-border)] bg-[var(--admin-success-subtle)]",
|
||||
};
|
||||
|
||||
export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
const { run, isPending } = useServerAction()
|
||||
const [ranks, setRanks] = useState(initialRanks)
|
||||
const [deleteTarget, setDeleteTarget] = useState<RankSummary | null>(null)
|
||||
const { run, isPending } = useServerAction();
|
||||
const [ranks, setRanks] = useState(initialRanks);
|
||||
const [deleteTarget, setDeleteTarget] = useState<RankSummary | null>(null);
|
||||
|
||||
const [showCreate, setShowCreate] = useState(false)
|
||||
const [newRankName, setNewRankName] = useState('')
|
||||
const [newRankLevel, setNewRankLevel] = useState('')
|
||||
const [showCreate, setShowCreate] = useState(false);
|
||||
const [newRankName, setNewRankName] = useState("");
|
||||
const [newRankLevel, setNewRankLevel] = useState("");
|
||||
|
||||
const totalUsers = ranks.reduce((sum, r) => sum + r.userCount, 0)
|
||||
const totalUsers = ranks.reduce((sum, r) => sum + r.userCount, 0);
|
||||
|
||||
function handleCreate() {
|
||||
const level = parseInt(newRankLevel, 10)
|
||||
const level = parseInt(newRankLevel, 10);
|
||||
if (!newRankName.trim() || !level || level < 1) {
|
||||
toast.error('Name and a valid level are required')
|
||||
return
|
||||
toast.error("Name and a valid level are required");
|
||||
return;
|
||||
}
|
||||
run(() => createRank({ rank_name: newRankName.trim(), level }), {
|
||||
successMessage: 'Rank created',
|
||||
successMessage: "Rank created",
|
||||
onSuccess: () => {
|
||||
setShowCreate(false)
|
||||
setNewRankName('')
|
||||
setNewRankLevel('')
|
||||
setShowCreate(false);
|
||||
setNewRankName("");
|
||||
setNewRankLevel("");
|
||||
},
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete() {
|
||||
if (!deleteTarget) return
|
||||
if (!deleteTarget) return;
|
||||
run(() => deleteRank({ id: deleteTarget.id }), {
|
||||
successMessage: 'Rank deleted',
|
||||
successMessage: "Rank deleted",
|
||||
onSuccess: () => {
|
||||
setRanks((prev) => prev.filter((r) => r.id !== deleteTarget!.id))
|
||||
setDeleteTarget(null)
|
||||
setRanks((prev) => prev.filter((r) => r.id !== deleteTarget!.id));
|
||||
setDeleteTarget(null);
|
||||
},
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -119,14 +109,14 @@ export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
||||
{ranks.map((rank) => {
|
||||
const prefixColor = rank.prefix_color
|
||||
? rank.prefix_color.startsWith('#')
|
||||
? rank.prefix_color.startsWith("#")
|
||||
? rank.prefix_color
|
||||
: `#${rank.prefix_color}`
|
||||
: undefined
|
||||
: undefined;
|
||||
return (
|
||||
<div
|
||||
key={rank.id}
|
||||
className={`rounded-xl border p-4 flex flex-col gap-3 hover:shadow-lg transition-all ${RANK_COLORS[rank.id] || ''}`}
|
||||
className={`rounded-xl border p-4 flex flex-col gap-3 hover:shadow-lg transition-all ${RANK_COLORS[rank.id] || ""}`}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
@@ -135,7 +125,7 @@ export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
<span className="font-bold">{rank.rank_name || `Rank ${rank.id}`}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
{rank.hidden_rank === '1' && (
|
||||
{rank.hidden_rank === "1" && (
|
||||
<span title="Hidden rank">
|
||||
<EyeOff className="h-3.5 w-3.5 text-muted-foreground" />
|
||||
</span>
|
||||
@@ -187,15 +177,13 @@ export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
className="h-8 w-8 text-destructive hover:text-destructive shrink-0"
|
||||
disabled={rank.userCount > 0 || isPending}
|
||||
onClick={() => setDeleteTarget(rank)}
|
||||
title={
|
||||
rank.userCount > 0 ? `Cannot delete: ${rank.userCount} users` : 'Delete rank'
|
||||
}
|
||||
title={rank.userCount > 0 ? `Cannot delete: ${rank.userCount} users` : "Delete rank"}
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -236,7 +224,7 @@ export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleCreate} disabled={isPending}>
|
||||
{isPending ? 'Creating...' : 'Create'}
|
||||
{isPending ? "Creating..." : "Create"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
@@ -248,8 +236,8 @@ export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
<DialogHeader>
|
||||
<DialogTitle>Delete Rank #{deleteTarget?.id}?</DialogTitle>
|
||||
<DialogDescription>
|
||||
This will permanently delete "{deleteTarget?.rank_name}" and its CMS role.
|
||||
This cannot be undone.
|
||||
This will permanently delete "{deleteTarget?.rank_name}" and its CMS role. This cannot
|
||||
be undone.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<DialogFooter>
|
||||
@@ -257,11 +245,11 @@ export function PermissionsList({ ranks: initialRanks }: Props) {
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="destructive" onClick={handleDelete} disabled={isPending}>
|
||||
{isPending ? 'Deleting...' : 'Delete'}
|
||||
{isPending ? "Deleting..." : "Delete"}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user