Files

78 lines
2.6 KiB
JavaScript

// The Tech Tools catalog.
//
// This is the ONLY place a tool has to be declared. Adding one is: write the
// view, add a route in routes.js, add an entry here. The index page groups by
// category and searches over name + description + keywords.
//
// Fields:
// id - stable slug, also the key the index uses
// name - card title
// description - one line, says what it does, not how
// category - group heading on the index
// route - path to open
// standalone - true when the route lives OUTSIDE AppLayout (print pages),
// so the index opens it as a normal link rather than a
// router-link and the user keeps this tab
// keywords - extra search terms someone might type instead of the name
export const TOOLS = [
{
id: 'code-generator',
name: 'Barcode / QR Generator',
description: 'Make QR or CODE128 labels from typed text, a URL, or a CSV, sized for your label stock.',
category: 'labels',
route: '/tools/codes',
standalone: true,
keywords: ['qr', 'barcode', 'code128', 'label', 'zebra', 'sticker', 'csv', 'print'],
},
{
id: 'secure-send',
name: 'Secure Send',
description: 'Hand somebody a password by a link that works once and then destroys it.',
category: 'security',
route: '/tools/secure-send',
keywords: ['password', 'secret', 'credential', 'share', 'link', 'expire',
'one time', 'burn', 'pusher'],
},
]
export const CATEGORY_LABELS = {
labels: 'Labels & Printing',
convert: 'Conversion',
security: 'Secrets & Access',
network: 'Network',
}
export function categoryLabel(category) {
return CATEGORY_LABELS[category] || category
}
// Tools matching a search string, or all of them when the box is empty.
export function searchTools(query) {
const needle = (query || '').trim().toLowerCase()
if (!needle) return TOOLS
return TOOLS.filter(tool => {
const haystack = [tool.name, tool.description, ...(tool.keywords || [])]
.join(' ')
.toLowerCase()
return haystack.includes(needle)
})
}
// Tools grouped for the index, categories in CATEGORY_LABELS order so the
// page does not reshuffle as tools are added.
export function groupTools(query) {
const matched = searchTools(query)
const order = Object.keys(CATEGORY_LABELS)
const seen = [...new Set(matched.map(tool => tool.category))]
seen.sort((a, b) => {
const ai = order.indexOf(a)
const bi = order.indexOf(b)
return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi)
})
return seen.map(category => ({
category,
label: categoryLabel(category),
tools: matched.filter(tool => tool.category === category),
}))
}