mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
feat(help): in-app help center with per-screen guides and pictures
A help icon on every screen opens a panel with the screen's overview, its sub-screens, task guides with a framed picture per step, search across guides and the wiki, and a switch to any other screen's help. Guides exist for the dashboard, Vacay, Atlas, Collections, Journey (list, journal, studio), Settings (all tabs), Admin (all tabs) and the trip frame; the trip's own screens are in progress. Pictures are produced by Playwright (client/e2e/help), texts in all 23 languages.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the admin area (`/admin`): one route with tabs, so every tab is a
|
||||
* screen under `admin`, anchored by the page for the tab that is open. The
|
||||
* step actions that produce the pictures live in `e2e/help/admin.guide.ts`.
|
||||
*/
|
||||
|
||||
const OVERVIEW = 'Admin-Panel-Overview'
|
||||
const USERS = 'Admin-Users-and-Invites'
|
||||
const ADDONS = 'Admin-Addons'
|
||||
const CATEGORIES = 'Admin-Categories'
|
||||
const PLUGINS = 'Admin-Plugins'
|
||||
const STORAGE = 'Admin-Storage'
|
||||
const NOTIFICATIONS = 'Notifications'
|
||||
const BACKUP = 'Backups'
|
||||
const MCP = 'Admin-MCP-Tokens'
|
||||
const TEMPLATES = 'Admin-Packing-Templates'
|
||||
const GITHUB = 'Admin-GitHub-Releases'
|
||||
|
||||
const guide = (
|
||||
id: string, context: string, icon: HelpGuide['icon'], size: HelpGuide['size'], steps: number, tips: number,
|
||||
docs: HelpGuide['docs'], related: string[], result = false,
|
||||
): HelpGuide => ({ id, context, icon, size, steps, tips, media: { steps: true, result }, docs, related })
|
||||
|
||||
export const adminGuides: HelpGuide[] = [
|
||||
// Users
|
||||
guide('create-user', 'admin-users', 'userPlus', 'guide', 3, 2, { slug: USERS }, ['edit-user', 'invite-links'], true),
|
||||
guide('edit-user', 'admin-users', 'pencil', 'quick', 2, 2, { slug: USERS }, ['create-user', 'delete-user']),
|
||||
guide('invite-links', 'admin-users', 'link', 'guide', 3, 2, { slug: USERS }, ['create-user'], true),
|
||||
guide('delete-user', 'admin-users', 'trash', 'quick', 1, 2, { slug: USERS }, ['edit-user']),
|
||||
guide('permissions', 'admin-users', 'sliders', 'quick', 2, 2, { slug: 'Admin-Permissions' }, ['edit-user']),
|
||||
// User Defaults
|
||||
guide('default-map', 'admin-defaults', 'map', 'quick', 2, 2, { slug: OVERVIEW }, ['instance-keys']),
|
||||
// Personalization
|
||||
guide('packing-templates', 'admin-config', 'library', 'guide', 3, 2, { slug: TEMPLATES }, ['categories'], true),
|
||||
guide('categories', 'admin-config', 'tags', 'quick', 2, 2, { slug: CATEGORIES }, ['packing-templates']),
|
||||
// Related across screens: the Vacay guide that switches these holidays on.
|
||||
guide('school-holiday-catalog', 'admin-config', 'graduationCap', 'quick', 2, 1, { slug: 'Vacay', anchor: 'manually-maintained-school-holidays' }, ['school-holidays', 'categories']),
|
||||
// Settings
|
||||
guide('auth-methods', 'admin-settings', 'lock', 'guide', 3, 2, { slug: OVERVIEW }, ['oidc']),
|
||||
guide('oidc', 'admin-settings', 'shield', 'guide', 2, 2, { slug: 'OIDC-SSO' }, ['auth-methods']),
|
||||
guide('instance-keys', 'admin-settings', 'key', 'guide', 3, 2, { slug: 'Places-and-Search' }, ['places-transit', 'default-map']),
|
||||
guide('places-transit', 'admin-settings', 'search', 'quick', 2, 2, { slug: 'Places-and-Search' }, ['instance-keys']),
|
||||
guide('file-types', 'admin-settings', 'fileInput', 'quick', 1, 1, { slug: 'Documents-and-Files' }, ['storage-backends']),
|
||||
// Addons
|
||||
guide('toggle-addon', 'admin-addons', 'sliders', 'quick', 2, 2, { slug: ADDONS }, ['install-plugin']),
|
||||
// Plugins
|
||||
guide('install-plugin', 'admin-plugins', 'plug', 'guide', 3, 2, { slug: PLUGINS }, ['toggle-addon']),
|
||||
// Storage
|
||||
guide('storage-backends', 'admin-storage', 'download', 'guide', 3, 2, { slug: STORAGE }, ['create-backup']),
|
||||
// Notifications
|
||||
guide('channels-instance', 'admin-notifications', 'bell', 'guide', 3, 2, { slug: NOTIFICATIONS, anchor: 'notification-channels' }, ['admin-channels']),
|
||||
guide('admin-channels', 'admin-notifications', 'bell', 'quick', 2, 1, { slug: NOTIFICATIONS }, ['channels-instance']),
|
||||
// MCP Access
|
||||
guide('mcp-tokens-admin', 'admin-mcp-tokens', 'key', 'quick', 2, 2, { slug: MCP }, ['auth-methods']),
|
||||
// GitHub
|
||||
guide('release-history', 'admin-github', 'bookOpen', 'quick', 2, 2, { slug: GITHUB }, ['create-backup']),
|
||||
// Backup
|
||||
guide('create-backup', 'admin-backup', 'archive', 'guide', 3, 2, { slug: BACKUP }, ['auto-backup', 'storage-backends'], true),
|
||||
guide('auto-backup', 'admin-backup', 'repeat', 'quick', 2, 2, { slug: BACKUP }, ['create-backup']),
|
||||
// Audit
|
||||
guide('audit-log', 'admin-audit', 'search', 'quick', 2, 2, { slug: 'Audit-Log' }, ['edit-user']),
|
||||
]
|
||||
|
||||
const forContext = (id: string) => adminGuides.filter(g => g.context === id).map(g => g.id)
|
||||
|
||||
export const adminContext: HelpContext = {
|
||||
id: 'admin',
|
||||
route: '/admin',
|
||||
icon: 'shield',
|
||||
bullets: 5,
|
||||
guides: [],
|
||||
docs: [{ slug: OVERVIEW }, { slug: USERS }, { slug: ADDONS }],
|
||||
hero: true,
|
||||
}
|
||||
|
||||
const tab = (id: string, icon: HelpContext['icon'], bullets: number, docs: HelpContext['docs']): HelpContext => ({
|
||||
id, parent: 'admin', route: `/admin?tab=${id.slice('admin-'.length)}`, icon, bullets, guides: forContext(id), docs, hero: true,
|
||||
})
|
||||
|
||||
export const adminTabContexts: HelpContext[] = [
|
||||
tab('admin-users', 'user', 4, [{ slug: USERS }, { slug: 'Admin-Permissions' }]),
|
||||
tab('admin-defaults', 'map', 2, [{ slug: OVERVIEW }]),
|
||||
tab('admin-config', 'sliders', 3, [{ slug: CATEGORIES }, { slug: TEMPLATES }]),
|
||||
tab('admin-settings', 'lock', 4, [{ slug: OVERVIEW }, { slug: 'OIDC-SSO' }, { slug: 'Places-and-Search' }]),
|
||||
tab('admin-addons', 'plug', 3, [{ slug: ADDONS }]),
|
||||
tab('admin-plugins', 'plug', 3, [{ slug: PLUGINS }]),
|
||||
tab('admin-storage', 'download', 3, [{ slug: STORAGE }]),
|
||||
tab('admin-notifications', 'bell', 3, [{ slug: NOTIFICATIONS }]),
|
||||
tab('admin-mcp-tokens', 'key', 2, [{ slug: MCP }]),
|
||||
tab('admin-github', 'bookOpen', 2, [{ slug: GITHUB }, { slug: 'Updating' }]),
|
||||
tab('admin-backup', 'archive', 3, [{ slug: BACKUP }]),
|
||||
tab('admin-audit', 'search', 2, [{ slug: 'Audit-Log' }]),
|
||||
]
|
||||
@@ -0,0 +1,121 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the Atlas addon (`/atlas`): the world map of visited countries,
|
||||
* regions and the bucket list. The step actions that produce the pictures live
|
||||
* in `e2e/help/atlas.guide.ts`, keyed by the same ids.
|
||||
*/
|
||||
|
||||
const ATLAS = 'Atlas'
|
||||
|
||||
export const atlasGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'mark-country',
|
||||
context: 'atlas',
|
||||
icon: 'mapPin',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'marking-countries-as-visited' },
|
||||
related: ['unmark-country', 'regions', 'bucket-country'],
|
||||
},
|
||||
{
|
||||
id: 'unmark-country',
|
||||
context: 'atlas',
|
||||
icon: 'minusCircle',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: ATLAS, anchor: 'marking-countries-as-visited' },
|
||||
related: ['mark-country'],
|
||||
},
|
||||
{
|
||||
id: 'country-details',
|
||||
context: 'atlas',
|
||||
icon: 'search',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'statistics' },
|
||||
related: ['stats', 'planned-countries'],
|
||||
},
|
||||
{
|
||||
id: 'planned-countries',
|
||||
context: 'atlas',
|
||||
icon: 'eye',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'visited-and-planned-countries' },
|
||||
related: ['country-details', 'mark-country'],
|
||||
},
|
||||
{
|
||||
id: 'regions',
|
||||
context: 'atlas',
|
||||
icon: 'regions',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'sub-national-regions' },
|
||||
related: ['search-place', 'mark-country'],
|
||||
},
|
||||
{
|
||||
id: 'search-place',
|
||||
context: 'atlas',
|
||||
icon: 'landmark',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'marking-countries-as-visited' },
|
||||
related: ['regions', 'bucket-place'],
|
||||
},
|
||||
{
|
||||
id: 'bucket-country',
|
||||
context: 'atlas',
|
||||
icon: 'star',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'bucket-list' },
|
||||
related: ['bucket-place', 'mark-country'],
|
||||
},
|
||||
{
|
||||
id: 'bucket-place',
|
||||
context: 'atlas',
|
||||
icon: 'plus',
|
||||
size: 'guide',
|
||||
steps: 4,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: ATLAS, anchor: 'bucket-list' },
|
||||
related: ['bucket-country'],
|
||||
},
|
||||
{
|
||||
id: 'stats',
|
||||
context: 'atlas',
|
||||
icon: 'chart',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: ATLAS, anchor: 'statistics' },
|
||||
related: ['country-details'],
|
||||
},
|
||||
]
|
||||
|
||||
export const atlasContext: HelpContext = {
|
||||
id: 'atlas',
|
||||
route: '/atlas',
|
||||
icon: 'globe',
|
||||
bullets: 6,
|
||||
guides: atlasGuides.map(g => g.id),
|
||||
docs: [{ slug: ATLAS }, { slug: 'Dawarich' }, { slug: 'Admin-Addons' }],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the Collections addon (`/collections`): the place library outside
|
||||
* of any trip. The step actions that produce the pictures live in
|
||||
* `e2e/help/collections.guide.ts`, keyed by the same ids.
|
||||
*/
|
||||
|
||||
const COLLECTIONS = 'Collections'
|
||||
|
||||
export const collectionsGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'create-list',
|
||||
context: 'collections',
|
||||
icon: 'plus',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'lists' },
|
||||
related: ['add-place', 'edit-list', 'import-from-trip'],
|
||||
},
|
||||
{
|
||||
id: 'add-place',
|
||||
context: 'collections',
|
||||
icon: 'mapPin',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'adding-places' },
|
||||
related: ['import-from-trip', 'place-detail'],
|
||||
},
|
||||
{
|
||||
id: 'import-from-trip',
|
||||
context: 'collections',
|
||||
icon: 'download',
|
||||
size: 'guide',
|
||||
steps: 4,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'adding-places' },
|
||||
related: ['add-place', 'copy-to-trip'],
|
||||
},
|
||||
{
|
||||
id: 'place-status',
|
||||
context: 'collections',
|
||||
icon: 'checkCircle',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'place-status' },
|
||||
related: ['place-detail', 'filter-select'],
|
||||
},
|
||||
{
|
||||
id: 'place-detail',
|
||||
context: 'collections',
|
||||
icon: 'panelRight',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: COLLECTIONS, anchor: 'place-detail' },
|
||||
related: ['place-status', 'copy-to-trip', 'labels'],
|
||||
},
|
||||
{
|
||||
id: 'labels',
|
||||
context: 'collections',
|
||||
icon: 'tags',
|
||||
size: 'guide',
|
||||
steps: 4,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'custom-labels' },
|
||||
related: ['filter-select', 'place-detail'],
|
||||
},
|
||||
{
|
||||
id: 'filter-select',
|
||||
context: 'collections',
|
||||
icon: 'filter',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'filtering-and-bulk-actions' },
|
||||
related: ['copy-to-trip', 'labels'],
|
||||
},
|
||||
{
|
||||
id: 'copy-to-trip',
|
||||
context: 'collections',
|
||||
icon: 'copy',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'filtering-and-bulk-actions' },
|
||||
related: ['filter-select', 'import-from-trip'],
|
||||
},
|
||||
{
|
||||
id: 'share-list',
|
||||
context: 'collections',
|
||||
icon: 'userPlus',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'sharing-a-list-fusion' },
|
||||
related: ['export-list'],
|
||||
},
|
||||
{
|
||||
id: 'export-list',
|
||||
context: 'collections',
|
||||
icon: 'upload',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: COLLECTIONS, anchor: 'sending-a-list-to-someone-else' },
|
||||
related: ['import-file', 'share-list'],
|
||||
},
|
||||
{
|
||||
id: 'import-file',
|
||||
context: 'collections',
|
||||
icon: 'fileInput',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'sending-a-list-to-someone-else' },
|
||||
related: ['export-list', 'create-list'],
|
||||
},
|
||||
{
|
||||
id: 'edit-list',
|
||||
context: 'collections',
|
||||
icon: 'pencil',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: COLLECTIONS, anchor: 'lists' },
|
||||
related: ['create-list'],
|
||||
},
|
||||
{
|
||||
id: 'all-saved',
|
||||
context: 'collections',
|
||||
icon: 'library',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: COLLECTIONS, anchor: 'lists' },
|
||||
related: ['filter-select'],
|
||||
},
|
||||
]
|
||||
|
||||
export const collectionsContext: HelpContext = {
|
||||
id: 'collections',
|
||||
route: '/collections',
|
||||
icon: 'bookmark',
|
||||
bullets: 6,
|
||||
guides: collectionsGuides.map(g => g.id),
|
||||
docs: [{ slug: COLLECTIONS }, { slug: 'Admin-Categories' }, { slug: 'Admin-Addons' }],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the desktop dashboard (`/dashboard`). The step actions that produce
|
||||
* the pictures for these guides live in `e2e/help/dashboard.guide.ts` and are
|
||||
* keyed by the same ids, so a step added here without an action there fails
|
||||
* the media run.
|
||||
*/
|
||||
|
||||
const DOCS = {
|
||||
dashboard: { slug: 'My-Trips-Dashboard' },
|
||||
creating: { slug: 'Creating-a-Trip' },
|
||||
widgets: { slug: 'Dashboard-Widgets' },
|
||||
feeds: { slug: 'Calendar-Feeds' },
|
||||
} as const
|
||||
|
||||
export const dashboardGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'create-trip',
|
||||
context: 'dashboard',
|
||||
icon: 'plus',
|
||||
size: 'guide',
|
||||
steps: 5,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: DOCS.creating,
|
||||
related: ['cover-image', 'edit-trip'],
|
||||
},
|
||||
{
|
||||
id: 'edit-trip',
|
||||
context: 'dashboard',
|
||||
icon: 'pencil',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: 'Creating-a-Trip', anchor: 'fields' },
|
||||
related: ['cover-image', 'duplicate-trip'],
|
||||
},
|
||||
{
|
||||
id: 'cover-image',
|
||||
context: 'dashboard',
|
||||
icon: 'image',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: 'Creating-a-Trip', anchor: 'fields' },
|
||||
related: ['edit-trip'],
|
||||
},
|
||||
{
|
||||
id: 'duplicate-trip',
|
||||
context: 'dashboard',
|
||||
icon: 'copy',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: 'My-Trips-Dashboard', anchor: 'per-trip-actions' },
|
||||
related: ['create-trip'],
|
||||
},
|
||||
{
|
||||
id: 'archive-trip',
|
||||
context: 'dashboard',
|
||||
icon: 'archive',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 0,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: 'My-Trips-Dashboard', anchor: 'archived-trips' },
|
||||
related: ['delete-trip', 'filter-and-view'],
|
||||
},
|
||||
{
|
||||
id: 'delete-trip',
|
||||
context: 'dashboard',
|
||||
icon: 'trash',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 0,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: 'My-Trips-Dashboard', anchor: 'per-trip-actions' },
|
||||
related: ['archive-trip'],
|
||||
},
|
||||
{
|
||||
id: 'filter-and-view',
|
||||
context: 'dashboard',
|
||||
icon: 'filter',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 0,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: 'My-Trips-Dashboard', anchor: 'view-modes' },
|
||||
related: ['archive-trip'],
|
||||
},
|
||||
{
|
||||
id: 'calendar-feed',
|
||||
context: 'dashboard',
|
||||
icon: 'calendar',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: 'Calendar-Feeds', anchor: 'turning-a-feed-on' },
|
||||
},
|
||||
{
|
||||
id: 'widgets',
|
||||
context: 'dashboard',
|
||||
icon: 'layout',
|
||||
size: 'guide',
|
||||
steps: 4,
|
||||
tips: 0,
|
||||
media: { steps: true, result: true },
|
||||
docs: DOCS.widgets,
|
||||
link: '/settings?tab=appearance',
|
||||
related: ['currency-widget', 'timezones-widget'],
|
||||
},
|
||||
{
|
||||
id: 'currency-widget',
|
||||
context: 'dashboard',
|
||||
icon: 'coins',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: 'Dashboard-Widgets', anchor: 'currency-converter' },
|
||||
related: ['widgets'],
|
||||
},
|
||||
{
|
||||
id: 'timezones-widget',
|
||||
context: 'dashboard',
|
||||
icon: 'clock',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 0,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: 'Dashboard-Widgets', anchor: 'timezone-clock' },
|
||||
related: ['widgets'],
|
||||
},
|
||||
]
|
||||
|
||||
export const dashboardContext: HelpContext = {
|
||||
id: 'dashboard',
|
||||
route: '/dashboard',
|
||||
icon: 'layout',
|
||||
bullets: 5,
|
||||
guides: dashboardGuides.map(g => g.id),
|
||||
docs: [DOCS.dashboard, DOCS.creating, DOCS.widgets, DOCS.feeds],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the Journey addon: the list of journeys (`/journey`) and one open
|
||||
* journal (`/journey/:id`) are two screens with their own guides. The step
|
||||
* actions that produce the pictures live in `e2e/help/journey.guide.ts`,
|
||||
* keyed by the same ids.
|
||||
*/
|
||||
|
||||
const JOURNEY = 'Journey-Journal'
|
||||
|
||||
export const journeyGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'create-journey',
|
||||
context: 'journey',
|
||||
icon: 'plus',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'creating-a-journey' },
|
||||
related: ['continue-writing', 'add-entry'],
|
||||
},
|
||||
{
|
||||
id: 'open-journey',
|
||||
context: 'journey',
|
||||
icon: 'bookOpen',
|
||||
size: 'quick',
|
||||
steps: 1,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'accessing-journey' },
|
||||
related: ['continue-writing'],
|
||||
},
|
||||
{
|
||||
id: 'continue-writing',
|
||||
context: 'journey',
|
||||
icon: 'pencil',
|
||||
size: 'quick',
|
||||
steps: 1,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'getting-around-a-long-journal' },
|
||||
related: ['add-entry', 'open-journey'],
|
||||
},
|
||||
]
|
||||
|
||||
export const journeyContext: HelpContext = {
|
||||
id: 'journey',
|
||||
route: '/journey',
|
||||
icon: 'bookOpen',
|
||||
bullets: 3,
|
||||
guides: journeyGuides.map(g => g.id),
|
||||
docs: [{ slug: JOURNEY }, { slug: 'Admin-Addons' }],
|
||||
hero: true,
|
||||
}
|
||||
|
||||
export const journalGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'add-entry',
|
||||
context: 'journey-detail',
|
||||
icon: 'plus',
|
||||
size: 'guide',
|
||||
steps: 4,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'journal-entries' },
|
||||
related: ['entry-photos', 'pros-cons', 'suggestions'],
|
||||
},
|
||||
{
|
||||
id: 'entry-photos',
|
||||
context: 'journey-detail',
|
||||
icon: 'image',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'journal-entries' },
|
||||
related: ['add-entry', 'gallery-map'],
|
||||
},
|
||||
{
|
||||
id: 'suggestions',
|
||||
context: 'journey-detail',
|
||||
icon: 'sparkles',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'creating-a-journey' },
|
||||
related: ['add-entry', 'link-trip'],
|
||||
},
|
||||
{
|
||||
id: 'add-on-day',
|
||||
context: 'journey-detail',
|
||||
icon: 'calendar',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'getting-around-a-long-journal' },
|
||||
related: ['add-entry'],
|
||||
},
|
||||
{
|
||||
id: 'pros-cons',
|
||||
context: 'journey-detail',
|
||||
icon: 'thumbsUp',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'journal-entries' },
|
||||
related: ['entry-fields', 'add-entry'],
|
||||
},
|
||||
{
|
||||
id: 'search-journey',
|
||||
context: 'journey-detail',
|
||||
icon: 'search',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'getting-around-a-long-journal' },
|
||||
related: ['gallery-map'],
|
||||
},
|
||||
{
|
||||
id: 'gallery-map',
|
||||
context: 'journey-detail',
|
||||
icon: 'gallery',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'map-view' },
|
||||
related: ['entry-photos', 'share-public'],
|
||||
},
|
||||
{
|
||||
id: 'entry-fields',
|
||||
context: 'journey-detail',
|
||||
icon: 'filter',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'entry-fields' },
|
||||
related: ['pros-cons'],
|
||||
},
|
||||
{
|
||||
id: 'link-trip',
|
||||
context: 'journey-detail',
|
||||
icon: 'link',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'creating-a-journey' },
|
||||
related: ['suggestions'],
|
||||
},
|
||||
{
|
||||
id: 'share-public',
|
||||
context: 'journey-detail',
|
||||
icon: 'share',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'public-sharing' },
|
||||
related: ['contributors', 'gallery-map'],
|
||||
},
|
||||
{
|
||||
id: 'contributors',
|
||||
context: 'journey-detail',
|
||||
icon: 'userPlus',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'creating-a-journey' },
|
||||
related: ['share-public'],
|
||||
},
|
||||
{
|
||||
id: 'studio',
|
||||
context: 'journey-detail',
|
||||
icon: 'book',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['entry-photos'],
|
||||
},
|
||||
{
|
||||
id: 'archive-journey',
|
||||
context: 'journey-detail',
|
||||
icon: 'archive',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'creating-a-journey' },
|
||||
related: ['link-trip'],
|
||||
},
|
||||
]
|
||||
|
||||
export const journalContext: HelpContext = {
|
||||
id: 'journey-detail',
|
||||
parent: 'journey',
|
||||
icon: 'bookOpen',
|
||||
bullets: 6,
|
||||
guides: journalGuides.map(g => g.id),
|
||||
docs: [{ slug: JOURNEY }, { slug: 'Public-Share-Links' }],
|
||||
hero: true,
|
||||
}
|
||||
|
||||
/** TREK Studio, the photo-book designer that opens over a journal (`/journey/:id/studio`). */
|
||||
export const studioGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'studio-auto-layout',
|
||||
context: 'journey-studio',
|
||||
icon: 'sparkles',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-pages', 'studio-layouts'],
|
||||
},
|
||||
{
|
||||
id: 'studio-pages',
|
||||
context: 'journey-studio',
|
||||
icon: 'book',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-layouts', 'studio-spread-file'],
|
||||
},
|
||||
{
|
||||
id: 'studio-layouts',
|
||||
context: 'journey-studio',
|
||||
icon: 'layout',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-auto-layout', 'studio-content'],
|
||||
},
|
||||
{
|
||||
id: 'studio-content',
|
||||
context: 'journey-studio',
|
||||
icon: 'image',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-properties', 'studio-elements'],
|
||||
},
|
||||
{
|
||||
id: 'studio-elements',
|
||||
context: 'journey-studio',
|
||||
icon: 'plus',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-travel', 'studio-properties'],
|
||||
},
|
||||
{
|
||||
id: 'studio-travel',
|
||||
context: 'journey-studio',
|
||||
icon: 'globe',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-elements'],
|
||||
},
|
||||
{
|
||||
id: 'studio-properties',
|
||||
context: 'journey-studio',
|
||||
icon: 'panelRight',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-content', 'studio-layouts'],
|
||||
},
|
||||
{
|
||||
id: 'studio-format',
|
||||
context: 'journey-studio',
|
||||
icon: 'filter',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-export'],
|
||||
},
|
||||
{
|
||||
id: 'studio-export',
|
||||
context: 'journey-studio',
|
||||
icon: 'upload',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-format', 'studio-spread-file'],
|
||||
},
|
||||
{
|
||||
id: 'studio-spread-file',
|
||||
context: 'journey-studio',
|
||||
icon: 'fileInput',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: JOURNEY, anchor: 'trek-studio' },
|
||||
related: ['studio-export', 'studio-pages'],
|
||||
},
|
||||
]
|
||||
|
||||
export const studioContext: HelpContext = {
|
||||
id: 'journey-studio',
|
||||
parent: 'journey',
|
||||
icon: 'book',
|
||||
bullets: 6,
|
||||
guides: studioGuides.map(g => g.id),
|
||||
docs: [{ slug: JOURNEY, anchor: 'trek-studio' }],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the user settings (`/settings`). The page is one route with tabs,
|
||||
* so every tab is a screen of its own under `settings`; the page anchors the
|
||||
* tab that is open. The step actions that produce the pictures live in
|
||||
* `e2e/help/settings.guide.ts`, keyed by the same ids.
|
||||
*/
|
||||
|
||||
const SETTINGS = 'User-Settings'
|
||||
const GENERAL = 'Display-Settings'
|
||||
const APPEARANCE = 'Appearance-Settings'
|
||||
const MAP = 'Map-Settings'
|
||||
const NOTIFICATIONS = 'Notifications'
|
||||
const OFFLINE = 'Offline-Mode-and-PWA'
|
||||
|
||||
const guide = (
|
||||
id: string, context: string, icon: HelpGuide['icon'], size: HelpGuide['size'], steps: number, tips: number,
|
||||
docs: HelpGuide['docs'], related: string[], result = true,
|
||||
): HelpGuide => ({ id, context, icon, size, steps, tips, media: { steps: true, result }, docs, related })
|
||||
|
||||
export const settingsGuides: HelpGuide[] = [
|
||||
// General
|
||||
guide('language-region', 'settings-display', 'globe', 'quick', 2, 2, { slug: GENERAL, anchor: 'language' }, ['travel-map-prefs', 'startup'], false),
|
||||
guide('travel-map-prefs', 'settings-display', 'mapPin', 'quick', 2, 1, { slug: GENERAL, anchor: 'always-show-booking-routes' }, ['language-region', 'map-provider'], false),
|
||||
guide('startup', 'settings-display', 'compass', 'quick', 2, 1, { slug: GENERAL, anchor: 'start-page' }, ['language-region'], false),
|
||||
// Appearance
|
||||
guide('theme-scheme', 'settings-appearance', 'palette', 'guide', 3, 2, { slug: APPEARANCE }, ['readability', 'dashboard-widgets']),
|
||||
guide('readability', 'settings-appearance', 'eye', 'quick', 2, 2, { slug: APPEARANCE }, ['theme-scheme'], false),
|
||||
guide('dashboard-widgets', 'settings-appearance', 'layout', 'quick', 2, 2, { slug: APPEARANCE }, ['theme-scheme'], false),
|
||||
// Map
|
||||
guide('map-provider', 'settings-map', 'map', 'guide', 3, 2, { slug: MAP }, ['travel-map-prefs'], false),
|
||||
// Notifications
|
||||
guide('notification-channels', 'settings-notifications', 'bell', 'guide', 3, 2, { slug: NOTIFICATIONS, anchor: 'notification-channels' }, [], false),
|
||||
// Integrations
|
||||
guide('photo-providers', 'settings-integrations', 'image', 'guide', 2, 2, { slug: 'Photo-Providers' }, ['api-keys'], false),
|
||||
guide('api-keys', 'settings-integrations', 'key', 'guide', 2, 2, { slug: SETTINGS, anchor: 'integrations-tab' }, ['mcp-oauth'], false),
|
||||
guide('mcp-oauth', 'settings-integrations', 'plug', 'guide', 3, 2, { slug: 'MCP-Setup' }, ['api-keys'], false),
|
||||
// Offline
|
||||
guide('offline-prepare', 'settings-offline', 'cloudOff', 'guide', 3, 2, { slug: OFFLINE, anchor: 'settings--offline' }, ['offline-conflicts'], false),
|
||||
guide('offline-conflicts', 'settings-offline', 'repeat', 'quick', 2, 1, { slug: OFFLINE, anchor: 'settings--offline' }, ['offline-prepare'], false),
|
||||
// Account
|
||||
guide('profile', 'settings-account', 'user', 'quick', 2, 1, { slug: SETTINGS, anchor: 'account-tab-summary' }, ['password'], false),
|
||||
guide('password', 'settings-account', 'lock', 'quick', 2, 1, { slug: SETTINGS, anchor: 'account-tab-summary' }, ['mfa'], false),
|
||||
guide('mfa', 'settings-account', 'shield', 'guide', 3, 2, { slug: 'Two-Factor-Authentication' }, ['passkeys', 'password']),
|
||||
// Passkeys only exist on https, which the media run is not: words only.
|
||||
{ ...guide('passkeys', 'settings-account', 'fingerprint', 'quick', 2, 2, { slug: 'Passkeys' }, ['mfa'], false), media: { steps: false, result: false } },
|
||||
guide('delete-account', 'settings-account', 'trash', 'quick', 1, 2, { slug: SETTINGS, anchor: 'account-tab-summary' }, ['profile'], false),
|
||||
]
|
||||
|
||||
const forContext = (id: string) => settingsGuides.filter(g => g.context === id).map(g => g.id)
|
||||
|
||||
export const settingsContext: HelpContext = {
|
||||
id: 'settings',
|
||||
route: '/settings',
|
||||
icon: 'sliders',
|
||||
bullets: 4,
|
||||
guides: [],
|
||||
docs: [{ slug: SETTINGS }, { slug: GENERAL }, { slug: APPEARANCE }],
|
||||
hero: true,
|
||||
}
|
||||
|
||||
const tab = (id: string, icon: HelpContext['icon'], bullets: number, docs: HelpContext['docs']): HelpContext => ({
|
||||
id, parent: 'settings', route: `/settings?tab=${id.slice('settings-'.length)}`, icon, bullets, guides: forContext(id), docs, hero: true,
|
||||
})
|
||||
|
||||
export const settingsTabContexts: HelpContext[] = [
|
||||
tab('settings-display', 'sliders', 3, [{ slug: GENERAL }]),
|
||||
tab('settings-appearance', 'palette', 4, [{ slug: APPEARANCE }]),
|
||||
tab('settings-map', 'map', 3, [{ slug: MAP }]),
|
||||
tab('settings-notifications', 'bell', 3, [{ slug: NOTIFICATIONS }]),
|
||||
tab('settings-integrations', 'plug', 4, [{ slug: SETTINGS, anchor: 'integrations-tab' }, { slug: 'MCP-Setup' }, { slug: 'Photo-Providers' }]),
|
||||
tab('settings-offline', 'cloudOff', 4, [{ slug: OFFLINE }]),
|
||||
tab('settings-account', 'user', 4, [{ slug: SETTINGS, anchor: 'account-tab-summary' }, { slug: 'Two-Factor-Authentication' }, { slug: 'Passkeys' }]),
|
||||
]
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for a trip (`/trips/:id`). The trip is a family of screens: this one is
|
||||
* the frame (the tabs, the three columns of the plan, the people in the trip),
|
||||
* the columns, the overlays and the other tabs each get their own screen under
|
||||
* it, anchored by the page for whatever is open. The step actions that produce
|
||||
* the pictures live in `e2e/help/trip.guide.ts`.
|
||||
*/
|
||||
|
||||
const SHARING = 'Sharing-and-Collaboration'
|
||||
const PLANNER = 'Trip-Planner'
|
||||
|
||||
const guide = (
|
||||
id: string, icon: HelpGuide['icon'], size: HelpGuide['size'], steps: number, tips: number,
|
||||
docs: HelpGuide['docs'], related: string[], result = false,
|
||||
): HelpGuide => ({ id, context: 'trip', icon, size, steps, tips, media: { steps: true, result }, docs, related })
|
||||
|
||||
export const tripGuides: HelpGuide[] = [
|
||||
guide('add-member', 'userPlus', 'quick', 3, 2, { slug: SHARING }, ['trip-invite-link', 'add-guest'], true),
|
||||
guide('trip-invite-link', 'link', 'quick', 3, 2, { slug: SHARING }, ['add-member', 'invite-links']),
|
||||
guide('add-guest', 'userRound', 'quick', 2, 2, { slug: SHARING, anchor: 'guests' }, ['add-member'], true),
|
||||
guide('public-link', 'share', 'quick', 3, 2, { slug: SHARING, anchor: 'public-share-links' }, ['add-member']),
|
||||
guide('transfer-ownership', 'crown', 'quick', 2, 2, { slug: SHARING }, ['add-member']),
|
||||
guide('collapse-columns', 'panelLeft', 'quick', 3, 2, { slug: PLANNER }, []),
|
||||
guide('undo-change', 'undo', 'quick', 1, 2, { slug: PLANNER }, []),
|
||||
]
|
||||
|
||||
export const tripContext: HelpContext = {
|
||||
id: 'trip',
|
||||
route: '/trips/:id?tab=plan',
|
||||
icon: 'route',
|
||||
bullets: 6,
|
||||
guides: tripGuides.map(g => g.id),
|
||||
docs: [{ slug: PLANNER }, { slug: SHARING }],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the days column of a trip's plan: the day cards, the stops on them,
|
||||
* their order and times, notes, the day's route, and everything that leaves
|
||||
* the plan (PDF, calendar, GPX). Bookings and transports show up here too, so
|
||||
* one guide reads them and points at the screens that create them.
|
||||
* A screen under `trip`; the step actions live in `e2e/help/trip-days.guide.ts`.
|
||||
*/
|
||||
|
||||
const DAYS = 'Day-Plans-and-Notes'
|
||||
const MAP = 'Map-Features'
|
||||
|
||||
const guide = (
|
||||
id: string, icon: HelpGuide['icon'], size: HelpGuide['size'], steps: number, tips: number,
|
||||
docs: HelpGuide['docs'], related: string[], result = false,
|
||||
): HelpGuide => ({ id, context: 'trip-days', icon, size, steps, tips, media: { steps: true, result }, docs, related })
|
||||
|
||||
export const tripDaysGuides: HelpGuide[] = [
|
||||
guide('read-day-plan', 'eye', 'guide', 5, 2, { slug: DAYS, anchor: 'day-timeline' }, ['bookings-in-plan', 'day-route']),
|
||||
guide('place-onto-day', 'calendarCheck', 'guide', 4, 3, { slug: DAYS, anchor: 'assigning-places-to-a-day' }, ['place-to-open-day', 'reorder-stops', 'undo-change'], true),
|
||||
guide('reorder-stops', 'repeat', 'quick', 4, 2, { slug: DAYS, anchor: 'assigning-places-to-a-day' }, ['place-onto-day', 'set-stop-times', 'lock-stop']),
|
||||
guide('set-stop-times', 'clock', 'quick', 3, 3, { slug: DAYS, anchor: 'day-timeline' }, ['reorder-stops', 'edit-place']),
|
||||
guide('remove-from-day', 'minusCircle', 'quick', 2, 2, { slug: DAYS, anchor: 'assigning-places-to-a-day' }, ['delete-place', 'undo-change']),
|
||||
guide('lock-stop', 'lock', 'quick', 2, 2, { slug: DAYS, anchor: 'toolbar-actions' }, ['day-route', 'reorder-stops']),
|
||||
guide('day-note', 'pencil', 'quick', 4, 2, { slug: DAYS, anchor: 'day-notes' }, ['read-day-plan'], true),
|
||||
guide('day-route', 'route', 'guide', 5, 3, { slug: MAP, anchor: 'route-lines' }, ['lock-stop', 'read-day-plan']),
|
||||
guide('manage-days', 'calendarDays', 'quick', 4, 2, { slug: DAYS, anchor: 'the-day-plan-sidebar' }, ['edit-trip']),
|
||||
guide('bookings-in-plan', 'ticket', 'guide', 5, 2, { slug: DAYS, anchor: 'multi-day-reservations' }, ['read-day-plan']),
|
||||
guide('export-plan', 'download', 'quick', 4, 3, { slug: MAP, anchor: 'exporting-a-trip-as-gpx' }, ['calendar-feed']),
|
||||
]
|
||||
|
||||
export const tripDaysContext: HelpContext = {
|
||||
id: 'trip-days',
|
||||
parent: 'trip',
|
||||
route: '/trips/:id?tab=plan',
|
||||
icon: 'calendarDays',
|
||||
bullets: 6,
|
||||
guides: tripDaysGuides.map(g => g.id),
|
||||
docs: [{ slug: DAYS }, { slug: MAP }],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the places column of a trip's plan: bringing places in (by hand,
|
||||
* from a file, from a shared list), finding them, changing and deleting them.
|
||||
* A screen under `trip`; the step actions live in `e2e/help/trip-places.guide.ts`.
|
||||
*/
|
||||
|
||||
const PLACES = 'Places-and-Search'
|
||||
const IMPORT = { slug: PLACES, anchor: 'importing-places' }
|
||||
|
||||
const guide = (
|
||||
id: string, icon: HelpGuide['icon'], size: HelpGuide['size'], steps: number, tips: number,
|
||||
docs: HelpGuide['docs'], related: string[], result = false,
|
||||
): HelpGuide => ({ id, context: 'trip-places', icon, size, steps, tips, media: { steps: true, result }, docs, related })
|
||||
|
||||
export const tripPlacesGuides: HelpGuide[] = [
|
||||
guide('create-place', 'plus', 'guide', 5, 3, { slug: PLACES }, ['place-to-open-day', 'edit-place'], true),
|
||||
guide('place-to-open-day', 'calendarCheck', 'quick', 3, 2, { slug: PLACES }, ['create-place']),
|
||||
guide('filter-places', 'filter', 'quick', 4, 2, { slug: PLACES }, ['select-places']),
|
||||
guide('edit-place', 'pencil', 'quick', 3, 2, { slug: PLACES }, ['create-place', 'delete-place']),
|
||||
guide('delete-place', 'trash', 'quick', 2, 2, { slug: PLACES }, ['edit-place', 'select-places', 'undo-change']),
|
||||
guide('select-places', 'checkCircle', 'quick', 4, 2, { slug: PLACES }, ['filter-places', 'delete-place'], true),
|
||||
guide('import-places-file', 'fileInput', 'guide', 4, 2, IMPORT, ['import-places-list', 'filter-places'], true),
|
||||
guide('import-places-list', 'upload', 'quick', 3, 2, IMPORT, ['import-places-file']),
|
||||
]
|
||||
|
||||
export const tripPlacesContext: HelpContext = {
|
||||
id: 'trip-places',
|
||||
parent: 'trip',
|
||||
route: '/trips/:id?tab=plan',
|
||||
icon: 'mapPin',
|
||||
bullets: 6,
|
||||
guides: tripPlacesGuides.map(g => g.id),
|
||||
docs: [{ slug: PLACES }, IMPORT],
|
||||
hero: true,
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
import type { HelpContext, HelpGuide } from '../types'
|
||||
|
||||
/**
|
||||
* Help for the Vacay addon (`/vacay`): the personal leave planner. The step
|
||||
* actions that produce the pictures live in `e2e/help/vacay.guide.ts`, keyed
|
||||
* by the same ids.
|
||||
*/
|
||||
|
||||
const VACAY = 'Vacay'
|
||||
|
||||
export const vacayGuides: HelpGuide[] = [
|
||||
{
|
||||
id: 'log-day',
|
||||
context: 'vacay',
|
||||
icon: 'calendarCheck',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'calendar-view' },
|
||||
related: ['half-day', 'comp-day', 'entitlement'],
|
||||
},
|
||||
{
|
||||
id: 'half-day',
|
||||
context: 'vacay',
|
||||
icon: 'halfDay',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'half-days-and-comp-days' },
|
||||
related: ['log-day', 'comp-day'],
|
||||
},
|
||||
{
|
||||
id: 'comp-day',
|
||||
context: 'vacay',
|
||||
icon: 'hourglass',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'half-days-and-comp-days' },
|
||||
related: ['log-day', 'half-day'],
|
||||
},
|
||||
{
|
||||
id: 'entitlement',
|
||||
context: 'vacay',
|
||||
icon: 'calculator',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'year-plans' },
|
||||
related: ['carry-over', 'years'],
|
||||
},
|
||||
{
|
||||
id: 'years',
|
||||
context: 'vacay',
|
||||
icon: 'calendarRange',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 0,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'year-plans' },
|
||||
related: ['entitlement', 'leave-year'],
|
||||
},
|
||||
{
|
||||
id: 'company-holidays',
|
||||
context: 'vacay',
|
||||
icon: 'building',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'calendar-view' },
|
||||
related: ['public-holidays', 'log-day'],
|
||||
},
|
||||
{
|
||||
id: 'public-holidays',
|
||||
context: 'vacay',
|
||||
icon: 'flag',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'calendar-view' },
|
||||
related: ['school-holidays', 'company-holidays'],
|
||||
},
|
||||
{
|
||||
id: 'school-holidays',
|
||||
context: 'vacay',
|
||||
icon: 'graduationCap',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 1,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'manually-maintained-school-holidays' },
|
||||
// The catalogue those holidays come from is kept under Admin.
|
||||
related: ['public-holidays', 'school-holiday-catalog'],
|
||||
},
|
||||
{
|
||||
id: 'weekends',
|
||||
context: 'vacay',
|
||||
icon: 'calendarOff',
|
||||
size: 'quick',
|
||||
steps: 3,
|
||||
tips: 0,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: VACAY, anchor: 'calendar-view' },
|
||||
related: ['leave-year'],
|
||||
},
|
||||
{
|
||||
id: 'leave-year',
|
||||
context: 'vacay',
|
||||
icon: 'calendarDays',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: VACAY, anchor: 'leave-year' },
|
||||
related: ['years', 'carry-over'],
|
||||
},
|
||||
{
|
||||
id: 'carry-over',
|
||||
context: 'vacay',
|
||||
icon: 'repeat',
|
||||
size: 'quick',
|
||||
steps: 2,
|
||||
tips: 1,
|
||||
media: { steps: true, result: false },
|
||||
docs: { slug: VACAY, anchor: 'year-plans' },
|
||||
related: ['entitlement'],
|
||||
},
|
||||
{
|
||||
id: 'invite',
|
||||
context: 'vacay',
|
||||
icon: 'userPlus',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'inviting-collaborators' },
|
||||
related: ['share-calendar'],
|
||||
},
|
||||
{
|
||||
id: 'share-calendar',
|
||||
context: 'vacay',
|
||||
icon: 'share',
|
||||
size: 'guide',
|
||||
steps: 3,
|
||||
tips: 2,
|
||||
media: { steps: true, result: true },
|
||||
docs: { slug: VACAY, anchor: 'sharing-your-calendar-view-only' },
|
||||
related: ['invite'],
|
||||
},
|
||||
]
|
||||
|
||||
export const vacayContext: HelpContext = {
|
||||
id: 'vacay',
|
||||
route: '/vacay',
|
||||
icon: 'calendarDays',
|
||||
bullets: 5,
|
||||
guides: vacayGuides.map(g => g.id),
|
||||
docs: [{ slug: VACAY }, { slug: 'Admin-Addons' }],
|
||||
hero: true,
|
||||
}
|
||||
Reference in New Issue
Block a user