+ }
+ title="Automate with script templates"
+ description="Pre-built and custom scripts your team can reference during sessions. PowerShell, bash, and more."
+ learnMoreLink="/guides/script-templates"
+ className="px-4"
+ />
)
}
diff --git a/frontend/src/components/step-library/StepLibraryBrowser.tsx b/frontend/src/components/step-library/StepLibraryBrowser.tsx
index 3f28805e..68787f42 100644
--- a/frontend/src/components/step-library/StepLibraryBrowser.tsx
+++ b/frontend/src/components/step-library/StepLibraryBrowser.tsx
@@ -1,6 +1,8 @@
import { useState, useEffect, useMemo } from 'react'
import { Search, ChevronDown, ChevronUp, Loader2 } from 'lucide-react'
import { Button } from '@/components/ui/Button'
+import { EmptyState } from '@/components/common/EmptyState'
+import { StepLibraryIllustration } from '@/components/common/EmptyStateIllustrations'
import { cn } from '@/lib/utils'
import { stepsApi } from '@/api/steps'
import { stepCategoriesApi } from '@/api/stepCategories'
@@ -259,12 +261,24 @@ export function StepLibraryBrowser({ onInsert, onCreateNew, showCreateButton = f
) : steps.length === 0 ? (
-
-
No steps found
-
- {hasActiveFilters ? 'Try adjusting your filters' : 'Create your first step to get started!'}
-
-
+ hasActiveFilters ? (
+
+
No steps found
+
Try adjusting your filters
+
+ ) : (
+ }
+ title="Build a reusable step library"
+ description="Save common troubleshooting steps once, reuse them across flows. Keeps your team consistent and saves build time."
+ action={
+ onCreateNew ? (
+
+ ) : undefined
+ }
+ learnMoreLink="/guides/step-library"
+ />
+ )
) : (
{/* My Steps */}
diff --git a/frontend/src/data/guides.ts b/frontend/src/data/guides.ts
index 68f596b1..413c8192 100644
--- a/frontend/src/data/guides.ts
+++ b/frontend/src/data/guides.ts
@@ -13,6 +13,8 @@ import {
Wrench,
Settings,
BarChart3,
+ Terminal,
+ Plug,
} from 'lucide-react'
export interface GuideStep {
@@ -492,4 +494,82 @@ export const guides: Guide[] = [
},
],
},
+ {
+ slug: 'script-templates',
+ title: 'Script Templates',
+ icon: Terminal,
+ summary: 'Browse, configure, and generate scripts from reusable templates.',
+ sections: [
+ {
+ title: 'Browsing Templates',
+ steps: [
+ { instruction: 'Click **Scripts** in the sidebar to open the Script Library.' },
+ { instruction: 'The left pane lists all available templates organized by category.' },
+ { instruction: 'Use the search bar to filter templates by name or keyword.' },
+ { instruction: 'Click any template to preview its script content in the right pane.' },
+ ],
+ },
+ {
+ title: 'Configuring and Generating Scripts',
+ steps: [
+ { instruction: 'Click **Configure** on a template to enter parameter values.' },
+ { instruction: 'Fill in the required fields (e.g., server name, IP address, credentials).' },
+ { instruction: 'Click **Generate** to produce a ready-to-run script with your values substituted.' },
+ { instruction: 'Copy the generated script to your clipboard or download it directly.', tip: 'Double-check generated scripts in a test environment before running them in production.' },
+ ],
+ },
+ {
+ title: 'Managing Templates',
+ steps: [
+ { instruction: 'Click **Manage Templates** at the top of the Script Library page.' },
+ { instruction: 'Create new templates with a name, category, script body, and configurable parameters.' },
+ { instruction: 'Edit or delete existing templates from the management page.' },
+ { instruction: 'Templates support PowerShell, Bash, Python, and other scripting languages.' },
+ ],
+ },
+ ],
+ },
+ {
+ slug: 'psa-setup',
+ title: 'PSA Integration Setup',
+ icon: Plug,
+ summary: 'Connect ConnectWise or other PSA tools to ResolutionFlow.',
+ sections: [
+ {
+ title: 'Getting Your API Credentials',
+ steps: [
+ { instruction: 'Log in to your ConnectWise PSA instance as an admin.' },
+ { instruction: 'Navigate to **System > Members > API Members** and create a new API member.' },
+ { instruction: 'Generate an **API key pair** (public key and private key) for the member.' },
+ { instruction: 'Note your **Company ID** (the company identifier used to log in) and **Site URL** (e.g., na.myconnectwise.net).', tip: 'Create a dedicated API member for ResolutionFlow with minimal permissions for security.' },
+ ],
+ },
+ {
+ title: 'Connecting in ResolutionFlow',
+ steps: [
+ { instruction: 'Go to **Account > Integrations** in ResolutionFlow.' },
+ { instruction: 'Enter a display name, your Site URL, Company ID, Public Key, and Private Key.' },
+ { instruction: 'Click **Connect** to save the connection.' },
+ { instruction: 'Click **Test Connection** to verify everything is working correctly.' },
+ ],
+ },
+ {
+ title: 'Member Mapping',
+ steps: [
+ { instruction: 'After connecting, switch to the **Member Mapping** tab.' },
+ { instruction: 'Click **Auto-Match by Email** to automatically pair ResolutionFlow users with ConnectWise members by email address.' },
+ { instruction: 'Manually adjust any unmatched or incorrectly matched members using the dropdowns.' },
+ { instruction: 'Click **Save Mappings** to apply changes. Mapped members are used when posting session notes to tickets.' },
+ ],
+ },
+ {
+ title: 'What the Integration Enables',
+ steps: [
+ { instruction: 'Session documentation can be posted directly to ConnectWise tickets as internal notes.' },
+ { instruction: 'Ticket context (client info, issue details) can be pulled into sessions for AI-assisted troubleshooting.' },
+ { instruction: 'Posts are attributed to the correct ConnectWise member based on your member mappings.' },
+ ],
+ },
+ ],
+ },
]
diff --git a/frontend/src/pages/MyAnalyticsPage.tsx b/frontend/src/pages/MyAnalyticsPage.tsx
index 28460d55..dfa92ac3 100644
--- a/frontend/src/pages/MyAnalyticsPage.tsx
+++ b/frontend/src/pages/MyAnalyticsPage.tsx
@@ -12,6 +12,7 @@ import {
} from 'recharts'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
+import { AnalyticsIllustration } from '@/components/common/EmptyStateIllustrations'
import { analyticsApi } from '@/api'
import { usePermissions } from '@/hooks/usePermissions'
import type { PersonalAnalyticsResponse, AnalyticsPeriod } from '@/types'
@@ -57,6 +58,7 @@ export default function MyAnalyticsPage() {
return (
+ }
+ title="Track your troubleshooting performance"
+ description="Analytics show resolution times, common paths, and team efficiency. Data appears automatically as you complete sessions."
+ action={
+
+ Run Your First Session
+
+ }
+ learnMoreLink="/guides/analytics"
+ />
+
+ )
+ }
+
const { summary, time_series, top_flows } = data
const outcomeBreakdown = summary.outcome_breakdown
diff --git a/frontend/src/pages/MySharesPage.tsx b/frontend/src/pages/MySharesPage.tsx
index 373ae67d..6feb4fdd 100644
--- a/frontend/src/pages/MySharesPage.tsx
+++ b/frontend/src/pages/MySharesPage.tsx
@@ -1,10 +1,11 @@
import { useState, useEffect, useCallback } from 'react'
import { Link, useNavigate } from 'react-router-dom'
-import { Globe, Users, Copy, Check, Link2, ExternalLink, Trash2, ArrowLeft } from 'lucide-react'
+import { Globe, Users, Copy, Check, ExternalLink, Trash2, ArrowLeft } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
+import { ShareIllustration } from '@/components/common/EmptyStateIllustrations'
import { ConfirmDialog } from '@/components/common/ConfirmDialog'
import { cn } from '@/lib/utils'
import { toast } from '@/lib/toast'
@@ -142,18 +143,17 @@ export default function MySharesPage() {
{/* Empty state */}
{shares.length === 0 ? (
-
- }
- title="No shared sessions"
- description="Share a session from the session detail page to create a link"
- action={
-
- }
- />
-
+ }
+ title="Share session results with your team"
+ description="Create shareable links to completed sessions for knowledge sharing and client communication."
+ action={
+
+ }
+ learnMoreLink="/guides/sharing-exports"
+ />
) : (
{shares.map((share) => {
diff --git a/frontend/src/pages/SessionHistoryPage.tsx b/frontend/src/pages/SessionHistoryPage.tsx
index 49f89560..9a85fb8a 100644
--- a/frontend/src/pages/SessionHistoryPage.tsx
+++ b/frontend/src/pages/SessionHistoryPage.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState, useRef, useCallback } from 'react'
-import { useNavigate, useSearchParams } from 'react-router-dom'
+import { Link, useNavigate, useSearchParams } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
import { sessionsApi } from '@/api/sessions'
import { treesApi } from '@/api/trees'
@@ -9,6 +9,7 @@ import { SessionFilters } from '@/components/session/SessionFilters'
import type { SessionFilterState } from '@/components/session/SessionFilters'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
+import { SessionIllustration } from '@/components/common/EmptyStateIllustrations'
import { cn } from '@/lib/utils'
import { toast } from '@/lib/toast'
import { getSessionResumePath } from '@/lib/routing'
@@ -259,19 +260,32 @@ export function SessionHistoryPage() {
) : sessions.length === 0 ? (
-
Clear all filters
- ) : undefined
- }
- />
+ }
+ />
+ ) : (
+ }
+ title="Your session history will appear here"
+ description="Every troubleshooting session is recorded with decisions, timing, and outcomes — ready for export or review."
+ action={
+
+ Start a Session
+
+ }
+ learnMoreLink="/guides/sessions"
+ />
+ )
) : (
<>
diff --git a/frontend/src/pages/TeamAnalyticsPage.tsx b/frontend/src/pages/TeamAnalyticsPage.tsx
index 48fa4c32..41fc67e6 100644
--- a/frontend/src/pages/TeamAnalyticsPage.tsx
+++ b/frontend/src/pages/TeamAnalyticsPage.tsx
@@ -12,6 +12,7 @@ import {
} from 'recharts'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
+import { AnalyticsIllustration } from '@/components/common/EmptyStateIllustrations'
import { analyticsApi } from '@/api'
import { usePermissions } from '@/hooks/usePermissions'
import { toast } from '@/lib/toast'
@@ -70,6 +71,7 @@ export default function TeamAnalyticsPage() {
return (
+ }
+ title="Track your troubleshooting performance"
+ description="Analytics show resolution times, common paths, and team efficiency. Data appears automatically as you complete sessions."
+ action={
+
+ Run Your First Session
+
+ }
+ learnMoreLink="/guides/analytics"
+ />
+
+ )
+ }
+
const { summary, time_series, top_flows, top_engineers } = data
return (
diff --git a/frontend/src/pages/TreeLibraryPage.tsx b/frontend/src/pages/TreeLibraryPage.tsx
index cb2c5aec..9bafdc97 100644
--- a/frontend/src/pages/TreeLibraryPage.tsx
+++ b/frontend/src/pages/TreeLibraryPage.tsx
@@ -3,6 +3,7 @@ import { useNavigate, useSearchParams } from 'react-router-dom'
import { X, RotateCcw, Play, FileUp } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
+import { FlowIllustration } from '@/components/common/EmptyStateIllustrations'
import { treesApi } from '@/api/trees'
import { categoriesApi } from '@/api/categories'
import { foldersApi } from '@/api/folders'
@@ -496,14 +497,29 @@ export function TreeLibraryPage() {
) : trees.length === 0 ? (
-
+ (searchQuery || hasActiveFilters) ? (
+
+ Clear Filters
+
+ }
+ />
+ ) : (
+ }
+ title="Build your first troubleshooting flow"
+ description="Flows guide your team through proven resolution paths, capturing every decision along the way."
+ action={
+ canCreateTrees ? (
+
+ ) : undefined
+ }
+ learnMoreLink="/guides/creating-flows"
+ />
+ )
) : (
<>
{treeLibraryView === 'grid' && (
diff --git a/frontend/src/pages/account/IntegrationsPage.tsx b/frontend/src/pages/account/IntegrationsPage.tsx
index 7c8d59f1..d0656079 100644
--- a/frontend/src/pages/account/IntegrationsPage.tsx
+++ b/frontend/src/pages/account/IntegrationsPage.tsx
@@ -1,6 +1,8 @@
import { useEffect, useState } from 'react'
import { Plug, CheckCircle2, AlertCircle, Loader2, Pencil, Trash2, Shield, History, Ticket, Users, Zap, Save } from 'lucide-react'
import { analytics } from '@/lib/analytics'
+import { EmptyState } from '@/components/common/EmptyState'
+import { IntegrationIllustration } from '@/components/common/EmptyStateIllustrations'
import { PageMeta } from '@/components/common/PageMeta'
import { integrationsApi } from '@/api/integrations'
import type { PsaConnectionResponse, PsaConnectionCreate, PsaConnectionUpdate, PsaConnectionTestResponse } from '@/types'
@@ -254,6 +256,18 @@ export function IntegrationsPage() {
{/* Connection Tab */}
{activeTab === 'connection' && (
+ {/* Illustrative empty state when no connection exists */}
+ {mode === 'setup' && (
+
+ }
+ title="Connect your PSA for seamless workflows"
+ description="Link ConnectWise or other PSA tools to pull ticket context into sessions and push documentation back automatically."
+ learnMoreLink="/guides/psa-setup"
+ />
+