Skip to content

Commit b7b9c78

Browse files
feat: remove telegram role
1 parent d3f52cc commit b7b9c78

2 files changed

Lines changed: 141 additions & 4 deletions

File tree

src/app/dashboard/(active)/telegram/users/page.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { stripChatId } from "@/lib/utils/telegram"
1515
import { AddRole } from "./add-role"
1616
import { DeleteGroupAdmin } from "./delete-group-admin"
1717
import { NewGroupAdmin } from "./new-group-admin"
18+
import { RemoveRole } from "./remove-role"
1819

1920
type User = ApiOutput["tg"]["users"]["getByUsername"]["user"]
2021

@@ -85,7 +86,7 @@ export default function TgUsers() {
8586

8687
{user && (
8788
<>
88-
<UserInfoCard user={user} roles={userData?.roles} />
89+
<UserInfoCard user={user} roles={userData?.roles ?? []} />
8990
<div className="pt-6 flex gap-4 items-center">
9091
<p>Admin in groups:</p>
9192
<NewGroupAdmin user={user} alreadyIn={userData?.groupAdmin.map((g) => g?.group.id ?? 0) ?? []} />
@@ -113,8 +114,7 @@ export default function TgUsers() {
113114
type UserRoles = ApiOutput["tg"]["permissions"]["getRoles"]["roles"]
114115
function UserInfoCard({ user, roles }: { user: NonNullable<User>; roles: UserRoles }) {
115116
return (
116-
<Card>
117-
{" "}
117+
<Card className="w-fit min-w-120">
118118
<CardHeader>
119119
<CardTitle>User ID: {user.id}</CardTitle>
120120
</CardHeader>
@@ -132,8 +132,9 @@ function UserInfoCard({ user, roles }: { user: NonNullable<User>; roles: UserRol
132132
{roles ? roles.map((r) => <Badge key={r}>{r}</Badge>) : "N/A"}
133133
</div>
134134
</CardContent>
135-
<CardFooter>
135+
<CardFooter className="gap-2">
136136
<AddRole alreadyRoles={roles ?? []} user={user} />
137+
<RemoveRole alreadyRoles={roles ?? []} user={user} />
137138
</CardFooter>
138139
</Card>
139140
)
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
"use client"
2+
import { USER_ROLE } from "@polinetwork/backend"
3+
import { useMutation, useQueryClient } from "@tanstack/react-query"
4+
import { Minus, Plus } from "lucide-react"
5+
import { useRouter } from "next/navigation"
6+
import { useState } from "react"
7+
import { toast } from "sonner"
8+
import { Badge } from "@/components/ui/badge"
9+
import { Button } from "@/components/ui/button"
10+
import {
11+
Dialog,
12+
DialogClose,
13+
DialogContent,
14+
DialogDescription,
15+
DialogFooter,
16+
DialogHeader,
17+
DialogTitle,
18+
DialogTrigger,
19+
} from "@/components/ui/dialog"
20+
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
21+
import { useSession } from "@/lib/auth"
22+
import { useTRPC } from "@/lib/trpc/client"
23+
import type { ApiOutput } from "@/lib/trpc/types"
24+
25+
type User = ApiOutput["tg"]["users"]["getByUsername"]["user"]
26+
type Roles = NonNullable<ApiOutput["tg"]["permissions"]["getRoles"]["roles"]>
27+
28+
const ARRAY_USER_ROLES = [
29+
USER_ROLE.ADMIN,
30+
USER_ROLE.HR,
31+
USER_ROLE.OWNER,
32+
USER_ROLE.CREATOR,
33+
USER_ROLE.DIRETTIVO,
34+
USER_ROLE.PRESIDENT,
35+
] as const
36+
37+
export function RemoveRole({ user, alreadyRoles }: { user: User; alreadyRoles: Roles }) {
38+
const sesh = useSession()
39+
const removerId = sesh.data?.user.telegramId
40+
41+
const userRoles = ARRAY_USER_ROLES.filter((r) => alreadyRoles.includes(r)).map((g) => ({
42+
value: g,
43+
label: `${g.slice(0, 1).toUpperCase()}${g.slice(1)}`,
44+
}))
45+
46+
const trpc = useTRPC()
47+
const qc = useQueryClient()
48+
const router = useRouter()
49+
50+
const [open, setOpen] = useState(false)
51+
const [selectedRole, setSelectedRole] = useState<Roles[number] | null>(null)
52+
53+
const submitMutation = useMutation(trpc.tg.permissions.removeRole.mutationOptions())
54+
55+
async function submit() {
56+
if (!removerId) return toast.warning("Invalid session, try reloading the page")
57+
if (!selectedRole) return toast.warning("No group selected, cannot proceed")
58+
if (!user) return toast.warning("Invalid user, try restarting the dialog")
59+
60+
try {
61+
await submitMutation.mutateAsync({ removerId, userId: user.id, role: selectedRole })
62+
toast.info(`Role removed`)
63+
handleOpenChange(false)
64+
router.refresh()
65+
} catch (err) {
66+
console.error(err)
67+
handleOpenChange(false)
68+
toast.error("There was an error, check logs")
69+
}
70+
}
71+
72+
function handleOpenChange(v: boolean) {
73+
setOpen(v)
74+
if (v === false) {
75+
// closing
76+
qc.invalidateQueries(trpc.tg.permissions.getRoles.queryOptions({ userId: user?.id ?? 0 }))
77+
setSelectedRole(null)
78+
}
79+
}
80+
81+
return (
82+
<Dialog open={open} onOpenChange={handleOpenChange}>
83+
<DialogTrigger
84+
render={
85+
<Button variant="destructive">
86+
<Minus size={20} /> Remove Role
87+
</Button>
88+
}
89+
/>
90+
<DialogContent className="sm:max-w-xl">
91+
<DialogHeader>
92+
<DialogTitle>Remove Role</DialogTitle>
93+
<DialogDescription>Remove a role from the telegram user</DialogDescription>
94+
</DialogHeader>
95+
{user && (
96+
<p>
97+
Target: {user.firstName} {user.username && `@${user.username}`} [{user.id}]
98+
</p>
99+
)}
100+
<div className="flex items-center justify-start gap-2">
101+
<span>User roles: </span>
102+
{alreadyRoles.map((r) => (
103+
<Badge key={r}>{r}</Badge>
104+
))}
105+
</div>
106+
107+
<Select
108+
items={userRoles}
109+
value={selectedRole}
110+
onValueChange={(v) => setSelectedRole(v)}
111+
disabled={userRoles.length === 0}
112+
>
113+
<SelectTrigger className="w-full max-w-48">
114+
<SelectValue />
115+
</SelectTrigger>
116+
<SelectContent>
117+
<SelectGroup>
118+
{userRoles.map((item) => (
119+
<SelectItem key={item.value} value={item.value}>
120+
{item.label}
121+
</SelectItem>
122+
))}
123+
</SelectGroup>
124+
</SelectContent>
125+
</Select>
126+
127+
<DialogFooter>
128+
<DialogClose render={<Button variant="outline">Cancel</Button>} />
129+
<Button onClick={submit} disabled={!selectedRole} variant="destructive">
130+
Confirm
131+
</Button>
132+
</DialogFooter>
133+
</DialogContent>
134+
</Dialog>
135+
)
136+
}

0 commit comments

Comments
 (0)