Skip to content

Commit 56b12c6

Browse files
committed
Dashboard: export the date in CSV as ISO string in wallets/users table, UI tweaks (#7802)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR enhances the `AdvancedSearchInput` component by adding a clear button, improving the layout, and integrating a loading spinner. It also updates the `InAppWalletUsersPageContent` to include a tooltip for user identifiers and modifies the display of created dates. ### Detailed summary - Added `XIcon` to `AdvancedSearchInput` for a clear button. - Integrated `Spinner` for loading state in `AdvancedSearchInput`. - Improved layout with responsive design adjustments. - Added `ToolTipLabel` for user identifier display in `InAppWalletUsersPageContent`. - Changed date format to ISO in `InAppWalletUsersPageContent`. - Updated button styles for better UI consistency. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an inline clear button ("X" icon) to the search input, allowing users to clear queries directly. * User identifiers now feature a copy-to-clipboard button with truncation and tooltip support. * Wallet creation dates now display detailed timestamps in a tooltip on hover. * **Improvements** * Enhanced responsive layout for search input and controls, optimizing usability across devices. * Updated button styles and input appearance for a more cohesive look. * CSV export now uses ISO date format for wallet creation dates. * Improved font size and styling for wallet labels and download button. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent abbdb0f commit 56b12c6

File tree

2 files changed

+68
-44
lines changed

2 files changed

+68
-44
lines changed
Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
"use client";
22

3-
import { SearchIcon } from "lucide-react";
3+
import { SearchIcon, XIcon } from "lucide-react";
44
import { useState } from "react";
55
import { Button } from "@/components/ui/button";
66
import { Input } from "@/components/ui/input";
7+
import { Spinner } from "@/components/ui/Spinner/Spinner";
78
import {
89
Select,
910
SelectContent,
1011
SelectItem,
1112
SelectTrigger,
1213
SelectValue,
1314
} from "@/components/ui/select";
14-
1515
import type { SearchType } from "./types";
1616

1717
export function AdvancedSearchInput(props: {
@@ -41,56 +41,57 @@ export function AdvancedSearchInput(props: {
4141
};
4242

4343
return (
44-
<div className="flex flex-col gap-2">
45-
<div className="flex gap-2">
46-
<Select
47-
value={searchType}
48-
onValueChange={(value) => setSearchType(value as SearchType)}
49-
>
50-
<SelectTrigger className="w-[140px] bg-card">
51-
<SelectValue />
52-
</SelectTrigger>
53-
<SelectContent>
54-
<SelectItem value="email">Email</SelectItem>
55-
<SelectItem value="phone">Phone</SelectItem>
56-
<SelectItem value="id">ID</SelectItem>
57-
<SelectItem value="address">Address</SelectItem>
58-
<SelectItem value="externalWallet">External Wallet</SelectItem>
59-
</SelectContent>
60-
</Select>
44+
<div className="flex flex-col md:flex-row gap-3">
45+
<Select
46+
value={searchType}
47+
onValueChange={(value) => setSearchType(value as SearchType)}
48+
>
49+
<SelectTrigger className="w-[140px] bg-card">
50+
<SelectValue />
51+
</SelectTrigger>
52+
<SelectContent>
53+
<SelectItem value="email">Email</SelectItem>
54+
<SelectItem value="phone">Phone</SelectItem>
55+
<SelectItem value="id">ID</SelectItem>
56+
<SelectItem value="address">Address</SelectItem>
57+
<SelectItem value="externalWallet">External Wallet</SelectItem>
58+
</SelectContent>
59+
</Select>
6160

61+
<div className="flex flex-1">
6262
<div className="relative flex-1">
6363
<Input
64-
className="bg-card pl-9"
64+
className="bg-card pl-9 border-r-0 rounded-r-none"
6565
placeholder={`Search by ${searchType}...`}
6666
value={query}
6767
onChange={(e) => setQuery(e.target.value)}
6868
onKeyDown={handleKeyDown}
6969
/>
7070
<SearchIcon className="-translate-y-1/2 absolute top-1/2 left-3 size-4 text-muted-foreground" />
71+
72+
{props.hasResults && (
73+
<div className="absolute top-1/2 -translate-y-1/2 right-2 ">
74+
<Button
75+
variant="ghost"
76+
onClick={handleClear}
77+
className="p-1 h-auto"
78+
>
79+
<XIcon className="size-4 text-muted-foreground" />
80+
</Button>
81+
</div>
82+
)}
7183
</div>
7284

7385
<Button
7486
onClick={handleSearch}
87+
variant="outline"
7588
disabled={!query.trim() || props.isLoading}
76-
size="sm"
89+
className="rounded-l-none gap-2 bg-card disabled:opacity-100"
7790
>
78-
{props.isLoading ? "Searching..." : "Search"}
91+
{props.isLoading && <Spinner className="size-4" />}
92+
Search
7993
</Button>
8094
</div>
81-
82-
{props.hasResults && (
83-
<div className="flex justify-center">
84-
<Button
85-
variant="outline"
86-
size="sm"
87-
onClick={handleClear}
88-
className="gap-2"
89-
>
90-
Clear Search & Return to List
91-
</Button>
92-
</div>
93-
)}
9495
</div>
9596
);
9697
}

apps/dashboard/src/@/components/in-app-wallet-users-content/in-app-wallet-users-content.tsx

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { WalletAddress } from "@/components/blocks/wallet-address";
1212
import { Button } from "@/components/ui/button";
1313
import { Spinner } from "@/components/ui/Spinner/Spinner";
1414
import {
15+
ToolTipLabel,
1516
Tooltip,
1617
TooltipContent,
1718
TooltipProvider,
@@ -21,6 +22,7 @@ import {
2122
useAllEmbeddedWallets,
2223
useEmbeddedWallets,
2324
} from "@/hooks/useEmbeddedWallets";
25+
import { CopyTextButton } from "../ui/CopyTextButton";
2426
import { AdvancedSearchInput } from "./AdvancedSearchInput";
2527
import { SearchResults } from "./SearchResults";
2628
import { searchUsers } from "./searchUsers";
@@ -57,7 +59,24 @@ export function InAppWalletUsersPageContent(
5759
columnHelper.accessor("linkedAccounts", {
5860
cell: (cell) => {
5961
const identifier = getUserIdentifier(cell.getValue());
60-
return <span className="text-sm">{identifier}</span>;
62+
63+
if (!identifier) {
64+
return "N/A";
65+
}
66+
67+
return (
68+
<CopyTextButton
69+
textToShow={
70+
identifier.length > 30
71+
? `${identifier.slice(0, 30)}...`
72+
: identifier
73+
}
74+
textToCopy={identifier}
75+
tooltip="Copy User Identifier"
76+
copyIconPosition="left"
77+
variant="ghost"
78+
/>
79+
);
6180
},
6281
enableColumnFilter: true,
6382
header: "User Identifier",
@@ -77,7 +96,7 @@ export function InAppWalletUsersPageContent(
7796
cell: (cell) => {
7897
const externalWallets = getExternalWallets(cell.getValue());
7998
if (externalWallets.length === 0) {
80-
return <span className="text-muted-foreground text-xs">None</span>;
99+
return <span className="text-muted-foreground text-sm">None</span>;
81100
}
82101
return (
83102
<div className="space-y-1">
@@ -111,9 +130,14 @@ export function InAppWalletUsersPageContent(
111130
return;
112131
}
113132
return (
114-
<span className="text-sm">
115-
{format(new Date(value), "MMM dd, yyyy")}
116-
</span>
133+
<ToolTipLabel
134+
label={format(new Date(value), "MMM dd, yyyy 'at' h:mm:ss a zzz")}
135+
hoverable
136+
>
137+
<span className="text-sm">
138+
{format(new Date(value), "MMM dd, yyyy")}
139+
</span>
140+
</ToolTipLabel>
117141
);
118142
},
119143
header: "Created",
@@ -215,7 +239,7 @@ export function InAppWalletUsersPageContent(
215239
return {
216240
address: row.wallets[0]?.address || "Uninitialized",
217241
created: row.wallets[0]?.createdAt
218-
? format(new Date(row.wallets[0].createdAt), "MMM dd, yyyy")
242+
? new Date(row.wallets[0].createdAt).toISOString()
219243
: "Wallet not created yet",
220244
external_wallets: externalWalletAddresses || "None",
221245
login_methods: row.linkedAccounts.map((acc) => acc.type).join(", "),
@@ -243,7 +267,7 @@ export function InAppWalletUsersPageContent(
243267
<div className="flex flex-col gap-4">
244268
{/* Top section */}
245269
<div className="flex flex-col gap-4">
246-
<div className="flex items-center justify-end gap-3">
270+
<div className="flex flex-col md:flex-row lg:items-center justify-end gap-3">
247271
<div className="w-full max-w-lg">
248272
<AdvancedSearchInput
249273
onSearch={handleSearch}
@@ -253,10 +277,9 @@ export function InAppWalletUsersPageContent(
253277
/>
254278
</div>
255279
<Button
256-
className="gap-2"
280+
className="gap-2 bg-card"
257281
disabled={wallets.length === 0 || isPending}
258282
onClick={downloadCSV}
259-
size="sm"
260283
variant="outline"
261284
>
262285
{isPending && <Spinner className="size-4" />}

0 commit comments

Comments
 (0)