Spaces:
Sleeping
Sleeping
| import { Component, signal } from '@angular/core'; | |
| import { CommonModule } from '@angular/common'; | |
| import { RouterLink } from '@angular/router'; | |
| import { FormsModule } from '@angular/forms'; | |
| interface DocSection { | |
| id: string; | |
| icon: string; | |
| title: string; | |
| description: string; | |
| articles: { title: string; badge?: string; badgeColor?: string }[]; | |
| } | |
| ({ | |
| selector: 'app-docs', | |
| standalone: true, | |
| imports: [CommonModule, RouterLink, FormsModule], | |
| template: ` | |
| <div class="docs-page"> | |
| <!-- Hero --> | |
| <div class="docs-hero"> | |
| <div class="hero-content"> | |
| <span class="hero-eyebrow">Documentation</span> | |
| <h1>Everything you need to get started</h1> | |
| <p>Guides, references, and tutorials for the MediCode platform.</p> | |
| <!-- Search bar --> | |
| <div class="docs-search"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/> | |
| </svg> | |
| <input | |
| type="text" | |
| placeholder="Search documentation…" | |
| [(ngModel)]="searchQuery" | |
| /> | |
| <kbd>⌘K</kbd> | |
| </div> | |
| </div> | |
| <div class="hero-graphic"> | |
| <div class="graphic-badge badge-icd">ICD-10</div> | |
| <div class="graphic-badge badge-cpt">CPT</div> | |
| <div class="graphic-badge badge-api">REST API</div> | |
| <div class="graphic-ring"></div> | |
| </div> | |
| </div> | |
| <!-- Quick links --> | |
| <div class="quick-links"> | |
| @for (q of quickLinks; track q.title) { | |
| <div class="quick-card" [class]="'quick-' + q.color"> | |
| <div class="quick-icon" [innerHTML]="q.icon"></div> | |
| <div> | |
| <div class="quick-title">{{ q.title }}</div> | |
| <div class="quick-sub">{{ q.sub }}</div> | |
| </div> | |
| <svg class="quick-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M5 12h14M12 5l7 7-7 7"/> | |
| </svg> | |
| </div> | |
| } | |
| </div> | |
| <!-- Main content --> | |
| <div class="docs-body"> | |
| <!-- Sidebar TOC --> | |
| <aside class="docs-toc"> | |
| <div class="toc-title">On this page</div> | |
| @for (s of sections; track s.id) { | |
| <a | |
| class="toc-link" | |
| [class.active]="activeSection() === s.id" | |
| (click)="scrollTo(s.id)" | |
| > | |
| {{ s.title }} | |
| </a> | |
| } | |
| </aside> | |
| <!-- Sections --> | |
| <div class="docs-content"> | |
| @for (s of sections; track s.id) { | |
| <section [id]="s.id" class="doc-section"> | |
| <div class="section-header"> | |
| <div class="section-icon" [innerHTML]="s.icon"></div> | |
| <div> | |
| <h2>{{ s.title }}</h2> | |
| <p>{{ s.description }}</p> | |
| </div> | |
| </div> | |
| <div class="articles-grid"> | |
| @for (a of s.articles; track a.title) { | |
| <div class="article-card"> | |
| <div class="article-top"> | |
| <span class="article-title">{{ a.title }}</span> | |
| @if (a.badge) { | |
| <span class="article-badge" [class]="'badge-' + a.badgeColor">{{ a.badge }}</span> | |
| } | |
| </div> | |
| <svg class="article-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M5 12h14M12 5l7 7-7 7"/> | |
| </svg> | |
| </div> | |
| } | |
| </div> | |
| </section> | |
| } | |
| </div> | |
| </div> | |
| <!-- Help banner --> | |
| <div class="help-banner"> | |
| <div class="help-text"> | |
| <h3>Can't find what you're looking for?</h3> | |
| <p>Our support team is available Monday–Friday, 9am–6pm EST.</p> | |
| </div> | |
| <div class="help-actions"> | |
| <a href="mailto:support@medicode.io" class="btn-outline">✉️ Email Support</a> | |
| <a routerLink="/api" class="btn-primary">View API Docs</a> | |
| </div> | |
| </div> | |
| </div> | |
| `, | |
| styles: [` | |
| .docs-page { | |
| padding: 0; | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| font-family: 'Inter', system-ui, sans-serif; | |
| } | |
| /* ── Hero ──────────────────────────────────────── */ | |
| .docs-hero { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 3rem 2rem 2.5rem; | |
| background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); | |
| border-bottom: 1px solid #bae6fd; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .hero-content { max-width: 540px; } | |
| .hero-eyebrow { | |
| font-size: 0.75rem; | |
| font-weight: 700; | |
| color: #0EA5E9; | |
| text-transform: uppercase; | |
| letter-spacing: 0.1em; | |
| display: block; | |
| margin-bottom: 0.75rem; | |
| } | |
| .docs-hero h1 { | |
| font-size: 2rem; | |
| font-weight: 800; | |
| color: #0f172a; | |
| margin: 0 0 0.75rem; | |
| line-height: 1.2; | |
| letter-spacing: -0.02em; | |
| } | |
| .docs-hero p { | |
| color: #475569; | |
| margin: 0 0 1.5rem; | |
| font-size: 1rem; | |
| } | |
| .docs-search { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| background: white; | |
| border: 1.5px solid #bae6fd; | |
| border-radius: 10px; | |
| padding: 0.75rem 1rem; | |
| max-width: 420px; | |
| box-shadow: 0 1px 3px rgba(0,0,0,0.06); | |
| } | |
| .docs-search svg { width: 18px; height: 18px; color: #94a3b8; flex-shrink: 0; } | |
| .docs-search input { | |
| flex: 1; | |
| border: none; | |
| outline: none; | |
| font-size: 0.9rem; | |
| color: #0f172a; | |
| background: transparent; | |
| } | |
| .docs-search input::placeholder { color: #94a3b8; } | |
| .docs-search kbd { | |
| background: #f1f5f9; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 5px; | |
| font-size: 0.7rem; | |
| color: #64748b; | |
| padding: 0.15rem 0.4rem; | |
| } | |
| /* Decorative graphic */ | |
| .hero-graphic { | |
| position: relative; | |
| width: 200px; | |
| height: 200px; | |
| flex-shrink: 0; | |
| display: none; | |
| } | |
| @media (min-width: 900px) { .hero-graphic { display: block; } } | |
| .graphic-ring { | |
| width: 160px; | |
| height: 160px; | |
| border-radius: 50%; | |
| border: 2px dashed #bae6fd; | |
| position: absolute; | |
| top: 20px; | |
| left: 20px; | |
| animation: spin 20s linear infinite; | |
| } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| .graphic-badge { | |
| position: absolute; | |
| font-size: 0.7rem; | |
| font-weight: 700; | |
| padding: 0.35rem 0.75rem; | |
| border-radius: 99px; | |
| letter-spacing: 0.04em; | |
| } | |
| .badge-icd { background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; top: 20px; left: 30px; } | |
| .badge-cpt { background: #f0fdf4; color: #15803d; border: 1px solid #bbf7d0; bottom: 30px; left: 10px; } | |
| .badge-api { background: #faf5ff; color: #7c3aed; border: 1px solid #ddd6fe; top: 50%; right: 0; transform: translateY(-50%); } | |
| /* ── Quick links ───────────────────────────────── */ | |
| .quick-links { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); | |
| gap: 1rem; | |
| padding: 2rem 2rem 0; | |
| } | |
| .quick-card { | |
| display: flex; | |
| align-items: center; | |
| gap: 1rem; | |
| padding: 1.1rem 1.25rem; | |
| border-radius: 12px; | |
| border: 1px solid #e2e8f0; | |
| background: white; | |
| cursor: pointer; | |
| transition: all 0.15s; | |
| } | |
| .quick-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); } | |
| .quick-icon { | |
| width: 38px; | |
| height: 38px; | |
| border-radius: 9px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| } | |
| .quick-icon :deep(svg) { width: 20px; height: 20px; } | |
| .quick-blue .quick-icon { background: #eff6ff; color: #3b82f6; } | |
| .quick-green .quick-icon { background: #f0fdf4; color: #10b981; } | |
| .quick-purple .quick-icon { background: #faf5ff; color: #8b5cf6; } | |
| .quick-sky .quick-icon { background: #f0f9ff; color: #0EA5E9; } | |
| .quick-title { font-size: 0.9rem; font-weight: 600; color: #0f172a; } | |
| .quick-sub { font-size: 0.78rem; color: #64748b; margin-top: 0.15rem; } | |
| .quick-arrow { width: 16px; height: 16px; color: #94a3b8; margin-left: auto; flex-shrink: 0; } | |
| /* ── Body layout ───────────────────────────────── */ | |
| .docs-body { | |
| display: grid; | |
| grid-template-columns: 220px 1fr; | |
| gap: 2rem; | |
| padding: 2rem; | |
| align-items: start; | |
| } | |
| /* TOC */ | |
| .docs-toc { | |
| position: sticky; | |
| top: 1.5rem; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.25rem; | |
| } | |
| .toc-title { | |
| font-size: 0.7rem; | |
| font-weight: 700; | |
| color: #94a3b8; | |
| text-transform: uppercase; | |
| letter-spacing: 0.1em; | |
| margin-bottom: 0.5rem; | |
| } | |
| .toc-link { | |
| font-size: 0.85rem; | |
| color: #64748b; | |
| cursor: pointer; | |
| padding: 0.35rem 0.75rem; | |
| border-radius: 6px; | |
| border-left: 2px solid transparent; | |
| transition: all 0.12s; | |
| } | |
| .toc-link:hover { color: #0EA5E9; background: #f0f9ff; } | |
| .toc-link.active { color: #0EA5E9; border-left-color: #0EA5E9; background: #f0f9ff; font-weight: 600; } | |
| /* Sections */ | |
| .docs-content { display: flex; flex-direction: column; gap: 2.5rem; } | |
| .doc-section { scroll-margin-top: 1.5rem; } | |
| .section-header { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 1rem; | |
| margin-bottom: 1.25rem; | |
| } | |
| .section-icon { | |
| width: 44px; | |
| height: 44px; | |
| border-radius: 10px; | |
| background: #f0f9ff; | |
| color: #0EA5E9; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| } | |
| .section-icon :deep(svg) { width: 22px; height: 22px; } | |
| .section-header h2 { | |
| font-size: 1.1rem; | |
| font-weight: 700; | |
| color: #0f172a; | |
| margin: 0 0 0.25rem; | |
| } | |
| .section-header p { | |
| font-size: 0.85rem; | |
| color: #64748b; | |
| margin: 0; | |
| } | |
| .articles-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); | |
| gap: 0.75rem; | |
| } | |
| .article-card { | |
| background: white; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 10px; | |
| padding: 1rem 1.1rem; | |
| cursor: pointer; | |
| transition: all 0.15s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 0.75rem; | |
| } | |
| .article-card:hover { | |
| border-color: #0EA5E9; | |
| box-shadow: 0 0 0 3px rgba(14,165,233,0.08); | |
| } | |
| .article-top { display: flex; flex-direction: column; gap: 0.35rem; } | |
| .article-title { font-size: 0.875rem; font-weight: 600; color: #1e293b; } | |
| .article-badge { | |
| font-size: 0.65rem; | |
| font-weight: 700; | |
| padding: 0.15rem 0.45rem; | |
| border-radius: 99px; | |
| width: fit-content; | |
| } | |
| .badge-green { background: #f0fdf4; color: #15803d; border: 1px solid #bbf7d0; } | |
| .badge-blue { background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; } | |
| .badge-sky { background: #f0f9ff; color: #0369a1; border: 1px solid #bae6fd; } | |
| .badge-purple{ background: #faf5ff; color: #7c3aed; border: 1px solid #ddd6fe; } | |
| .article-arrow { width: 15px; height: 15px; color: #cbd5e1; flex-shrink: 0; transition: color 0.15s; } | |
| .article-card:hover .article-arrow { color: #0EA5E9; } | |
| /* ── Help banner ───────────────────────────────── */ | |
| .help-banner { | |
| margin: 0 2rem 2rem; | |
| background: linear-gradient(135deg, #0f172a 0%, #1e3a5f 100%); | |
| border-radius: 14px; | |
| padding: 2rem 2.5rem; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 2rem; | |
| flex-wrap: wrap; | |
| } | |
| .help-banner h3 { font-size: 1.1rem; font-weight: 700; color: #f8fafc; margin: 0 0 0.35rem; } | |
| .help-banner p { font-size: 0.875rem; color: #94a3b8; margin: 0; } | |
| .help-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; } | |
| .btn-primary { | |
| padding: 0.65rem 1.25rem; | |
| background: #0EA5E9; | |
| color: white; | |
| border-radius: 8px; | |
| font-weight: 600; | |
| font-size: 0.875rem; | |
| text-decoration: none; | |
| transition: background 0.15s; | |
| } | |
| .btn-primary:hover { background: #0284c7; } | |
| .btn-outline { | |
| padding: 0.65rem 1.25rem; | |
| background: transparent; | |
| color: #cbd5e1; | |
| border: 1px solid #334155; | |
| border-radius: 8px; | |
| font-weight: 600; | |
| font-size: 0.875rem; | |
| text-decoration: none; | |
| transition: all 0.15s; | |
| } | |
| .btn-outline:hover { border-color: #94a3b8; color: #f1f5f9; } | |
| @media (max-width: 900px) { | |
| .docs-body { grid-template-columns: 1fr; } | |
| .docs-toc { display: none; } | |
| } | |
| `], | |
| }) | |
| export class DocsComponent { | |
| searchQuery = ''; | |
| activeSection = signal('getting-started'); | |
| scrollTo(id: string) { | |
| this.activeSection.set(id); | |
| document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }); | |
| } | |
| quickLinks = [ | |
| { | |
| title: 'Getting Started', | |
| sub: '5-minute setup guide', | |
| color: 'blue', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>`, | |
| }, | |
| { | |
| title: 'ICD-10 Reference', | |
| sub: 'Diagnostic code lookup', | |
| color: 'green', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>`, | |
| }, | |
| { | |
| title: 'CPT Codes', | |
| sub: 'Procedure coding guide', | |
| color: 'purple', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>`, | |
| }, | |
| { | |
| title: 'API Reference', | |
| sub: 'REST endpoints & auth', | |
| color: 'sky', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`, | |
| }, | |
| ]; | |
| sections: DocSection[] = [ | |
| { | |
| id: 'getting-started', | |
| title: 'Getting Started', | |
| description: 'Everything you need to set up and configure MediCode for your practice.', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>`, | |
| articles: [ | |
| { title: 'Platform Overview', badge: 'Start here', badgeColor: 'green' }, | |
| { title: 'Creating Your Account' }, | |
| { title: 'Roles & Permissions', badge: 'Admin', badgeColor: 'purple' }, | |
| { title: 'Onboarding Checklist' }, | |
| ], | |
| }, | |
| { | |
| id: 'patients', | |
| title: 'Patient Management', | |
| description: 'How to create, update, and manage patient records and encounters.', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>`, | |
| articles: [ | |
| { title: 'Adding a New Patient' }, | |
| { title: 'Encounter Workflow', badge: 'Core', badgeColor: 'blue' }, | |
| { title: 'Attaching ICD-10 Codes' }, | |
| { title: 'Attaching CPT Codes' }, | |
| { title: 'Billing Status Lifecycle' }, | |
| { title: 'Exporting Patient Data' }, | |
| ], | |
| }, | |
| { | |
| id: 'coding', | |
| title: 'Medical Coding', | |
| description: 'Reference guides for ICD-10-CM diagnostic codes and CPT procedure codes.', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>`, | |
| articles: [ | |
| { title: 'ICD-10-CM Structure', badge: 'ICD-10', badgeColor: 'blue' }, | |
| { title: 'CPT Code Categories', badge: 'CPT', badgeColor: 'green' }, | |
| { title: 'Code Search Tips' }, | |
| { title: 'Modifier Usage' }, | |
| ], | |
| }, | |
| { | |
| id: 'reports', | |
| title: 'Reports & Analytics', | |
| description: 'Generate, filter, and export reports for your coding activity.', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 3v18h18"/><path d="m19 9-5 5-4-4-3 3"/></svg>`, | |
| articles: [ | |
| { title: 'Encounters by Month' }, | |
| { title: 'Top Diagnoses Report' }, | |
| { title: 'Export to PDF', badge: 'PDF', badgeColor: 'sky' }, | |
| { title: 'Export to Excel', badge: 'Excel', badgeColor: 'green' }, | |
| ], | |
| }, | |
| { | |
| id: 'api', | |
| title: 'API Integration', | |
| description: 'Integrate MediCode with your existing systems via our REST API.', | |
| icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`, | |
| articles: [ | |
| { title: 'Authentication & JWT', badge: 'Auth', badgeColor: 'purple' }, | |
| { title: 'Patients Endpoints' }, | |
| { title: 'Codes Endpoints' }, | |
| { title: 'Webhooks' }, | |
| ], | |
| }, | |
| ]; | |
| } |