shadcn.io is not affiliated with official shadcn/ui
Project Archive Restore CRUD Block for Ark UI
A design agency's project list with an Archive beside it: archive a job, see how many days it is kept, restore it, delete it now behind an alert dialog or empty the lot by typing a word.
Installation
Overview
Keep finished work out of the way without losing it, with this archive and restore list for React with Ark UI. Two lists sit side by side, Active and Archive, each with its count and a held frame that scrolls inside itself (they stack on a phone). Archive on a project moves it across, dated as of 14 October, and the foot says "Archived Dairy rebrand. Kept for 30 days." beside an Undo. In the Archive every row says how long it is kept, "Removed for good in 12 days", and has Restore, which puts it back where it was, and Delete now, an Alert Dialog with a destructive action. A row past thirty days reads "Expired: removed at the next clean-up" and stays. Empty archive asks you to type the word empty before it removes the lot. The quick line adds a project with an Input and the one Shine Button: a name is required and unique. For project lists, folders, boards and any record that should wait before it goes.
FAQ
How do I fill it with my projects?
Edit PROJECTS: each has an id, a name, a client and archivedOn, an ISO day or an empty string while it is active. The counts, the days kept and the expired state are all derived from that list and the constant AS_OF, so nothing reads the clock; the keeping period is KEEP_DAYS.
How are the days counted?
Whole days between archivedOn and AS_OF, taken from UTC midnights, subtracted from thirty. Zero reads "Removed for good today" and a negative number reads "Expired: removed at the next clean-up". Nothing is deleted when a row expires: in your app a nightly job does that, and the row keeps its place until then.
What do Delete now and Empty archive ask?
Delete now opens an alert dialog on that project with Cancel first in its footer, and its action is the destructive button. Empty archive opens one that asks for the word empty; the destructive action stays disabled until it matches, so a stray Enter does nothing. Both leave a line in the foot with Undo.
Where does keyboard focus go after a move?
Focus follows the row: after Archive it lands on that project's Restore button in the Archive, after Restore on its Archive button in Active, and after a delete on the next archived row, or on the quick line when none is left. Undo returns focus to the control you used.
What stays local, and how do I wire a real archive?
Projects live in state in this tab and a reload brings the ten originals back; no file is touched. In your app call your API from move, deleteOne and emptyAll, soft-delete on the server with an archived_at column, and make Undo call the restore endpoint. Keep the thirty-day rule on the server as well.