Přeskočit obsah

🏆 TOP 3 NEJPROPRACOVANĚJŠÍ ENTERPRISE ŘEŠENÍ

Datum: 2025-12-08 Cíl: Maximálně profesionální dashboard pro 2.5M kontaktů + GPS + AML


🥇 #1: TABLEAU + SALESFORCE (Nejlepší celkově)

💰 Cena: $70-145/user/měsíc

⭐ Proč je to nejlepší:

Tableau je absolutní král vizualizace dat: - ✅ Nejkrásnější grafy na světě (Hollywood používá Tableau pro data viz) - ✅ Drag & drop bez kódu - ✅ AI-powered insights (Ask Data - ptej se anglicky) - ✅ Real-time dashboards s auto-refresh - ✅ Mobile apps (iOS/Android native) - ✅ Sdílení: Public/Private/Embedded - ✅ Enterprise features: SSO, row-level security, audit logs

📊 Co dostaneš pro AML Platform:

TABLEAU DASHBOARD:
┌────────────────────────────────────────────────────────────┐
│  AML PLATFORM - Executive Dashboard                        │
├────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐      │
│  │ 2.5M    │  │ 99.95%  │  │ 1.5M    │  │ $1.2M   │      │
│  │Contacts │  │ Phone   │  │Geocoded │  │ Revenue │      │
│  │ ▲ 5.2%  │  │ ▲ 0.3%  │  │ ▲ 15%   │  │ ▲ 8.1%  │      │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘      │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  📍 GEOGRAPHIC HEATMAP (Interactive)                 │ │
│  │  ┌────────────────────────────────────────────────┐ │ │
│  │  │                                                 │ │ │
│  │  │   [Tableau Map Layers]                         │ │ │
│  │  │   • Density heatmap (gradient colors)          │ │ │
│  │  │   • Risk zones (red/yellow/green)              │ │ │
│  │  │   • City boundaries                            │ │ │
│  │  │   • Custom territories                         │ │ │
│  │  │   • Flow maps (relationship networks)          │ │ │
│  │  │   • 3D extrusions (building heights)           │ │ │
│  │  │                                                 │ │ │
│  │  │   Interactions:                                │ │ │
│  │  │   - Hover → Tooltip with details              │ │ │
│  │  │   - Click → Drill-down to contacts            │ │ │
│  │  │   - Lasso select → Bulk actions               │ │ │
│  │  │   - Filter by: City, Risk, Date, Status       │ │ │
│  │  │                                                 │ │ │
│  │  └────────────────────────────────────────────────┘ │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌─────────────────────┬──────────────────────────────┐   │
│  │ RISK ANALYSIS       │  TREND ANALYSIS              │   │
│  │ ┌─────────────────┐ │  ┌────────────────────────┐ │   │
│  │ │ [Sankey Diagram]│ │  │ [Time Series Line]     │ │   │
│  │ │                 │ │  │                        │ │   │
│  │ │ Contacts →      │ │  │ Contact Growth         │ │   │
│  │ │   → Low Risk    │ │  │ GPS Coverage %         │ │   │
│  │ │   → Medium      │ │  │ AML Checks             │ │   │
│  │ │   → High        │ │  │ Revenue                │ │   │
│  │ │   → Critical    │ │  │                        │ │   │
│  │ └─────────────────┘ │  └────────────────────────┘ │   │
│  └─────────────────────┴──────────────────────────────┘   │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  TOP INSIGHTS (AI-Powered)                           │ │
│  │  🤖 "60% increase in Prague contacts this quarter"  │ │
│  │  🤖 "High-risk contacts concentrated in Ostrava"    │ │
│  │  🤖 "Email coverage improved by 5% this month"      │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  INTERACTIVE DATA TABLE (Smart)                       │ │
│  │  [Filter] [Sort] [Search] [Export] [Bulk Actions]    │ │
│  │  ┌────┬──────────┬──────────┬──────┬──────┬────────┐ │ │
│  │  │ ID │ Name     │ Phone    │ City │ Risk │ Action │ │ │
│  │  ├────┼──────────┼──────────┼──────┼──────┼────────┤ │ │
│  │  │123 │Jan Novák │+420608.. │Praha │ 🟢   │ [View] │ │ │
│  │  │... │          │          │      │      │        │ │ │
│  │  └────┴──────────┴──────────┴──────┴──────┴────────┘ │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
└────────────────────────────────────────────────────────────┘

[Ask Data]: "Show me high-risk contacts in Prague with insolvency"
            → Tableau AI automatically creates visualization!

🎨 Unikátní Features Tableau:

  1. Ask Data (Natural Language)

    You: "Which cities have the most high-risk contacts?"
    Tableau: [Automatically creates bar chart]
    
    You: "Show trend of GPS coverage over time"
    Tableau: [Creates line chart with annotations]
    

  2. Smart Recommendations

  3. Tableau navrhne nejlepší typ grafu pro tvá data
  4. "Try this visualization instead" suggestions
  5. Auto-formatting (colors, labels, legends)

  6. Story Points

  7. Vytvoř prezentaci z dashboardů
  8. Kliknutelné slides s animacemi
  9. Perfect pro board meetings

  10. Data Blending

  11. Kombinuj MASTER_CONTACTS + ARES + RUIAN
  12. Join přes UI (bez SQL)
  13. Live connections

  14. Alerts & Subscriptions

    Alert: "Notify me when high-risk contacts > 100 in Praha"
    Email: Daily snapshot of dashboard
    Slack: Post KPIs to #aml-team
    

📦 Setup (1 týden):

Day 1-2: Tableau Desktop setup

1. Download Tableau Desktop ($70/měsíc)
2. Connect to MASTER_CONTACTS.db (SQLite connector)
3. Import všechny tabulky
4. Create relationships (data model)

Day 3-4: Build dashboards

5. Drag lat/lon → Map
6. Add filters (City, Risk, Date)
7. Create calculated fields (risk_score, completeness)
8. Build KPI cards
9. Add trend charts
10. Design interactivity (click actions)

Day 5: Styling & Polish

11. Apply corporate colors
12. Add logo & branding
13. Configure tooltips
14. Set up alerts

Day 6-7: Deploy & Share

15. Publish to Tableau Server/Cloud
16. Set permissions (who can see what)
17. Embed in web app (iframe)
18. Setup mobile app

💡 Advanced Use Cases:

1. Predictive Analytics

Forecast: Next quarter contact growth
Trend Lines: Linear/Exponential/Polynomial
Confidence Intervals: 95% bands

2. Cohort Analysis

Group contacts by:
- Acquisition date
- Geography
- Risk level
Track retention over time

3. Network Graph

Visualize:
- Person → Companies
- Companies → Shareholders
- UBO structures
Interactive force-directed layout

4. Geographic Routing

Optimize sales routes:
- Starting point
- Visit contacts
- Minimize distance
Show on map with path

💰 Pricing:

Tier Price Features
Tableau Creator $70/user/měsíc Desktop + Server access
Tableau Explorer $42/user/měsíc View & edit existing
Tableau Viewer $15/user/měsíc View only

For you: 1 Creator ($70) + 10 Viewers ($150) = $220/měsíc

✅ Doporučení:

PRO: - ⭐⭐⭐⭐⭐ Nejlepší vizualizace - ⭐⭐⭐⭐⭐ Enterprise features - ⭐⭐⭐⭐⭐ Škálovatelnost - ⭐⭐⭐⭐ Snadnost použití

CON: - 💰 Nejdražší - 📚 Learning curve (1-2 týdny)

Verdict:Best for enterprise, impresivní pro klienty


🥈 #2: POWER BI + AZURE (Microsoft Ekosystém)

💰 Cena: $10-20/user/měsíc

⭐ Proč je skvělý:

Microsoft Power BI: - ✅ Nejlevnější enterprise řešení - ✅ Tight integration s Office 365 (Excel, Teams, SharePoint) - ✅ AI insights (Quick Insights, Q&A visual) - ✅ DAX language (pokročilé výpočty) - ✅ Custom visuals (1000+ v marketplace) - ✅ Real-time streaming (live dashboards) - ✅ Mobile apps (iOS/Android)

📊 Co dostaneš:

POWER BI DASHBOARD:
┌────────────────────────────────────────────────────────────┐
│  🔍 AML Platform - Power BI                                │
├────────────────────────────────────────────────────────────┤
│                                                             │
│  [Filter Pane]              [Report Canvas]                │
│  ┌──────────────┐           ┌──────────────────────────┐  │
│  │ Filters:     │           │  📊 KPI CARDS            │  │
│  │ ☑ Praha      │           │  ┌────┐ ┌────┐ ┌────┐   │  │
│  │ ☑ Brno       │           │  │2.5M│ │99% │ │1.5M│   │  │
│  │ ☐ Ostrava    │           │  └────┘ └────┘ └────┘   │  │
│  │              │           └──────────────────────────┘  │
│  │ Risk Level:  │                                          │
│  │ ◉ All        │           ┌──────────────────────────┐  │
│  │ ○ High only  │           │  🗺️ AZURE MAPS          │  │
│  │              │           │  ┌────────────────────┐  │  │
│  │ Date Range:  │           │  │ [Interactive Map]  │  │  │
│  │ [▓▓▓▓░░░░░] │           │  │                    │  │  │
│  │ 2024-01-01   │           │  │ • Bubble map       │  │  │
│  │ 2024-12-08   │           │  │ • Heat layers      │  │  │
│  │              │           │  │ • Custom markers   │  │  │
│  └──────────────┘           │  │ • Traffic layer    │  │  │
│                              │  │ • Weather overlay  │  │  │
│  [Bookmarks]                │  └────────────────────┘  │  │
│  • Overview                 └──────────────────────────┘  │
│  • Geographic                                             │
│  • Risk Analysis            ┌──────────────────────────┐  │
│  • Trends                   │  📈 CHARTS               │  │
│  • Custom View 1            │  [Column] [Line] [Pie]   │  │
│                              │  [Waterfall] [Funnel]    │  │
│                              └──────────────────────────┘  │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  Q&A Visual (Ask in Czech!)                          │ │
│  │  [Kolik máme kontaktů v Praze s vysokým rizikem?]    │ │
│  │  → Power BI: [Bar chart appears]                     │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
└────────────────────────────────────────────────────────────┘

🎨 Unikátní Features Power BI:

  1. Q&A Visual (Czech language!)

    "Zobraz top 10 měst podle počtu kontaktů"
    "Jaký je průměrný risk score v Praze?"
    "Porovnej Brno a Ostravu"
    

  2. Quick Insights (AI)

  3. Auto-discover patterns
  4. Outlier detection
  5. Trend analysis
  6. Correlation finder

  7. DAX Formulas (Excel-like)

    High_Risk_Count =
    CALCULATE(
        COUNT(Contacts[ID]),
        Contacts[Risk_Level] = "HIGH"
    )
    
    GPS_Coverage% =
    DIVIDE(
        COUNTROWS(FILTER(Contacts, Contacts[lat] <> BLANK())),
        COUNTROWS(Contacts)
    )
    

  8. Integration s Microsoft ekosystémem

    Teams: Embed dashboard v Teams channel
    Excel: Export to Excel with live connection
    SharePoint: Publish dashboards
    Outlook: Schedule email reports
    Power Automate: Trigger workflows on data changes
    

  9. Streaming Datasets

    // Real-time updates každou sekundu
    var client = new PowerBIClient();
    await client.Datasets.PostRowsAsync(
        groupId: "xxx",
        datasetId: "yyy",
        tableName: "contacts",
        rows: newContacts
    );
    

📦 Setup (3-5 dní):

Day 1: Power BI Desktop

1. Download Power BI Desktop (FREE)
2. Get Data → SQLite → MASTER_CONTACTS.db
3. Transform data (Power Query)
4. Create data model (relationships)

Day 2-3: Build Reports

5. Insert visuals (drag & drop)
6. Configure Azure Maps visual
7. Create DAX measures
8. Design pages (Overview, Map, Analytics)
9. Add slicers (filters)
10. Configure interactions

Day 4: Publish & Share

11. Publish to Power BI Service
12. Create workspace
13. Set permissions
14. Schedule data refresh (každou hodinu)
15. Embed v web app

Day 5: Advanced Features

16. Setup row-level security
17. Create mobile layout
18. Configure alerts
19. Setup paginated reports (PDF export)

💡 Advanced Features:

1. Paginated Reports

Perfect for PDF exports:
- Contact list s custom formatting
- AML screening reports
- Compliance documents
- Invoice-style layouts

2. Dataflows

ETL v cloudu:
- Schedule MASTER_CONTACTS refresh
- Join with ARES, RUIAN
- Clean & transform
- Store in Azure Data Lake

3. Power BI Embedded

// Embed v tvé React app
import { PowerBIEmbed } from 'powerbi-client-react';

<PowerBIEmbed
  embedConfig={{
    type: 'report',
    id: 'your-report-id',
    embedUrl: 'https://...',
    accessToken: token
  }}
  cssClassName="report-container"
/>

4. Composite Models

Combine:
- MASTER_CONTACTS (Import)
- ARES (DirectQuery)
- Azure SQL (Live)
Best of both worlds

💰 Pricing:

Tier Price Features
Power BI Desktop FREE Authoring tool
Power BI Pro $10/user/měsíc Share & collaborate
Power BI Premium $20/user/měsíc Paginated reports, AI
Power BI Embedded $1/hodina For ISVs (white-label)

For you: 1 Pro ($10) + Power BI Embedded ($100/měsíc) = $110/měsíc

✅ Doporučení:

PRO: - ⭐⭐⭐⭐⭐ Cena/výkon nejlepší - ⭐⭐⭐⭐ Office 365 integrace - ⭐⭐⭐⭐ Snadnost (pokud znáš Excel) - ⭐⭐⭐⭐ Azure Maps (skvělé pro ČR)

CON: - ⭐⭐⭐ Vizualizace (ne tak pěkné jako Tableau) - ⭐⭐⭐ Desktop app (ne web-based authoring)

Verdict:Best value for money, perfect pokud používáš Microsoft


🥉 #3: LOOKER (Google Cloud) - Data Modeling Beast

💰 Cena: Custom (cca $3,000-5,000/měsíc)

⭐ Proč je unikátní:

Looker (now part of Google Cloud): - ✅ LookML: vlastní modeling language (git-based) - ✅ Single source of truth: jeden data model pro všechny - ✅ Embedded analytics: white-label pro klienty - ✅ API-first: vše má API endpoint - ✅ Version control: Git integration pro všechno - ✅ Google BigQuery integration: lightning fast - ✅ Custom visualizations: D3.js based

📊 Co dostaneš:

LOOKER DASHBOARD:
┌────────────────────────────────────────────────────────────┐
│  AML Platform Analytics                      [Admin] [API] │
├────────────────────────────────────────────────────────────┤
│                                                             │
│  [Explore: Contacts]                                        │
│                                                             │
│  Dimensions:                   Measures:                    │
│  ☑ ID                         ☑ Count                      │
│  ☑ Full Name                  ☑ Count Distinct             │
│  ☑ City                       ☑ Average Risk Score         │
│  ☑ Risk Level                 ☑ GPS Coverage %             │
│                                                             │
│  Filters:                                                   │
│  City is [Praha, Brno]                                     │
│  Risk Level is not [NONE]                                  │
│  Created Date is in the last 30 days                       │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  📊 VISUALIZATION                                     │ │
│  │  [Table] [Chart] [Map] [Single Value] [Custom]       │ │
│  │                                                       │ │
│  │  City      | Count  | Avg Risk | GPS %              │ │
│  │  ──────────────────────────────────────────────      │ │
│  │  Praha     | 140K   | 25       | 65%                │ │
│  │  Brno      | 50K    | 18       | 58%                │ │
│  │  Ostrava   | 74K    | 32       | 62%                │ │
│  │                                                       │ │
│  │  [+ Add to Dashboard] [Schedule] [Download] [API]    │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  🗺️ GOOGLE MAPS INTEGRATION                          │ │
│  │  ┌────────────────────────────────────────────────┐ │ │
│  │  │                                                 │ │ │
│  │  │   [Google Maps with custom layers]             │ │ │
│  │  │                                                 │ │ │
│  │  │   • BigQuery GIS integration                   │ │ │
│  │  │   • Sub-second query times                     │ │ │
│  │  │   • Millions of points                         │ │ │
│  │  │   • Custom styling (Mapbox GL style)           │ │ │
│  │  │                                                 │ │ │
│  │  └────────────────────────────────────────────────┘ │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
└────────────────────────────────────────────────────────────┘

🎨 Unikátní Features Looker:

  1. LookML (Data Modeling Language)

    # contacts.model.lkml
    
    view: contacts {
      sql_table_name: MASTER_CONTACTS ;;
    
      dimension: id {
        primary_key: yes
        type: number
        sql: ${TABLE}.id ;;
      }
    
      dimension: full_name {
        type: string
        sql: ${TABLE}.full_name ;;
      }
    
      dimension: city {
        type: string
        sql: ${TABLE}.city ;;
        drill_fields: [full_name, phone, risk_level]
      }
    
      dimension: location {
        type: location
        sql_latitude: ${TABLE}.lat ;;
        sql_longitude: ${TABLE}.lon ;;
      }
    
      dimension: risk_level {
        type: string
        sql:
          CASE
            WHEN ${risk_score} >= 50 THEN 'CRITICAL'
            WHEN ${risk_score} >= 30 THEN 'HIGH'
            WHEN ${risk_score} >= 15 THEN 'MEDIUM'
            ELSE 'LOW'
          END ;;
      }
    
      measure: count {
        type: count
        drill_fields: [detail*]
      }
    
      measure: gps_coverage_pct {
        type: number
        sql: 100.0 * ${count_with_gps} / ${count} ;;
        value_format: "0.00\"%\""
      }
    }
    

  2. Git-Based Development

    # LookML je v gitu!
    git clone looker-project
    cd lookml
    code contacts.model.lkml
    git commit -m "Add risk_level dimension"
    git push
    # Auto-deploy to production
    

  3. API-First Architecture

    # Každý Looker query má API endpoint!
    import looker_sdk
    
    sdk = looker_sdk.init40()
    
    # Run query
    result = sdk.run_inline_query(
        result_format="json",
        body={
            "model": "aml_platform",
            "view": "contacts",
            "fields": ["contacts.city", "contacts.count"],
            "filters": {"contacts.risk_level": "HIGH"}
        }
    )
    
    # Use in your app
    print(result)
    

  4. Embedded Analytics (White-Label)

    <!-- Embed Looker v tvé app -->
    <iframe
      src="https://your-instance.looker.com/embed/dashboards/123?
           embed_domain=https://your-domain.com&
           theme=custom"
      width="100%"
      height="800px"
    ></iframe>
    
    <!-- Looks like tvá app, not Looker -->
    

  5. Actions (Automation)

    # Send Slack notification when high-risk contact appears
    action: {
      label: "Send to Slack"
      url: "https://hooks.slack.com/..."
      form_param: {
        name: "Message"
        type: textarea
        default: "New high-risk contact: {{ contacts.full_name._value }}"
      }
    }
    
    # Trigger webhook
    action: {
      label: "Start AML Check"
      url: "https://your-api.com/aml/check"
      param: {
        name: "contact_id"
        value: "{{ contacts.id._value }}"
      }
    }
    

📦 Setup (2-3 týdny):

Week 1: Infrastructure

1. Setup Google Cloud Project
2. Upload MASTER_CONTACTS to BigQuery
3. Provision Looker instance
4. Connect Looker → BigQuery

Week 2: LookML Development

5. Create LookML project (git)
6. Define views (contacts, companies, addresses)
7. Create explores (how views connect)
8. Add derived tables (risk calculations)
9. Write reusable measures
10. Test & validate

Week 3: Dashboards & Deployment

11. Build dashboards (drag & drop)
12. Create Looks (saved queries)
13. Setup schedules (email reports)
14. Configure embed (white-label)
15. Deploy to production

💡 Advanced Features:

1. BigQuery ML Integration

# Train ML model v BigQuery
CREATE OR REPLACE MODEL `aml.risk_prediction`
OPTIONS(model_type='logistic_reg') AS
SELECT
  * EXCEPT(id, full_name),
  CASE WHEN insolvency THEN 1 ELSE 0 END as label
FROM contacts;

# Use v Looker
SELECT
  *,
  ML.PREDICT(MODEL `aml.risk_prediction`,
             TABLE contacts) as predicted_risk

2. Data Actions

Right-click any row → Actions:
- Send to Salesforce
- Create Jira ticket
- Start workflow
- Export to Google Sheets

3. Persistent Derived Tables (PDT)

# Cache expensive queries
derived_table: {
  sql:
    SELECT
      city,
      COUNT(*) as contact_count,
      AVG(risk_score) as avg_risk
    FROM contacts
    GROUP BY 1 ;;

  persist_for: "1 hour"
  indexes: ["city"]
}

💰 Pricing:

Tier Price Features
Looker Platform $3,000-5,000/měsíc Base platform
Additional users Included Unlimited viewers
Embed Included White-label embedding
API Included Full API access

For you: $3,500/měsíc (flat fee, unlimited users!)

✅ Doporučení:

PRO: - ⭐⭐⭐⭐⭐ Data modeling (nejlepší) - ⭐⭐⭐⭐⭐ API-first - ⭐⭐⭐⭐⭐ Embedded analytics - ⭐⭐⭐⭐⭐ Git-based (version control) - ⭐⭐⭐⭐ Google Cloud integration

CON: - 💰💰 Velmi drahé - 📚 Steep learning curve (LookML) - 🕐 Long setup time (2-3 týdny)

Verdict:Best for ISVs & embedding, overkill pro internal use


🏆 BONUS #4: CUSTOM NEXT.JS + SHADCN + RECHARTS (Nejmodernější)

💰 Cena: FREE (jen čas vývoje)

⭐ Proč je unikátní:

Modern Web Stack: - ✅ Next.js 14: React framework s Server Components - ✅ Shadcn/ui: Nejkrásnější component library (Tailwind CSS) - ✅ Recharts: Responsive charts - ✅ Mapbox GL JS: Professional maps - ✅ Framer Motion: Smooth animations - ✅ React Query: Data fetching - ✅ Zustand: State management

📊 Co dostaneš (buildnu ti to!):

// app/dashboard/page.tsx
import { Suspense } from 'react';
import { KPICards } from '@/components/kpi-cards';
import { InteractiveMap } from '@/components/interactive-map';
import { ContactsTable } from '@/components/contacts-table';
import { AnalyticsCharts } from '@/components/analytics-charts';

export default function DashboardPage() {
  return (
    <div className="container mx-auto p-6 space-y-6">
      {/* KPI Cards */}
      <Suspense fallback={<KPICardsSkeleton />}>
        <KPICards />
      </Suspense>

      {/* Interactive Map */}
      <Card>
        <CardHeader>
          <CardTitle>Geographic Distribution</CardTitle>
        </CardHeader>
        <CardContent>
          <InteractiveMap />
        </CardContent>
      </Card>

      {/* Charts */}
      <div className="grid grid-cols-2 gap-6">
        <TopCitiesChart />
        <RiskDistributionChart />
        <TrendChart />
        <CoverageChart />
      </div>

      {/* Contacts Table */}
      <ContactsTable />
    </div>
  );
}

🎨 Co to bude vypadat:

MODERN DASHBOARD (Shadcn/ui style):
┌────────────────────────────────────────────────────────────┐
│  ☰  AML Platform            🔍 Search      👤 User   [⚙️] │
├────────────────────────────────────────────────────────────┤
│                                                             │
│  Dashboard > Overview                          [Filters ▼] │
│                                                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │
│  │ 📊          │  │ 📞          │  │ 🗺️          │       │
│  │ 2,529,097   │  │ 99.95%      │  │ 1.5M        │       │
│  │ Contacts    │  │ Phone       │  │ Geocoded    │       │
│  │ ↗ +5.2%     │  │ ↗ +0.3%     │  │ ↗ +15%      │       │
│  │ vs last mo  │  │ vs last mo  │  │ vs last mo  │       │
│  └─────────────┘  └─────────────┘  └─────────────┘       │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  🗺️ Interactive Map                     [3D] [Heat]  │ │
│  │  ┌────────────────────────────────────────────────┐ │ │
│  │  │                                                 │ │ │
│  │  │   Mapbox GL with:                              │ │ │
│  │  │   • Smooth animations (Framer Motion)          │ │ │
│  │  │   • Click → Drawer with contact details        │ │ │
│  │  │   • Lasso select tool                          │ │ │
│  │  │   • Layers: Heatmap, Clusters, Points          │ │ │
│  │  │   • Real-time updates (React Query)            │ │ │
│  │  │                                                 │ │ │
│  │  └────────────────────────────────────────────────┘ │ │
│  │  [🎨 Styles: Dark, Light, Custom]                  │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌─────────────────────┬──────────────────────────────┐   │
│  │ 📊 Top Cities       │  📈 Risk Trends              │   │
│  │ [Recharts Bar]      │  [Recharts Line with Area]   │   │
│  │ Interactive         │  Smooth animations           │   │
│  │ Hover tooltips      │  Zoom & pan                  │   │
│  └─────────────────────┴──────────────────────────────┘   │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐ │
│  │  📋 Contacts Table (TanStack Table)                  │ │
│  │  [🔍] [Filter] [Sort] [Export] [Columns ▼]          │ │
│  │  ┌────┬──────────┬──────────┬──────┬──────────────┐ │ │
│  │  │ ☐  │ Name     │ Phone    │ City │ Risk    [⋮]  │ │ │
│  │  ├────┼──────────┼──────────┼──────┼──────────────┤ │ │
│  │  │ ☐  │Jan Novák │+420608.. │Praha │🟢 Low   [⋮]  │ │ │
│  │  │    │          │          │      │              │ │ │
│  │  └────┴──────────┴──────────┴──────┴──────────────┘ │ │
│  │  Showing 1-50 of 2,529,097  [← 1 2 3 ... 50,582 →]  │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                             │
└────────────────────────────────────────────────────────────┘

[Theme: Dark Mode / Light Mode / Auto]
[Smooth scroll, Animations, Gestures, Keyboard shortcuts]

💻 Build Stack:

{
  "dependencies": {
    "next": "14.0.0",
    "@radix-ui/react-*": "^1.0.0",  // Shadcn components
    "tailwindcss": "^3.3.0",
    "framer-motion": "^10.0.0",
    "recharts": "^2.10.0",
    "mapbox-gl": "^3.0.0",
    "react-map-gl": "^7.1.0",
    "@tanstack/react-table": "^8.10.0",
    "@tanstack/react-query": "^5.0.0",
    "zustand": "^4.4.0",
    "zod": "^3.22.0",  // Validation
    "date-fns": "^3.0.0",
    "lucide-react": "^0.300.0"  // Icons
  }
}

🎨 Component Examples:

1. KPI Card (Shadcn)

// components/kpi-card.tsx
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ArrowUpIcon, ArrowDownIcon } from "lucide-react";
import { motion } from "framer-motion";

interface KPICardProps {
  title: string;
  value: string;
  change: number;
  icon: React.ReactNode;
}

export function KPICard({ title, value, change, icon }: KPICardProps) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3 }}
    >
      <Card>
        <CardHeader className="flex flex-row items-center justify-between pb-2">
          <CardTitle className="text-sm font-medium">{title}</CardTitle>
          {icon}
        </CardHeader>
        <CardContent>
          <div className="text-2xl font-bold">{value}</div>
          <p className="text-xs text-muted-foreground flex items-center gap-1">
            {change > 0 ? (
              <ArrowUpIcon className="h-4 w-4 text-green-500" />
            ) : (
              <ArrowDownIcon className="h-4 w-4 text-red-500" />
            )}
            <span className={change > 0 ? "text-green-500" : "text-red-500"}>
              {Math.abs(change)}%
            </span>
            <span>vs last month</span>
          </p>
        </CardContent>
      </Card>
    </motion.div>
  );
}

2. Interactive Map

// components/interactive-map.tsx
'use client';

import Map, { Marker, Popup, Layer, Source } from 'react-map-gl';
import { useState } from 'react';

export function InteractiveMap() {
  const [selectedContact, setSelectedContact] = useState(null);
  const [viewState, setViewState] = useState({
    latitude: 50.0755,
    longitude: 14.4378,
    zoom: 7
  });

  return (
    <Map
      {...viewState}
      onMove={evt => setViewState(evt.viewState)}
      mapStyle="mapbox://styles/mapbox/dark-v11"
      mapboxAccessToken={process.env.NEXT_PUBLIC_MAPBOX_TOKEN}
    >
      {/* Heatmap Layer */}
      <Source
        id="contacts"
        type="geojson"
        data={{
          type: 'FeatureCollection',
          features: contacts.map(c => ({
            type: 'Feature',
            geometry: { type: 'Point', coordinates: [c.lon, c.lat] },
            properties: { risk: c.risk_score }
          }))
        }}
      >
        <Layer
          id="heatmap"
          type="heatmap"
          paint={{
            'heatmap-weight': ['get', 'risk'],
            'heatmap-intensity': 1,
            'heatmap-color': [
              'interpolate',
              ['linear'],
              ['heatmap-density'],
              0, 'rgba(0,0,255,0)',
              0.2, 'rgb(0,255,0)',
              0.4, 'rgb(255,255,0)',
              0.6, 'rgb(255,128,0)',
              1, 'rgb(255,0,0)'
            ]
          }}
        />
      </Source>

      {/* Markers */}
      {contacts.map(contact => (
        <Marker
          key={contact.id}
          latitude={contact.lat}
          longitude={contact.lon}
          onClick={() => setSelectedContact(contact)}
        >
          <div className={`marker marker-${contact.risk_level.toLowerCase()}`} />
        </Marker>
      ))}

      {/* Popup */}
      {selectedContact && (
        <Popup
          latitude={selectedContact.lat}
          longitude={selectedContact.lon}
          onClose={() => setSelectedContact(null)}
        >
          <ContactPopup contact={selectedContact} />
        </Popup>
      )}
    </Map>
  );
}

3. Data Table (TanStack)

// components/contacts-table.tsx
'use client';

import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
} from '@tanstack/react-table';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

const columns = [
  {
    accessorKey: 'full_name',
    header: 'Name',
    cell: ({ row }) => (
      <div className="font-medium">{row.getValue('full_name')}</div>
    ),
  },
  {
    accessorKey: 'phone',
    header: 'Phone',
  },
  {
    accessorKey: 'city',
    header: 'City',
  },
  {
    accessorKey: 'risk_level',
    header: 'Risk',
    cell: ({ row }) => (
      <RiskBadge level={row.getValue('risk_level')} />
    ),
  },
];

export function ContactsTable({ data }: { data: any[] }) {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
  });

  return (
    <div className="space-y-4">
      <Input
        placeholder="Search contacts..."
        value={(table.getColumn('full_name')?.getFilterValue() as string) ?? ''}
        onChange={(event) =>
          table.getColumn('full_name')?.setFilterValue(event.target.value)
        }
        className="max-w-sm"
      />

      <div className="rounded-md border">
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map((headerGroup) => (
              <TableRow key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <TableHead key={header.id}>
                    {header.isPlaceholder
                      ? null
                      : flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}
                  </TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows?.length ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id}>
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext()
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell
                  colSpan={columns.length}
                  className="h-24 text-center"
                >
                  No results.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>

      <div className="flex items-center justify-between">
        <div className="text-sm text-muted-foreground">
          Page {table.getState().pagination.pageIndex + 1} of{' '}
          {table.getPageCount()}
        </div>
        <div className="space-x-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => table.previousPage()}
            disabled={!table.getCanPreviousPage()}
          >
            Previous
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => table.nextPage()}
            disabled={!table.getCanNextPage()}
          >
            Next
          </Button>
        </div>
      </div>
    </div>
  );
}

📦 Setup (3-5 dní):

Day 1: Scaffold Project

npx create-next-app@latest aml-dashboard --typescript --tailwind --app
cd aml-dashboard
npx shadcn-ui@latest init
npx shadcn-ui@latest add card table button input
npm install framer-motion recharts mapbox-gl react-map-gl
npm install @tanstack/react-table @tanstack/react-query zustand

Day 2-3: Build Components

- KPI Cards
- Interactive Map (Mapbox)
- Charts (Recharts)
- Data Table (TanStack)
- Filters & Search
- Contact Detail Drawer

Day 4: API Integration

// app/api/contacts/route.ts
import { NextResponse } from 'next/server';
import Database from 'better-sqlite3';

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const city = searchParams.get('city');
  const limit = parseInt(searchParams.get('limit') || '100');

  const db = new Database('D:/REALITY_SCAN_DATA/DATABASES/MASTER_CONTACTS.db');

  const query = city
    ? db.prepare('SELECT * FROM contacts WHERE city = ? LIMIT ?')
    : db.prepare('SELECT * FROM contacts LIMIT ?');

  const contacts = city
    ? query.all(city, limit)
    : query.all(limit);

  return NextResponse.json(contacts);
}

Day 5: Deploy

# Deploy to Vercel (FREE)
npm install -g vercel
vercel deploy --prod

# Or Docker
docker build -t aml-dashboard .
docker run -p 3000:3000 aml-dashboard

💰 Pricing:

Development: 3-5 dní tvého času (nebo $3,000-5,000 outsource) Hosting: Vercel FREE tier nebo $20/měsíc Pro Mapbox: FREE (50K loads/měsíc) nebo $5/1000 loads Database: Self-hosted (FREE)

Total: $0-20/měsíc 🎉

✅ Doporučení:

PRO: - ⭐⭐⭐⭐⭐ Maximum kontrola - ⭐⭐⭐⭐⭐ Nejmodernější tech stack - ⭐⭐⭐⭐⭐ Nejrychlejší výkon - ⭐⭐⭐⭐⭐ Vlastní branding - ⭐⭐⭐⭐ Skvělý design (Shadcn)

CON: - 🕐 Čas vývoje (3-5 dní) - 📚 Vyžaduje React/TypeScript znalost

Verdict:Best if máš čas nebo budget na dev


📊 FINAL SROVNÁNÍ

Feature Tableau Power BI Looker Custom Next.js
Cena/měsíc $220 $110 $3,500 $20
Setup Time 1 týden 3-5 dní 2-3 týdny 3-5 dní
Vizualizace ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Customization ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Performance ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Enterprise ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
GPS Maps ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
AI Features ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐ (DIY)
Mobile ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
Embedding ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

🎯 MÉ DOPORUČENÍ PRO TEBE:

OPTION 1: TABLEAU (Nejprofesionálnější)

Použij pokud: - ✅ Potřebuješ impresivní prezentace pro klienty - ✅ Chceš nejlepší vizualizace - ✅ Budget není problém ($220/měsíc) - ✅ Enterprise features (audit logs, SSO)

Timeline: 1 týden setup → Ihned production-ready


OPTION 2: POWER BI (Best Value)

Použij pokud: - ✅ Používáš Microsoft ekosystém (Office 365, Teams) - ✅ Chceš nejlepší cena/výkon ($110/měsíc) - ✅ Potřebuješ Czech language support (Q&A) - ✅ Azure Maps pro ČR data

Timeline: 3-5 dní setup → Production-ready


OPTION 3: CUSTOM NEXT.JS (Doporučuji!)

Použij pokud: - ✅ Chceš maximum kontrolu - ✅ Plánuješ white-label pro klienty - ✅ Máš čas (3-5 dní) nebo budget ($3-5K outsource) - ✅ Chceš nejmodernější tech stack - ✅ Nejlevnější ($20/měsíc hosting)

Timeline: 3-5 dní development → Deploy na Vercel


💡 MŮJ NÁVRH:

HYBRID APPROACH (Nejlepší ze všech světů):

Phase 1 (TEĎKA): Streamlit pro interní testing Phase 2 (Za měsíc): Custom Next.js pro klienty Phase 3 (Budoucnost): Power BI embedded do Next.js

Proč: - ✅ Streamlit: Rychlý start (5 minut) - ✅ Next.js: Profesionální pro klienty - ✅ Power BI: Enterprise analytics embedded


🚀 CO TI MŮŽU UDĚLAT TEĎKA:

  1. [ ] Build Custom Next.js Dashboard (3-5 dní, nejkrásnější)
  2. [ ] Setup Tableau trial (30 dní free, otestuj)
  3. [ ] Setup Power BI (nejrychlejší enterprise)
  4. [ ] Kombinace: Next.js + Power BI embedded

Řekni mi kterou cestu chceš! 🎯


Generated: 2025-12-08 Enterprise Dashboard Solutions Tableau | Power BI | Looker | Custom Next.js