Skip to content

Commit 66c73d0

Browse files
feat: add telegram groups search
1 parent 9265c18 commit 66c73d0

2 files changed

Lines changed: 139 additions & 1 deletion

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"use client"
2+
import { useQueryClient } from "@tanstack/react-query"
3+
import { ArrowLeft, Copy, Search, X } from "lucide-react"
4+
import Link from "next/link"
5+
import { useState } from "react"
6+
import { toast } from "sonner"
7+
import { Button } from "@/components/ui/button"
8+
import { Input } from "@/components/ui/input"
9+
import { Label } from "@/components/ui/label"
10+
import { useTRPC } from "@/lib/trpc/client"
11+
import type { ApiOutput } from "@/lib/trpc/types"
12+
13+
type Groups = ApiOutput["tg"]["groups"]["search"]["groups"]
14+
15+
export default function TgGroups() {
16+
const [query, setQuery] = useState("")
17+
18+
const trpc = useTRPC()
19+
const qc = useQueryClient()
20+
const queryOpts = trpc.tg.groups.search.queryOptions({ query, limit: 20 })
21+
22+
const [rows, setRows] = useState<Groups>([])
23+
async function search(e: React.FormEvent<HTMLFormElement>) {
24+
e.preventDefault()
25+
26+
const res = await qc.fetchQuery(queryOpts)
27+
setRows(res.groups)
28+
if (res.count === 0) toast.warning("No groups found with this query")
29+
else toast.info(`Found ${res.count} groups`)
30+
}
31+
32+
function reset() {
33+
setRows([])
34+
setQuery("")
35+
}
36+
37+
return (
38+
<div className="container p-8">
39+
<Link href="/dashboard/telegram" className="flex gap-1 items-center text-muted-foreground mb-2 hover:underline">
40+
<ArrowLeft size={16} /> Back
41+
</Link>
42+
<form onSubmit={search} className="pt-2 gap-y-4 flex flex-col justify-start items-start">
43+
<div className="flex gap-2 flex-col items-start justify-start">
44+
<Label htmlFor="email" className="text-base">
45+
Search
46+
</Label>
47+
<div className="flex gap-2 items-center justify-start">
48+
<Input
49+
id="group-query"
50+
type="text"
51+
placeholder="Group name"
52+
className="bg-card w-auto"
53+
required
54+
onChange={(e) => {
55+
setQuery(e.target.value)
56+
}}
57+
value={query}
58+
/>
59+
<Button type="submit" size="icon">
60+
<Search />
61+
</Button>
62+
{rows.length > 0 && (
63+
<Button variant="outline" onClick={reset}>
64+
<X />
65+
Reset
66+
</Button>
67+
)}
68+
</div>
69+
<span className="text-muted-foreground text-xs">Max results: 20</span>
70+
</div>
71+
</form>
72+
<div className="flex flex-col w-full items-start justify-start py-4">
73+
<div className="grid gap-4 items-center grid-cols-4 w-full border-b py-2">
74+
<p>telegram ID</p>
75+
<p>Title</p>
76+
<p>Tag</p>
77+
<p>Invite Link</p>
78+
</div>
79+
{rows.map((r) => (
80+
<GroupRow row={r} key={r.telegramId} />
81+
))}
82+
</div>
83+
</div>
84+
)
85+
}
86+
87+
function GroupRow({ row: r }: { row: Groups[number] }) {
88+
return (
89+
<div className="grid gap-4 items-center grid-cols-4 border-b py-2 w-full">
90+
<p>{r.telegramId}</p>
91+
<p>{r.title}</p>
92+
<p className={r.tag ? "" : "text-muted-foreground italic"}>{r.tag ? `@${r.tag}` : `<unset>`}</p>
93+
<div className="flex items-center justify-start gap-2">
94+
{r.link && (
95+
<a
96+
href={r.link}
97+
target="_blank"
98+
rel="noopener noreferrer"
99+
aria-label={`Link for group ${r.title}`}
100+
className="hover:underline"
101+
>
102+
{r.link}
103+
</a>
104+
)}
105+
<Button
106+
type="button"
107+
variant="outline"
108+
size="icon"
109+
className={!r.link ? "hidden" : ""}
110+
onClick={async () => {
111+
try {
112+
if (!r.link) return
113+
await navigator.clipboard.writeText(r.link)
114+
toast.success("Link copied to clipboard!")
115+
} catch (err) {
116+
toast.error("Cannot copy link to clipboard")
117+
console.error(err)
118+
}
119+
}}
120+
>
121+
<Copy />
122+
</Button>
123+
</div>
124+
</div>
125+
)
126+
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { UsersRound } from "lucide-react"
1+
import { Group, UsersRound } from "lucide-react"
22
import Link from "next/link"
33
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
44

@@ -18,6 +18,18 @@ export default function TelegramIndex() {
1818
</CardHeader>
1919
</Card>
2020
</Link>
21+
22+
<Link href="/dashboard/telegram/groups">
23+
<Card className="w-90 hover:bg-accent transition-colors">
24+
<CardHeader>
25+
<CardTitle className="flex gap-2 items-center">
26+
<Group size={20} />
27+
Groups
28+
</CardTitle>
29+
<CardDescription>Search groups and get links</CardDescription>
30+
</CardHeader>
31+
</Card>
32+
</Link>
2133
</div>
2234
</div>
2335
)

0 commit comments

Comments
 (0)