refactor: update notifications settings UI for improved layout and accessibility

- Removed unused imports and components to streamline the code.
- Enhanced the notifications section layout with improved spacing and styling.
- Updated the display of notification channels to use a more accessible design.
- Added loading and empty state indicators for better user experience.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-11-18 16:29:14 +08:00
parent 36193abdc0
commit fdd7d5adf8
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
1 changed files with 77 additions and 59 deletions

View File

@ -1,15 +1,6 @@
import { Button } from "@follow/components/ui/button/index.js"
import { Divider } from "@follow/components/ui/divider/index.js"
import { LoadingCircle } from "@follow/components/ui/loading/index.jsx"
import { ScrollArea } from "@follow/components/ui/scroll-area/index.js"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@follow/components/ui/table/index.jsx"
import {
Tooltip,
TooltipContent,
@ -43,55 +34,82 @@ export const SettingNotifications = () => {
}, [])
return (
<section className="mt-4">
<div className="mb-4 space-y-2 text-sm">
<p>
<Trans
ns="settings"
i18nKey="notifications.info"
components={{
ActionsLink: (
<Link
className="underline"
to="/action"
onClick={() => {
dismiss()
}}
/>
),
}}
/>
</p>
</div>
<Divider className="mb-6 mt-8" />
<div className="flex flex-1 flex-col">
{isLoading && <LoadingCircle size="large" className="center absolute inset-0" />}
<section className="mt-4 space-y-6">
{/* Info Section */}
<ScrollArea.ScrollArea viewportClassName="max-h-[380px]">
<div className="overflow-auto">
<Table className="mt-4">
<TableHeader>
<TableRow className="[&_*]:!font-semibold">
<TableHead size="sm">{t.settings("notifications.channel")}</TableHead>
<TableHead size="sm">{t.settings("notifications.token")}</TableHead>
<TableHead size="sm" className="center">
{t.common("words.actions")}
</TableHead>
</TableRow>
</TableHeader>
<TableBody className="border-t-[12px] border-transparent [&_td]:!px-3">
<p className="text-sm leading-relaxed text-text-secondary">
<Trans
ns="settings"
i18nKey="notifications.info"
components={{
ActionsLink: (
<Link
className="font-medium text-accent underline-offset-2 hover:text-accent/80 hover:underline"
to="/action"
onClick={() => {
dismiss()
}}
/>
),
}}
/>
</p>
{/* Channels Section */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<h3 className="text-sm font-semibold text-text">{t.settings("notifications.channel")}</h3>
<span className="text-xs text-text-tertiary">
<span>{data?.data?.length || 0}</span> <span>{t.common("words.items")}</span>
</span>
</div>
<div className="relative min-h-[200px]">
{isLoading && (
<div className="absolute inset-0 flex items-center justify-center">
<LoadingCircle size="large" />
</div>
)}
{!isLoading && (!data?.data || data.data.length === 0) ? (
<div className="flex flex-col items-center justify-center rounded-xl border border-dashed border-border bg-material-medium py-12">
<i className="i-mgc-notification-cute-re mb-3 text-4xl text-text-quaternary" />
<p className="text-sm text-text-tertiary">No notification channels</p>
</div>
) : (
<ScrollArea.ScrollArea viewportClassName="max-h-[400px]">
<div className="space-y-2">
{data?.data?.map((row) => (
<TableRow key={row.channel} className="h-8">
<TableCell size="sm">{row.channel}</TableCell>
<TableCell size="sm" className="truncate">
{row.token.slice(0, 6)}...{row.token.slice(-6)}
{row.token === token && ` ${t.settings("notifications.current")}`}
</TableCell>
<TableCell size="sm" className="center">
<div
key={row.channel}
className="group relative flex items-center gap-4 rounded-lg border border-border bg-background p-4 transition-all hover:border-border hover:bg-fill-secondary/30"
>
{/* Channel Info */}
<div className="flex-1 space-y-1">
<div className="flex items-center gap-2">
<span className="font-medium text-text">{row.channel}</span>
{row.token === token && (
<span className="inline-flex items-center gap-1 rounded-full bg-accent/10 px-2 py-0.5 text-xs font-medium text-accent">
<i className="i-mgc-check-cute-re text-[10px]" />
{t.settings("notifications.current")}
</span>
)}
</div>
<div className="flex items-center gap-2">
<code className="rounded bg-fill px-2 py-0.5 font-mono text-xs text-text-secondary">
{row.token.slice(0, 8)}...{row.token.slice(-8)}
</code>
</div>
</div>
{/* Actions */}
<div className="flex items-center gap-2">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="sm"
buttonClassName="size-8 p-0"
onClick={() =>
testMessaging.mutate(
{ channel: row.channel },
@ -103,20 +121,20 @@ export const SettingNotifications = () => {
)
}
>
<i className="i-mgc-finger-press-cute-re" />
<i className="i-mgc-finger-press-cute-re text-base" />
</Button>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>{t.settings("notifications.test")}</TooltipContent>
</TooltipPortal>
</Tooltip>
</TableCell>
</TableRow>
</div>
</div>
))}
</TableBody>
</Table>
</div>
</ScrollArea.ScrollArea>
</div>
</ScrollArea.ScrollArea>
)}
</div>
</div>
</section>
)