Skip to content

Commit 14c0cda

Browse files
feat(telegram): implement leave chat
1 parent 5f4710a commit 14c0cda

6 files changed

Lines changed: 113 additions & 13 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"@base-ui/react": "^1.3.0",
1717
"@better-auth/passkey": "^1.5.5",
1818
"@hookform/resolvers": "^3.9.1",
19-
"@polinetwork/backend": "^0.15.16",
19+
"@polinetwork/backend": "^0.15.17",
2020
"@radix-ui/react-dialog": "^1.1.15",
2121
"@t3-oss/env-nextjs": "^0.13.10",
2222
"@tanstack/react-table": "^8.21.2",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/dashboard/(active)/telegram/groups/group-row.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Badge } from "@/components/ui/badge"
66
import { Button } from "@/components/ui/button"
77
import { setGroupHide } from "@/server/actions/groups"
88
import type { TgGroup } from "@/server/trpc/types"
9+
import { LeaveChat } from "./leave-chat"
910

1011
export function GroupRow({ row: r }: { row: TgGroup }) {
1112
const router = useRouter()
@@ -21,7 +22,7 @@ export function GroupRow({ row: r }: { row: TgGroup }) {
2122
}
2223

2324
return (
24-
<div className="grid gap-4 items-center grid-cols-5 border-b py-2 w-full">
25+
<div className="grid gap-4 items-center grid-cols-[1fr_2fr_1fr_3fr_1fr] border-b py-2 w-full">
2526
<p>{r.telegramId}</p>
2627
<p>{r.title}</p>
2728
<p className={r.tag ? "" : "text-muted-foreground italic"}>{r.tag ? `@${r.tag}` : `<unset>`}</p>
@@ -57,10 +58,18 @@ export function GroupRow({ row: r }: { row: TgGroup }) {
5758
</Button>
5859
</div>
5960
<div className="flex items-center justify-start gap-2">
60-
<p>{r.hide ? <Badge className="bg-yellow-800">HIDDEN</Badge> : <Badge variant="secondary">Visibile</Badge>}</p>
61-
<Button type="button" variant="outline" size="icon-sm" onClick={toggleHide}>
62-
<Pen />
63-
</Button>
61+
<p>
62+
{r.hide ? (
63+
<Badge onClick={toggleHide} className="bg-yellow-800 hover:bg-yellow-600 cursor-pointer">
64+
HIDDEN
65+
</Badge>
66+
) : (
67+
<Badge onClick={toggleHide} variant="secondary" className="hover:bg-slate-600 cursor-pointer">
68+
Visibile
69+
</Badge>
70+
)}
71+
</p>
72+
<LeaveChat chatId={r.telegramId} />
6473
</div>
6574
</div>
6675
)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"use client"
2+
3+
import { OctagonX, Trash2 } from "lucide-react"
4+
import { useRouter } from "next/navigation"
5+
import { useState } from "react"
6+
import { toast } from "sonner"
7+
import { Spinner } from "@/components/spinner"
8+
import {
9+
AlertDialog,
10+
AlertDialogAction,
11+
AlertDialogCancel,
12+
AlertDialogContent,
13+
AlertDialogDescription,
14+
AlertDialogFooter,
15+
AlertDialogHeader,
16+
AlertDialogMedia,
17+
AlertDialogTitle,
18+
AlertDialogTrigger,
19+
} from "@/components/ui/alert-dialog"
20+
import { Button } from "@/components/ui/button"
21+
import { leaveChat } from "@/server/actions/groups"
22+
23+
export function LeaveChat({ chatId }: { chatId: number }) {
24+
const router = useRouter()
25+
const [open, setOpen] = useState(false)
26+
const [pending, setPending] = useState(false)
27+
28+
async function submit() {
29+
setPending(true)
30+
try {
31+
const { error } = await leaveChat(chatId)
32+
33+
if (error === "UNAUTHORIZED") toast.error("You don't have enough permission")
34+
else if (error === "BOT_ERROR") {
35+
toast.error("Cannot leave the group")
36+
} else if (error === "NOT_FOUND") {
37+
toast.warning("Group left BUT not found in db")
38+
} else {
39+
toast.success("Group left and deleted")
40+
router.refresh()
41+
}
42+
} catch (err) {
43+
toast.error("There was an error")
44+
console.error(err)
45+
} finally {
46+
setPending(false)
47+
handleOpenChange(false)
48+
}
49+
}
50+
51+
function handleOpenChange(v: boolean) {
52+
setOpen(v)
53+
}
54+
55+
return (
56+
<AlertDialog open={open} onOpenChange={handleOpenChange}>
57+
<AlertDialogTrigger
58+
render={
59+
<Button variant="destructive">
60+
<Trash2 />
61+
Leave
62+
</Button>
63+
}
64+
></AlertDialogTrigger>
65+
<AlertDialogContent size="sm">
66+
<AlertDialogHeader>
67+
<AlertDialogMedia className="bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive">
68+
<OctagonX />
69+
</AlertDialogMedia>
70+
<AlertDialogTitle>Leave chat</AlertDialogTitle>
71+
<AlertDialogDescription>
72+
This will make the bot leave the chat and the backend delete the group from the table.
73+
</AlertDialogDescription>
74+
</AlertDialogHeader>
75+
<AlertDialogFooter>
76+
<AlertDialogCancel disabled={pending}>Cancel</AlertDialogCancel>
77+
<AlertDialogAction disabled={pending} onClick={submit} variant="destructive">
78+
{pending ? <Spinner /> : "Confirm"}
79+
</AlertDialogAction>
80+
</AlertDialogFooter>
81+
</AlertDialogContent>
82+
</AlertDialog>
83+
)
84+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ export default async function TgGroups({ searchParams }: { searchParams: Promise
2323
Count: <span className="text-foreground">{rows.length}</span>
2424
</p>
2525
<div className="flex flex-col w-full items-start justify-start py-4">
26-
<div className="grid gap-4 items-center grid-cols-5 w-full border-b py-2">
26+
<div className="grid gap-4 items-center grid-cols-[1fr_2fr_1fr_3fr_1fr] w-full border-b py-2">
2727
<p>telegram ID</p>
2828
<p>Title</p>
2929
<p>Tag</p>
3030
<p>Invite Link</p>
31-
<p>Hide</p>
31+
<p>Actions</p>
3232
</div>
3333
{sorted.map((r) => (
3434
<GroupRow row={r} key={r.telegramId} />

src/server/actions/groups.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ export async function setGroupHide(groupId: number, hide: boolean) {
1313

1414
return trpc.tg.groups.setHide.mutate({ telegramId: groupId, hide })
1515
}
16+
17+
export async function leaveChat(chatId: number) {
18+
const { allowed, telegramId } = await requireRole(["owner", "direttivo", "president"])
19+
if (!allowed) return { error: "UNAUTHORIZED" }
20+
21+
return trpc.tg.groups.leaveChat.mutate({ chatId, performerId: telegramId })
22+
}

0 commit comments

Comments
 (0)