🏆 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:
-
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] -
Smart Recommendations
- Tableau navrhne nejlepší typ grafu pro tvá data
- "Try this visualization instead" suggestions
-
Auto-formatting (colors, labels, legends)
-
Story Points
- Vytvoř prezentaci z dashboardů
- Kliknutelné slides s animacemi
-
Perfect pro board meetings
-
Data Blending
- Kombinuj MASTER_CONTACTS + ARES + RUIAN
- Join přes UI (bez SQL)
-
Live connections
-
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:
-
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" -
Quick Insights (AI)
- Auto-discover patterns
- Outlier detection
- Trend analysis
-
Correlation finder
-
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) ) -
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 -
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:
-
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\"%\"" } } -
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 -
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) -
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 --> -
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:
- [ ] Build Custom Next.js Dashboard (3-5 dní, nejkrásnější)
- [ ] Setup Tableau trial (30 dní free, otestuj)
- [ ] Setup Power BI (nejrychlejší enterprise)
- [ ] 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