fix: ui fixes

This commit is contained in:
gosangam
2026-06-16 16:25:54 +05:30
parent 5342123fba
commit d3c043f6b0
4 changed files with 79 additions and 6 deletions
+5 -5
View File
@@ -173,10 +173,10 @@ export default function FeedbackPage() {
}
function StatusBadge({ f }: { f: AdminFeedback }) {
const label = f.replied_at
? "Replied"
: f.resolved_at
? "Resolved"
const label = f.resolved_at
? "Resolved"
: f.replied_at
? "Replied"
: f.acknowledged_at
? "Acknowledged"
: "Open";
@@ -240,7 +240,7 @@ function ReplyModal({
onChange={(e) => setMessage(e.target.value)}
rows={5}
maxLength={4000}
placeholder="Write your reply… (emailed to the submitter, marks this resolved)"
placeholder="Write your reply… (emailed to the submitter; use Resolve separately to close it)"
/>
</label>
<div className="flex justify-end gap-2">
+39 -1
View File
@@ -1,8 +1,10 @@
"use client";
import { useCallback, useState } from "react";
import { Mail } from "lucide-react";
import { toast } from "sonner";
import { api, AdminError, type AdminUser } from "@/lib/api";
import { GoogleIcon, FacebookIcon } from "@/components/ui/provider-icons";
import { usePagedList } from "@/lib/use-paged-list";
import { ListShell, EmptyRow } from "@/components/list-shell";
import { Table, THead, TR, TH, TD } from "@/components/ui/table";
@@ -74,6 +76,7 @@ export default function UsersPage() {
<TR>
<TH>User</TH>
<TH>Email</TH>
<TH>Auth</TH>
<TH>Posts</TH>
<TH>Joined</TH>
<TH className="text-right">Actions</TH>
@@ -81,7 +84,7 @@ export default function UsersPage() {
</THead>
<tbody>
{list.items.length === 0 && !list.loading ? (
<EmptyRow cols={5} label="No users found." />
<EmptyRow cols={6} label="No users found." />
) : (
list.items.map((u) => (
<TR key={u.id}>
@@ -106,6 +109,9 @@ export default function UsersPage() {
<TD>
{u.email ?? <span className="text-muted-foreground">—</span>}
</TD>
<TD>
<AuthIcons user={u} />
</TD>
<TD>{u.post_count}</TD>
<TD className="whitespace-nowrap">{fmtDate(u.created_at)}</TD>
<TD className="text-right">
@@ -122,6 +128,38 @@ export default function UsersPage() {
);
}
function AuthIcons({ user }: { user: AdminUser }) {
const hasGoogle = user.providers.includes("google");
const hasFacebook = user.providers.includes("facebook");
if (!user.has_password && !hasGoogle && !hasFacebook) {
return <span className="text-muted-foreground">—</span>;
}
return (
<div className="flex items-center gap-2">
{user.has_password ? (
// Tooltip shows the email on hover; clicking copies it to the clipboard.
<button
type="button"
title={user.email ? `Click to copy ${user.email}` : "Email & password"}
onClick={() => {
if (!user.email) return;
// No await before the write — keeps the click's user activation.
navigator.clipboard.writeText(user.email).then(
() => toast.success("Email copied"),
() => toast.error("Could not copy"),
);
}}
className="inline-flex text-muted-foreground outline-none hover:text-foreground focus-visible:text-foreground"
>
<Mail className="size-4" />
</button>
) : null}
{hasGoogle ? <GoogleIcon className="size-4" /> : null}
{hasFacebook ? <FacebookIcon className="size-4" /> : null}
</div>
);
}
function NotifyModal({
user,
onClose,