Components Reference

Complete catalog of all React components in frontend/kundkort/components/.

Source: frontend/kundkort/components/**/*.tsx


Page-Level Components

Appapp.tsx

Props: None (root component)

Purpose: Application entry point. Manages top-level view state (search vs kundkort), auth gating, and URL synchronization.

Key features:

  • Reads ?org= from URL on mount to deep-link to kundkort
  • Handles browser back/forward via popstate
  • Shows inline spinner during auth loading state
  • Renders LoginModal when unauthenticated, SearchPage or KundkortPage when authenticated
  • Mounts ErrorPanel globally (always visible when logged in)

Dependencies: useAuth, LoginModal, SearchPage, KundkortPage, ErrorPanel


SearchPagecomponents/SearchPage.tsx

Props:

interface SearchPageProps {
  token: string;
  onSelect: (orgNr: string, name: string) => void;
  onLogout: () => void;
}

Purpose: Company search landing page. Provides search input, results dropdown, advanced filters, recent searches, and CSV export.

Key features:

  • Debounced search via useSearch (300ms)
  • Results dropdown with company name, org number, legal form, and city
  • Advanced filters: SNI code, city, legal form
  • Recent searches persisted to localStorage (max 5)
  • CSV export of current search results
  • Logout button (top-right)
  • Wordmark branding

Dependencies: useSearch, Footer, formatOrgNr


KundkortPagecomponents/KundkortPage.tsx

Props:

interface KundkortPageProps {
  orgNr: string;
  token: string;
  onBack: () => void;
  onLogout: () => void;
}

Purpose: Full company detail page. The core product view. Organized into three tabs: Overview, Analytics & Graphs, Contacts.

Key features:

  • Sticky action bar with back button, company name, reload, enrich, and PDF export
  • Tab 1 — Overview: Identity card, contact info, summary, financials, koncern, trademarks
  • Tab 2 — Analytics: Gaps panel, insights panel, financial chart, contact distribution, data completeness
  • Tab 3 — Contacts: Full contacts section with distribution chart
  • Advertising block warning banner (GDPR reklamspärr)
  • Enrichment toast with API usage stats (Firecrawl credits, Serper calls, cost)
  • Sources footer with fetch timestamp

Dependencies: useKundkort, useEcoApi, CompanyHeader, all section components, all chart components, Footer, SkeletonLoader, ErrorState


LoginModalcomponents/LoginModal.tsx

Props:

interface LoginModalProps {
  onLogin: (email: string, password: string) => Promise<void>;
}

Purpose: Authentication gate. Email/password form that calls the parent’s onLogin handler.

Key features:

  • Centered card layout with brand wordmark
  • Form validation (required fields)
  • Loading spinner on submit
  • Error display (401 → “Felaktigt e-post eller lösenord”, other → generic)
  • Auto-focus on email input

Dependencies: None


Header & Layout Components

CompanyHeadercomponents/CompanyHeader.tsx

Props:

interface CompanyHeaderProps {
  data: KundkortResponse;
}

Purpose: Kundkort page header. Displays company identity, validation status, and data completeness.

Key features:

  • Avatar with company initials (2 letters, auto-generated)
  • Company name with overflow ellipsis
  • Meta line: org number · city · legal form
  • Status pill: Aktivt/Inaktivt/Okänd with colored dot
  • Lead score badge: Score X.X/10
  • Validation badge: Ej validerad / Delvis validerad / Validerad (based on lead score thresholds)
  • Data completeness progress bar (animated width transition)

Dependencies: formatOrgNr


Props: None

Purpose: Fixed bottom bar showing brand, enrichment usage, and dev mode indicator.

Key features:

  • Polls /api/config every 30 seconds
  • Enrichment counter with progress bar (count/limit)
  • Color-coded usage: green → yellow (≥80%) → red (at limit)
  • DEVMODE badge (red pill) when dev_mode: true
  • Hidden on print (data-no-print)

Dependencies: None


ErrorPanelcomponents/ErrorPanel.tsx

Props:

interface ErrorPanelProps {
  token: string;
}

Purpose: Floating enrichment error monitor. Collapsed as a toggle button; expands to a slide-in panel.

Key features:

  • Fetches /api/enrichment/errors?resolved=false on mount and when opened
  • Toggle button shows error count with ⚠️ icon
  • Slide-in panel (400px, right-side) with error list
  • Each error shows: org number, error type, message, timestamp, retry button
  • Retry triggers /api/kundkort/:orgNr/enrich POST and removes item on success
  • Styled via separate ErrorPanel.css

Dependencies: ErrorPanel.css


Section Components (components/sections/)

IdentityCardcomponents/sections/IdentityCard.tsx

Props:

interface IdentityCardProps {
  data: KundkortResponse;
}

Purpose: Company identity information card.

Key features:

  • Org number (monospace, formatted with dash)
  • Country, status (color-coded), registration date
  • SNI codes with descriptions (up to 3, as badges)
  • Trade names / bifirmas (up to 3)
  • Last enriched date

Dependencies: SectionHeading, KvRow, formatOrgNr


ContactInfoCardcomponents/sections/ContactInfoCard.tsx

Props:

interface ContactInfoCardProps {
  data: KundkortResponse;
}

Purpose: Company contact information card.

Key features:

  • Website (clickable, auto-prepends https://)
  • Phone (clickable tel: link, with source tag)
  • Customer service email (clickable mailto:)
  • Website status: Aktiv/Inaktiv/—
  • Social media icons: Twitter/X, Facebook, Instagram (SVG icons, clickable)

Dependencies: SectionHeading, KvRow


SummarySectioncomponents/sections/SummarySection.tsx

Props:

interface SummarySectionProps {
  data: KundkortResponse;
}

Purpose: AI-generated company summary display.

Key features:

  • Section heading with source tag (e.g., “gpt-4o”)
  • Summary text in readable 14px body copy
  • Fallback: “Ingen beskrivning tillgänglig” in muted italic

Dependencies: SectionHeading


FinancialsSectioncomponents/sections/FinancialsSection.tsx

Props:

interface FinancialsSectionProps {
  data: KundkortResponse;
}

Purpose: Financial history table.

Key features:

  • Sorts finansiell_historik by year ascending
  • Table with columns per year, rows: Antal anställda, Omsättning, Resultat
  • Omsättning/Resultat formatted as Mkr (1 decimal, Swedish locale)
  • Resultat color-coded: red if negative
  • GapBadge shown for missing years or data_gap entries
  • Horizontal scroll on overflow

Dependencies: SectionHeading, GapBadge


ContactsSectioncomponents/sections/ContactsSection.tsx

Props:

interface ContactsSectionProps {
  data: KundkortResponse;
}

Purpose: Contact persons organized by role.

Key features:

  • Iterates CONTACT_ROLE_ORDER (9 roles: VD, Styrelseordförande, Styrelseledamot, Marknadschef, Försäljningschef, HR-chef, Miljöchef, IT-chef, Övriga)
  • Each role has a colored left border and uppercase label
  • Contact count per role
  • Contacts displayed in responsive grid (auto-fill, minmax(200px, 1fr))
  • Empty roles show “Ej identifierad” + GapBadge (except Övriga which is hidden when empty)

Dependencies: SectionHeading, ContactCard, GapBadge, CONTACT_ROLE_ORDER


KoncernSectioncomponents/sections/KoncernSection.tsx

Props:

interface KoncernSectionProps {
  data: KundkortResponse;
}

Purpose: Corporate group structure.

Key features:

  • Shows GapBadge when data unavailable
  • Parent company name + org number (if in group)
  • “Ej del av koncern” when standalone
  • Subsidiary list (up to 5, with “+N till” overflow)

Dependencies: SectionHeading, GapBadge


VarumarkenSectioncomponents/sections/VarumarkenSection.tsx

Props:

interface VarumarkenSectionProps {
  data: KundkortResponse;
}

Purpose: Owned trademarks (from PRV data).

Key features:

  • Shows GapBadge when data unavailable
  • Each trademark: name, status badge (green for “gällande”/“registrerat”), Nice classes
  • Items in raised cards

Dependencies: SectionHeading, GapBadge


UI Primitives (components/ui/)

SectionHeadingcomponents/ui/SectionHeading.tsx

Props:

interface SectionHeadingProps {
  children: React.ReactNode;
}

Purpose: Consistent section title styling. Uppercase, 11px, muted color, letter-spaced.


KvRowcomponents/ui/KvRow.tsx

Props:

interface KvRowProps {
  label: string;
  children: React.ReactNode;
  noBorder?: boolean;
}

Purpose: Key-value row for cards. Label left (uppercase, muted), value right (primary text, right-aligned, break-word).


ContactCardcomponents/ui/ContactCard.tsx

Props:

interface ContactCardProps {
  contact: KundkortContact;
  roleColor: string;
}

Purpose: Individual contact display within ContactsSection.

Key features:

  • Left border colored by role
  • Name (bold), role (muted)
  • Phone with type tag (mobil/fast)
  • Email (ellipsis overflow, title tooltip)
  • “Ingen kontaktinfo” fallback
  • Source tag pill

GapBadgecomponents/ui/GapBadge.tsx

Props: None

Purpose: Visual indicator for missing data. Small “GAP” badge in raised style.


SkeletonLoadercomponents/ui/SkeletonLoader.tsx

Props: None

Purpose: Full-page loading placeholder for KundkortPage.

Key features:

  • Pulsing skeleton blocks matching the actual layout
  • Header, completeness bar, two-column grid, summary, financials, contacts
  • Uses animate-pulse class + CSS custom properties

ErrorStatecomponents/ui/ErrorState.tsx

Props:

interface ErrorStateProps {
  error: string;
  statusCode: number | null;
  orgNr: string;
  onBack: () => void;
  onLogout: () => void;
}

Purpose: Error display for KundkortPage when data fetch fails.

Key features:

  • Status-aware messaging: 401 (re-login), 404 (not found), 5xx (server error), network error
  • Contextual icon and background color
  • “Tillbaka till sökning” link
  • “Logga in igen” button for 401

LoadingCardcomponents/ui/LoadingCard.tsx

Props:

interface LoadingCardProps {
  title: string;
  height?: string; // default: 'h-48'
}

Purpose: Tremor Card wrapper with centered spinner. Used for async chart/data loading states.

Dependencies: Card, Flex, Text (Tremor)


Chart Components (components/ui/)

FinancialChartcomponents/ui/FinancialChart.tsx

Props:

interface FinancialChartProps {
  data: FinancialData; // { years, turnover, employees }
}

Purpose: Financial trend visualization.

Key features:

  • Area chart for turnover (MSEK) if data exists
  • Bar chart for employees as fallback
  • Value formatter: X.X MSEK
  • Animated, with legend and grid lines

Dependencies: Card, Title, AreaChart, BarChart (Tremor)


ContactDistributionChartcomponents/ui/ContactDistributionChart.tsx

Props:

interface ContactDistributionProps {
  distribution: Record<string, number>;
}

Purpose: Contact role distribution visualization.

Key features:

  • Donut chart + vertical bar chart side by side (responsive grid)
  • Role color mapping (VD=blue, Styrelseordförande=violet, etc.)
  • Total count in title
  • Empty state: “Inga kontakter tillgängliga”

Dependencies: Card, Title, DonutChart, BarChart (Tremor)


DataCompletenessChartcomponents/ui/DataCompletenessChart.tsx

Props:

interface DataCompletenessProps {
  overall: number;
  byCategory: Record<string, number>;
}

Purpose: Data completeness breakdown.

Key features:

  • Large metric display for overall percentage (color-coded: ≥75% green, ≥50% yellow, ≥25% orange, <25% red)
  • Donut chart by category
  • Progress bars per category: Grundläggande info, Finansiell data, Kontakter, Digital närvaro

Dependencies: Card, Title, DonutChart, ProgressBar, Flex, Text, Metric (Tremor)


GapsPanelcomponents/ui/GapsPanel.tsx

Props:

interface GapsPanelProps {
  gaps: GapsResponse | null;
  onEnrich: () => void;
  isEnriching: boolean;
}

Purpose: Data gap analysis panel with enrichment CTA.

Key features:

  • Summary: total gaps + high-priority count, or ”✓ All data komplett”
  • “Fyll gap” button (triggers enrichment)
  • Accordion group by priority: Hög / Medel / Låg
  • Each gap: priority badge, field label, “Kan fyllas” badge
  • Field labels mapped to Swedish

Dependencies: Card, Title, Badge, List, ListItem, Flex, Text, Button, Accordion, AccordionHeader, AccordionBody (Tremor)


InsightsPanelcomponents/ui/InsightsPanel.tsx

Props:

interface InsightsPanelProps {
  insights: EcoApiInsights | null;
}

Purpose: Business insights summary.

Key features:

  • Metric cards: Datakompletthet %, total contacts
  • Growth signals list (green ↗)
  • Risk signals list (red ⚠)
  • Fallback: “Inga specifika signaler identifierade ännu.”

Dependencies: Card, Title, Badge, List, ListItem, Flex, Text, Metric, Grid (Tremor)


Component Count

CategoryCountFiles
Page-level4App, SearchPage, KundkortPage, LoginModal
Layout3CompanyHeader, Footer, ErrorPanel
Sections7IdentityCard, ContactInfoCard, SummarySection, FinancialsSection, ContactsSection, KoncernSection, VarumarkenSection
UI primitives6SectionHeading, KvRow, ContactCard, GapBadge, SkeletonLoader, ErrorState, LoadingCard
Charts / Panels5FinancialChart, ContactDistributionChart, DataCompletenessChart, GapsPanel, InsightsPanel
Total25

See also

See also