Add bulk delete-all for bookmarks (#20)

* Add editable display-name field to generic integrations

Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4

* Surface the new-integration name field as a labeled input

The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4

* Add file upload for SSH private key and certificate fields

Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.

* Fix SSH private key paste corrupting multi-line PEM format

Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.

* Add JSON-converted bookmark import file for Archnest data import

Converts homarr-bookmarks.md into the format expected by /api/data/import.

* Auto-populate bookmark icons via favicon service in import JSON

Each bookmark now points to Google's favicon endpoint for its domain
instead of having no icon at all.

* Add bulk delete-all for bookmarks

Adds DELETE /api/bookmarks to clear every bookmark in one request, and a
"Delete All" button (with confirmation) on the BookNest page so re-imports
don't require deleting dozens of entries one at a time.

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Samuel James 2026-06-20 09:09:44 -04:00 committed by GitHub
parent ad2cfe808c
commit d9d9f3f610
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 651 additions and 1 deletions

View file

@ -71,6 +71,13 @@ export async function bookmarkRoutes(app: FastifyInstance) {
return { ok: true }
})
app.delete('/api/bookmarks', async (_req, reply) => {
const count = (db.prepare('SELECT COUNT(*) as count FROM bookmarks').get() as { count: number }).count
db.prepare('DELETE FROM bookmarks').run()
logEvent('bookmark_deleted', `Deleted all ${count} bookmarks`)
return reply.code(204).send()
})
app.delete('/api/bookmarks/:id', async (req, reply) => {
const id = Number((req.params as { id: string }).id)
const existing = db.prepare('SELECT title FROM bookmarks WHERE id = ?').get(id) as { title: string } | undefined

View file

@ -0,0 +1,609 @@
{
"version": 1,
"integrations": [],
"bookmarkCategories": [
{
"id": 1,
"name": "Infrastructure & Self-Hosted",
"icon": null,
"sortOrder": 0
},
{
"id": 2,
"name": "Development & Code / Notes",
"icon": null,
"sortOrder": 1
},
{
"id": 3,
"name": "Lab & Networking",
"icon": null,
"sortOrder": 2
},
{
"id": 4,
"name": "Amazon Work / AWS",
"icon": null,
"sortOrder": 3
},
{
"id": 5,
"name": "AI Tools",
"icon": null,
"sortOrder": 4
},
{
"id": 6,
"name": "Learning",
"icon": null,
"sortOrder": 5
},
{
"id": 7,
"name": "Finance & Investing",
"icon": null,
"sortOrder": 6
},
{
"id": 8,
"name": "Bills, Loans, Insurance & Taxes",
"icon": null,
"sortOrder": 7
},
{
"id": 9,
"name": "Life / Streaming / Misc",
"icon": null,
"sortOrder": 8
}
],
"bookmarks": [
{
"categoryId": 1,
"title": "CasaOS",
"url": "https://casaos.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=casaos.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Proxmox (pve1)",
"url": "https://pve1.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=pve1.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Proxmox (mtr)",
"url": "https://mtr.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=mtr.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Portainer",
"url": "https://portainer.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=portainer.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Cockpit",
"url": "https://cockpit.snsnetlabs.com/system",
"icon": "https://www.google.com/s2/favicons?domain=cockpit.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Cloudflare",
"url": "https://dash.cloudflare.com/b95d12adb602dae911702cd8f27b9410/snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=dash.cloudflare.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Nginx Proxy Manager (NPM)",
"url": "https://npm2.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=npm2.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "NetBird",
"url": "https://app.netbird.io/peers",
"icon": "https://www.google.com/s2/favicons?domain=app.netbird.io&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Linode",
"url": "https://cloud.linode.com/linodes",
"icon": "https://www.google.com/s2/favicons?domain=cloud.linode.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "RackNerd",
"url": "https://my.racknerd.com/clientarea.php",
"icon": "https://www.google.com/s2/favicons?domain=my.racknerd.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Dozzle",
"url": "https://dozzle.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=dozzle.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Guacamole",
"url": "https://guac.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=guac.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Nexterm",
"url": "https://nexterm.snsnetlabs.com/servers",
"icon": "https://www.google.com/s2/favicons?domain=nexterm.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Glance",
"url": "https://glance.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=glance.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "OpenClaw",
"url": "https://openclaw.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=openclaw.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Homarr",
"url": "https://archnest.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=archnest.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 1,
"title": "Uptime Kuma",
"url": "https://uptime.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=uptime.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "GitHub",
"url": "https://github.com/",
"icon": "https://www.google.com/s2/favicons?domain=github.com&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "Gitea",
"url": "https://gitea.snsnetlabs.com/gitea",
"icon": "https://www.google.com/s2/favicons?domain=gitea.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "Forgejo",
"url": "http://192.168.122.102:3000",
"icon": "https://www.google.com/s2/favicons?domain=192.168.122.102:3000&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "Code Server",
"url": "https://code.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=code.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "Trillium Notes",
"url": "https://notes.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=notes.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "Obsidian",
"url": "https://obsidian.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=obsidian.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "IT-Tools",
"url": "https://it-tools.tech/",
"icon": "https://www.google.com/s2/favicons?domain=it-tools.tech&sz=64",
"favorite": false
},
{
"categoryId": 2,
"title": "Resume Site (samjam-tech)",
"url": "https://samuelsjames.github.io/samjam-tech/",
"icon": "https://www.google.com/s2/favicons?domain=samuelsjames.github.io&sz=64",
"favorite": false
},
{
"categoryId": 3,
"title": "GNS3",
"url": "https://gns3.snsnetlabs.com/static/web-ui/controller/1/projects",
"icon": "https://www.google.com/s2/favicons?domain=gns3.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 3,
"title": "PNETLab",
"url": "https://pnet.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=pnet.snsnetlabs.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "A2Z (Home)",
"url": "https://atoz.amazon.work/home",
"icon": "https://www.google.com/s2/favicons?domain=atoz.amazon.work&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "A2Z (Schedule)",
"url": "https://atoz.amazon.work/schedule",
"icon": "https://www.google.com/s2/favicons?domain=atoz.amazon.work&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Amazon Payroll",
"url": "https://payroll.amazon.work/",
"icon": "https://www.google.com/s2/favicons?domain=payroll.amazon.work&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Phone Tool",
"url": "https://phonetool.amazon.com/users/ssamjame",
"icon": "https://www.google.com/s2/favicons?domain=phonetool.amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Slack",
"url": "https://amazon.enterprise.slack.com/",
"icon": "https://www.google.com/s2/favicons?domain=amazon.enterprise.slack.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Quip",
"url": "https://quip-amazon.com/all",
"icon": "https://www.google.com/s2/favicons?domain=quip-amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Outlook",
"url": "https://outlook.office.com/mail/",
"icon": "https://www.google.com/s2/favicons?domain=outlook.office.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Meetings",
"url": "https://meetings.amazon.com/#/room-booking",
"icon": "https://www.google.com/s2/favicons?domain=meetings.amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Boost",
"url": "https://app.boost.aws.a2z.com/platform",
"icon": "https://www.google.com/s2/favicons?domain=app.boost.aws.a2z.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Inventory (Argo)",
"url": "https://aws.argo.ocean-wave.aws.a2z.com/inventory-receive/receive/",
"icon": "https://www.google.com/s2/favicons?domain=aws.argo.ocean-wave.aws.a2z.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Mobility",
"url": "https://prod.us-east-1.mobility.scm.aws.dev/part/search",
"icon": "https://www.google.com/s2/favicons?domain=prod.us-east-1.mobility.scm.aws.dev&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "RDPM (Cable Mgmt)",
"url": "https://rdpm.amazon.com/cable_management",
"icon": "https://www.google.com/s2/favicons?domain=rdpm.amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 4,
"title": "Interview",
"url": "https://hire.amazon.com/interviewing",
"icon": "https://www.google.com/s2/favicons?domain=hire.amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 5,
"title": "PartyRock",
"url": "https://internal.partyrock.aws.dev/image",
"icon": "https://www.google.com/s2/favicons?domain=internal.partyrock.aws.dev&sz=64",
"favorite": false
},
{
"categoryId": 5,
"title": "Chat Claude",
"url": "https://prod.matome.tools.aws.dev/chat-claude-4",
"icon": "https://www.google.com/s2/favicons?domain=prod.matome.tools.aws.dev&sz=64",
"favorite": false
},
{
"categoryId": 6,
"title": "WGU Student Portal",
"url": "https://my.wgu.edu/degree-plan",
"icon": "https://www.google.com/s2/favicons?domain=my.wgu.edu&sz=64",
"favorite": false
},
{
"categoryId": 6,
"title": "Udemy (WGU)",
"url": "https://wgu.udemy.com/organization/home/",
"icon": "https://www.google.com/s2/favicons?domain=wgu.udemy.com&sz=64",
"favorite": false
},
{
"categoryId": 6,
"title": "LinkedIn Learning",
"url": "https://www.linkedin.com/learning/?u=2045532",
"icon": "https://www.google.com/s2/favicons?domain=www.linkedin.com&sz=64",
"favorite": false
},
{
"categoryId": 6,
"title": "Toastmasters",
"url": "https://www.toastmasters.org/",
"icon": "https://www.google.com/s2/favicons?domain=www.toastmasters.org&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Ally",
"url": "https://secure.ally.com/",
"icon": "https://www.google.com/s2/favicons?domain=secure.ally.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Capital One",
"url": "https://www.capitalone.com/",
"icon": "https://www.google.com/s2/favicons?domain=www.capitalone.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Credit One",
"url": "https://www.creditonebank.com/",
"icon": "https://www.google.com/s2/favicons?domain=www.creditonebank.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Acorns",
"url": "https://app.acorns.com/present",
"icon": "https://www.google.com/s2/favicons?domain=app.acorns.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Stash",
"url": "https://app.stash.com/",
"icon": "https://www.google.com/s2/favicons?domain=app.stash.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Fundrise",
"url": "https://fundrise.com/account/overview",
"icon": "https://www.google.com/s2/favicons?domain=fundrise.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Roots Investments",
"url": "https://app.investwithroots.com/dashboard",
"icon": "https://www.google.com/s2/favicons?domain=app.investwithroots.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Fidelity",
"url": "https://digital.fidelity.com/prgw/digital/login/full-page",
"icon": "https://www.google.com/s2/favicons?domain=digital.fidelity.com&sz=64",
"favorite": false
},
{
"categoryId": 7,
"title": "Experian",
"url": "https://usa.experian.com/mfe/dashboard",
"icon": "https://www.google.com/s2/favicons?domain=usa.experian.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "Ford Motor Credit",
"url": "https://accountmanager.ford.com/dashboard",
"icon": "https://www.google.com/s2/favicons?domain=accountmanager.ford.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "Freedom Mortgage",
"url": "https://www.freedommortgage.com/",
"icon": "https://www.google.com/s2/favicons?domain=www.freedommortgage.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "Climb Investco (Student Loan)",
"url": "https://www.climbloanservicingbyuas.com/account",
"icon": "https://www.google.com/s2/favicons?domain=www.climbloanservicingbyuas.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "AT&T",
"url": "https://www.att.com/",
"icon": "https://www.google.com/s2/favicons?domain=www.att.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "Progressive (Auto)",
"url": "https://www.progressive.com/",
"icon": "https://www.google.com/s2/favicons?domain=www.progressive.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "Tower Hill Insurance",
"url": "https://customerportal.thig.com/#/home",
"icon": "https://www.google.com/s2/favicons?domain=customerportal.thig.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "TurboTax",
"url": "https://myturbotax.intuit.com/",
"icon": "https://www.google.com/s2/favicons?domain=myturbotax.intuit.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "FreeTaxUSA",
"url": "https://www.freetaxusa.com/",
"icon": "https://www.google.com/s2/favicons?domain=www.freetaxusa.com&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "IRS",
"url": "https://www.irs.gov/",
"icon": "https://www.google.com/s2/favicons?domain=www.irs.gov&sz=64",
"favorite": false
},
{
"categoryId": 8,
"title": "EveryDollar (Budget)",
"url": "https://www.everydollar.com/app/budget",
"icon": "https://www.google.com/s2/favicons?domain=www.everydollar.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Google Calendar",
"url": "https://calendar.google.com/calendar/u/0/r",
"icon": "https://www.google.com/s2/favicons?domain=calendar.google.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "WhatsApp",
"url": "https://web.whatsapp.com/",
"icon": "https://www.google.com/s2/favicons?domain=web.whatsapp.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Feedly",
"url": "https://feedly.com/i/my/me",
"icon": "https://www.google.com/s2/favicons?domain=feedly.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "FreeConference",
"url": "https://hello.freeconference.com/",
"icon": "https://www.google.com/s2/favicons?domain=hello.freeconference.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Amazon Shopping",
"url": "https://amazon.com",
"icon": "https://www.google.com/s2/favicons?domain=amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Amazon Prime Video",
"url": "https://www.amazon.com/gp/video/movie",
"icon": "https://www.google.com/s2/favicons?domain=www.amazon.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Netflix",
"url": "https://www.netflix.com/browse",
"icon": "https://www.google.com/s2/favicons?domain=www.netflix.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Disney+",
"url": "https://www.disneyplus.com/home",
"icon": "https://www.google.com/s2/favicons?domain=www.disneyplus.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Peacock",
"url": "https://www.peacocktv.com/watch/movies/highlights",
"icon": "https://www.google.com/s2/favicons?domain=www.peacocktv.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Paramount+",
"url": "https://www.paramountplus.com/movies/",
"icon": "https://www.google.com/s2/favicons?domain=www.paramountplus.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Tubi",
"url": "https://tubitv.com/",
"icon": "https://www.google.com/s2/favicons?domain=tubitv.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "DailyWire+",
"url": "https://www.dailywire.com/watch",
"icon": "https://www.google.com/s2/favicons?domain=www.dailywire.com&sz=64",
"favorite": false
},
{
"categoryId": 9,
"title": "Wellness",
"url": "https://wellness.snsnetlabs.com",
"icon": "https://www.google.com/s2/favicons?domain=wellness.snsnetlabs.com&sz=64",
"favorite": false
}
],
"tunnels": []
}

View file

@ -69,6 +69,7 @@ export const api = {
updateBookmark: (id: number, data: Partial<{ categoryId: number | null; title: string; url: string; icon: string; favorite: boolean }>) =>
apiFetch<{ ok: boolean }>(`/bookmarks/${id}`, { method: 'PUT', body: JSON.stringify(data) }),
deleteBookmark: (id: number) => apiFetch<void>(`/bookmarks/${id}`, { method: 'DELETE' }),
deleteAllBookmarks: () => apiFetch<void>('/bookmarks', { method: 'DELETE' }),
listEvents: (limit = 20) => apiFetch<{ events: Event[] }>(`/events?limit=${limit}`),
listResources: () => apiFetch<{ resources: Resource[] }>('/integrations/resources'),

View file

@ -465,6 +465,19 @@ export default function BookNest() {
}
}
async function deleteAllBookmarks() {
const count = bookmarks?.length ?? 0
if (count === 0) return
if (!window.confirm(`Delete all ${count} bookmark${count === 1 ? '' : 's'}? This cannot be undone.`)) return
const prevBookmarks = bookmarks
setBookmarks([])
try {
await api.deleteAllBookmarks()
} catch {
setBookmarks(prevBookmarks)
}
}
async function toggleFavorite(bookmark: Bookmark) {
const next = bookmark.favorite ? false : true
setBookmarks((prev) => prev?.map((b) => (b.id === bookmark.id ? { ...b, favorite: next ? 1 : 0 } : b)) ?? prev)
@ -541,12 +554,32 @@ export default function BookNest() {
)}
<div className="grid w-full gap-5" style={{ gridTemplateColumns: '3fr 1fr', gridTemplateRows: 'auto 1fr' }}>
{/* Page stats — sits directly under the hero title/subtitle, like the blueprint */}
<div className="flex items-center shrink-0" style={{ gridColumn: 1, gridRow: 1, marginTop: '8px' }}>
<div className="flex items-center justify-between shrink-0" style={{ gridColumn: 1, gridRow: 1, marginTop: '8px' }}>
<div className="flex items-center gap-5" style={{ fontSize: '12px', color: '#7A7D85' }}>
<span className="flex items-center gap-1.5"><Link2 size={13} style={{ color: '#C8A434' }} /> <strong style={{ color: '#E8E6E0' }}>{bookmarks.length}</strong> Links</span>
<span className="flex items-center gap-1.5"><FolderOpen size={13} style={{ color: '#C8A434' }} /> <strong style={{ color: '#E8E6E0' }}>{categories.length}</strong> Categories</span>
<span className="flex items-center gap-1.5"><Star size={13} style={{ color: '#C8A434' }} /> <strong style={{ color: '#E8E6E0' }}>{favorites.length}</strong> Favorites</span>
</div>
{bookmarks.length > 0 && (
<button
onClick={deleteAllBookmarks}
className="flex items-center gap-1.5 cursor-pointer transition-colors whitespace-nowrap"
style={{
fontSize: '11px',
fontWeight: 500,
color: '#7A7D85',
backgroundColor: 'transparent',
border: '1px solid rgba(231, 76, 60, 0.2)',
borderRadius: '8px',
padding: '6px 10px',
}}
onMouseEnter={(e) => { e.currentTarget.style.color = '#E74C3C'; e.currentTarget.style.borderColor = 'rgba(231, 76, 60, 0.5)' }}
onMouseLeave={(e) => { e.currentTarget.style.color = '#7A7D85'; e.currentTarget.style.borderColor = 'rgba(231, 76, 60, 0.2)' }}
>
<Trash2 size={12} />
Delete All
</button>
)}
</div>
{/* Main column */}