shadcn.io is not affiliated with official shadcn/ui
Sign-in History Account Block for React Aria
Every sign-in attempt in the last 14 days in a sortable, searchable table with failed attempts marked by an icon and a reason, rows that open to the user agent and steps, pages of 5 or 10 and four derived figures.
Installation
Overview
Let people check who tried to get into their account, with this sign-in history panel for React with React Aria. A hairline frame with a plus mark on each corner opens with a strip of four figures worked out from the attempts: how many there were, how many failed, how many came from places the account had not been used from, and when the last one succeeded. Below it a toolbar holds a search over place and address in an Input and a Native Select for the result. The table has a sortable When, Result, Method and Place, the address in mono and the browser. A failed attempt has an X icon, the word Failed and its reason in a few words, and no tint. A row opens, with a Collapsible on a phone, to the full user agent, the steps the attempt went through and the reason in full. The foot says which rows show, sets pages of 5 or 10 and holds the catalog Pagination. Searching, sorting and paging keep the panel's height, and a search that matches nothing shows an Empty state with a way back. Below the large breakpoint each attempt is a three-line card. It's built from Input, Native Select, Collapsible, Pagination, Empty, Button and Guides, with a CSS entrance only. For the security page of any app with a record of sign-ins.
FAQ
How do I list my own attempts?
Edit SOURCES (a place and a program: city, documentation address, browser, the user agent and how it signs in) and ATTEMPTS (a time in UTC, the source, and for a failure its short reason, the full one and the step it stopped at). The four figures, the method chain in each row, the sort orders and the page counts are worked out from those, so nothing is typed twice. KNOWN lists the places the account was already used from; any other place counts as new.
What can the table do?
Sort by When, Result, Method or Place: the first press picks the column's usual direction (newest first, failed first, A to Z), the next reverses it, and the header says which with an arrow and for a screen reader with the column's sort state. Search matches part of a place or an address, the result menu limits the list to the ones that went through or failed, and each change goes back to the first page. A search or a result with no match shows an empty state with a button that clears both. The panel keeps the height of a full page, so none of this moves it; choosing 10 per page does, on purpose.
How is a failed attempt shown without colour?
Every result is an icon and a word: a check and Succeeded, or a cross and Failed with its reason ("Wrong password") under it. Only the cross takes the destructive colour, and the row isn't tinted. Opening the row gives the reason in full, the steps it went through ("Password, Rejected") and the full user agent, for the attempts worth a second look.
What stays local, and how do I connect it?
It is all typed, read-only data, so there is nothing to undo or save. To make it real, build ATTEMPTS from your sign-in log (time, source address, user agent, the method and the outcome) and resolve the place from the address on your server. Page on the server for a long history: the table already shows only one page, and the page links are real links with a page query. Times are shown in UTC; convert them to the person's zone if you prefer.
How does it look on a phone?
Below the large breakpoint the table is replaced by a list of cards of the same three lines: when and the result, the method with the browser (or the reason, for a failure), and the place with the address. A card is a button that opens the same details under it. The four figures stay two by two above, and the page links wrap under the row count.
Is the table accessible?
It is a native table with a caption, column headers with their sort state and a button in each sortable header. The first cell of every row is a button that says which sign-in it opens ("Details of the sign-in on 14 Oct, 07:48") and whether it is expanded. The row count is a polite status that is present from the start, the page links are a labelled navigation with the current page marked, and the addresses read start to end in any language. The table is native on React Aria too, so its cells take no arrow-key grid focus.