@burdenoff/microfe-proserviceworld 2026.625.1 → 2026.626.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/proserviceworld/pages/AdminReportsPage.js +102 -68
  2. package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
  3. package/dist/proserviceworld/pages/AdminUsersPage.js +37 -33
  4. package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
  5. package/dist/proserviceworld/pages/AnalyticsPage.js +66 -36
  6. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/proserviceworld/pages/BookingsPage.js +52 -48
  8. package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
  9. package/dist/proserviceworld/pages/DashboardPage.js +275 -243
  10. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  11. package/dist/proserviceworld/pages/DocumentsPage.js +204 -200
  12. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  13. package/dist/proserviceworld/pages/MessagesPage.js +200 -186
  14. package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
  15. package/dist/proserviceworld/pages/PaymentsPage.js +70 -39
  16. package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
  17. package/dist/proserviceworld/pages/ProjectsPage.js +510 -477
  18. package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
  19. package/dist/proserviceworld/pages/ProviderDetailPage.js +71 -41
  20. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
  21. package/dist/proserviceworld/pages/ProvidersPage.js +62 -58
  22. package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ReviewsPage.js +80 -63
  24. package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/ServiceDetailsPage.js +118 -83
  26. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/ServicesPage.js +134 -130
  28. package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/VerificationPage.js +23 -19
  30. package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
  31. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ProviderDetailPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ProviderDetailPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Button,\n Badge,\n GlassCard,\n EmphasisPanel,\n CTAOverflowMenu,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Star,\n CheckCircle,\n MapPin,\n Briefcase,\n Award,\n MessageSquare,\n Share2,\n Calendar,\n Users,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype DetailTab = 'overview' | 'services' | 'reviews';\n\nexport function ProviderDetailPage() {\n const { providers, services, reviews } = useProServiceWorldStore();\n const [activeTab, setActiveTab] = useState<DetailTab>('overview');\n\n const provider = providers[0];\n const providerServices = services.filter((s) => s.providerId === provider.id);\n const providerReviews = reviews.filter((r) => r.providerName === provider.name);\n\n const tabs: { id: DetailTab; label: string }[] = [\n { id: 'overview', label: 'Overview' },\n { id: 'services', label: `Services (${providerServices.length})` },\n { id: 'reviews', label: `Reviews (${providerReviews.length})` },\n ];\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2\">\n {/* Provider hero — the single emphasised zone for this page */}\n <EmphasisPanel className=\"relative overflow-hidden\">\n <div className=\"flex items-start space-x-6\">\n <div className=\"h-20 w-20 rounded-full bg-accent-soft flex items-center justify-center shrink-0\">\n <span className=\"text-text-primary text-2xl font-bold\">\n {provider.name.charAt(0)}\n {provider.name.split(' ')[1]?.charAt(0)}\n </span>\n </div>\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-3 mb-1\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{provider.businessName}</h1>\n {provider.verified && (\n <Badge variant=\"default\">\n <CheckCircle className=\"h-3 w-3 mr-1\" />\n Verified\n </Badge>\n )}\n </div>\n <p className=\"text-text-secondary mb-2\">{provider.name}</p>\n <p className=\"text-sm text-text-secondary mb-4\">{provider.tagline}</p>\n <div className=\"flex flex-wrap items-center gap-4 text-sm\">\n <div className=\"flex items-center\">\n <Star className=\"h-4 w-4 text-status-warning-text fill-current mr-1\" />\n <span className=\"font-medium tabular-nums\">{provider.rating.toFixed(1)}</span>\n <span className=\"text-text-secondary ml-1\">\n ({provider.totalReviews} reviews)\n </span>\n </div>\n <div className=\"flex items-center text-text-secondary\">\n <MapPin className=\"h-4 w-4 mr-1\" />\n {provider.location}\n </div>\n <div className=\"flex items-center text-text-secondary\">\n <Briefcase className=\"h-4 w-4 mr-1\" />\n {provider.yearsExperience} years\n </div>\n </div>\n </div>\n </div>\n </EmphasisPanel>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-6 space-y-4\">\n <div className=\"text-center\">\n <div className=\"text-2xl font-bold tabular-nums\">${provider.hourlyRate}/hr</div>\n <p className=\"text-sm text-text-secondary\">Starting rate</p>\n </div>\n <Button className=\"w-full\">\n <MessageSquare className=\"h-4 w-4 mr-2\" />\n Contact Provider\n </Button>\n <CTAOverflowMenu\n className=\"justify-center\"\n actions={[\n {\n label: 'Book Consultation',\n onSelect: () => {},\n icon: <Calendar className=\"h-4 w-4\" />,\n },\n {\n label: 'Share Profile',\n onSelect: () => {},\n icon: <Share2 className=\"h-4 w-4\" />,\n },\n ]}\n />\n <div className=\"grid grid-cols-2 gap-4 text-sm pt-4 border-t border-border-seam\">\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.responseTime}h</div>\n <div className=\"text-text-secondary\">Response</div>\n </div>\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.completionRate}%</div>\n <div className=\"text-text-secondary\">Completion</div>\n </div>\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.projectsCompleted}</div>\n <div className=\"text-text-secondary\">Projects</div>\n </div>\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.activeProjects}</div>\n <div className=\"text-text-secondary\">Active</div>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"border-b border-border-seam\">\n <nav className=\"-mb-px flex space-x-8\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n aria-pressed={activeTab === tab.id}\n className={`py-3 px-1 border-b-2 font-medium text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${activeTab === tab.id ? 'border-accent-blue text-accent-blue' : 'border-transparent text-text-secondary hover:text-text-primary'}`}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {activeTab === 'overview' && (\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>About</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-text-secondary\">{provider.description}</p>\n </CardContent>\n </Card>\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Specializations</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap gap-2\">\n {provider.specializations.map((s) => (\n <Badge key={s} variant=\"secondary\">\n {s}\n </Badge>\n ))}\n </div>\n </CardContent>\n </Card>\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Certifications</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {provider.certifications.map((c) => (\n <div key={c} className=\"flex items-center gap-3\">\n <Award className=\"h-5 w-5 text-accent-blue\" />\n <span>{c}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n <div className=\"space-y-6\">\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Location</span>\n <span>{provider.location}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Languages</span>\n <span>{provider.languages.join(', ')}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Member Since</span>\n <span>\n {new Date(provider.joinedDate).toLocaleDateString('en-US', {\n month: 'short',\n year: 'numeric',\n })}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Category</span>\n <span className=\"capitalize\">{provider.category.replace('_', ' ')}</span>\n </div>\n </CardContent>\n </Card>\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Similar Providers</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {providers\n .filter((p) => p.id !== provider.id)\n .slice(0, 3)\n .map((p) => (\n <div key={p.id} className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-bg-sunken flex items-center justify-center text-xs font-medium\">\n {p.name.charAt(0)}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{p.businessName}</p>\n <p className=\"text-xs text-text-secondary\">{p.specializations[0]}</p>\n </div>\n <div className=\"flex items-center text-xs\">\n <Star className=\"h-3 w-3 text-status-warning-text fill-current mr-0.5\" />\n <span className=\"tabular-nums\">{p.rating.toFixed(1)}</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n )}\n\n {activeTab === 'services' && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {providerServices.length > 0 ? (\n providerServices.map((svc) => (\n <GlassCard\n key={svc.id}\n treatment=\"plain\"\n className=\"border-border-seam transition-shadow hover:shadow-pop\"\n >\n <CardContent className=\"p-6\">\n <h3 className=\"font-semibold mb-2\">{svc.title}</h3>\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">\n {svc.description}\n </p>\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {svc.tags.slice(0, 3).map((t) => (\n <Badge key={t} variant=\"outline\" className=\"text-xs\">\n {t}\n </Badge>\n ))}\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-3\">\n <span className=\"font-medium tabular-nums\">\n From ${svc.pricing.basePrice.toLocaleString()}\n </span>\n <span className=\"text-sm text-text-secondary tabular-nums\">\n {svc.duration.typical} days\n </span>\n </div>\n <Button variant=\"outline\" size=\"sm\" className=\"w-full mt-3\">\n View Details\n </Button>\n </CardContent>\n </GlassCard>\n ))\n ) : (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No services listed yet\"\n description=\"This provider has not published any services.\"\n />\n </div>\n )}\n </div>\n )}\n\n {activeTab === 'reviews' && (\n <div className=\"space-y-4\">\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <div className=\"flex flex-col gap-8 sm:flex-row sm:items-center\">\n <div className=\"text-center\">\n <div className=\"text-4xl font-bold tabular-nums\">{provider.rating.toFixed(1)}</div>\n <div className=\"flex justify-center mt-1\">\n {[1, 2, 3, 4, 5].map((s) => (\n <Star\n key={s}\n className={`h-4 w-4 ${s <= Math.round(provider.rating) ? 'text-status-warning-text fill-current' : 'text-text-secondary'}`}\n />\n ))}\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n {provider.totalReviews} reviews\n </p>\n </div>\n <div className=\"flex-1 space-y-1\">\n {[5, 4, 3, 2, 1].map((r) => {\n const c = providerReviews.filter((rv) => Math.round(rv.rating) === r).length;\n const p = providerReviews.length > 0 ? (c / providerReviews.length) * 100 : 0;\n return (\n <div key={r} className=\"flex items-center gap-2\">\n <span className=\"text-sm w-3 tabular-nums\">{r}</span>\n <Star className=\"h-3 w-3 text-status-warning-text fill-current\" />\n <div className=\"flex-1 bg-bg-sunken rounded-full h-2\">\n <div\n className=\"bg-status-warning-text h-2 rounded-full\"\n style={{ width: `${p}%` }}\n />\n </div>\n <span className=\"text-sm text-text-secondary w-6 text-right tabular-nums\">\n {c}\n </span>\n </div>\n );\n })}\n </div>\n </div>\n </CardContent>\n </GlassCard>\n {providerReviews.map((rev) => (\n <Card key={rev.id} className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <div className=\"h-10 w-10 rounded-full bg-accent-soft flex items-center justify-center\">\n <span className=\"text-text-primary font-medium\">\n {rev.clientName.charAt(0)}\n </span>\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{rev.clientName}</span>\n <div className=\"flex\">\n {[1, 2, 3, 4, 5].map((s) => (\n <Star\n key={s}\n className={`h-3 w-3 ${s <= rev.rating ? 'text-status-warning-text fill-current' : 'text-text-secondary'}`}\n />\n ))}\n </div>\n </div>\n <p className=\"text-xs text-text-secondary\">\n {rev.serviceName} -{' '}\n {new Date(rev.createdAt).toLocaleDateString('en-US', {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n })}\n </p>\n </div>\n </div>\n <p className=\"text-sm text-text-secondary mb-3\">{rev.comment}</p>\n <div className=\"flex flex-wrap gap-4 text-xs text-text-secondary\">\n <span className=\"tabular-nums\">Value: ${rev.projectValue.toLocaleString()}</span>\n <span className=\"tabular-nums\">Duration: {rev.projectDuration} days</span>\n <span className=\"flex items-center\">\n <Users className=\"h-3 w-3 mr-1\" />\n <span className=\"tabular-nums\">{rev.helpful}</span> helpful\n </span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProviderDetailPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ProviderDetailPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Button,\n Badge,\n GlassCard,\n EmphasisPanel,\n CTAOverflowMenu,\n IllustratedEmptyState,\n PagePurpose,\n NextSteps,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Star,\n CheckCircle,\n MapPin,\n Briefcase,\n Award,\n MessageSquare,\n Share2,\n Calendar,\n Users,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype DetailTab = 'overview' | 'services' | 'reviews';\n\nexport function ProviderDetailPage() {\n const { providers, services, reviews } = useProServiceWorldStore();\n const [activeTab, setActiveTab] = useState<DetailTab>('overview');\n\n const provider = providers[0];\n const providerServices = services.filter((s) => s.providerId === provider.id);\n const providerReviews = reviews.filter((r) => r.providerName === provider.name);\n\n const tabs: { id: DetailTab; label: string }[] = [\n { id: 'overview', label: 'Overview' },\n { id: 'services', label: `Services (${providerServices.length})` },\n { id: 'reviews', label: `Reviews (${providerReviews.length})` },\n ];\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n <PagePurpose icon={<Briefcase className=\"h-4 w-4\" />}>\n A full picture of this provider before you engage. Review their background, specializations,\n certifications, and ratings, browse the services they offer, and read client reviews — then\n contact them or book a consultation with confidence.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"proserviceworld-provider-detail\"\n steps={[\n {\n id: 'services',\n label: 'Browse their services',\n description: 'See what this provider offers and starting prices.',\n icon: <Briefcase className=\"h-4 w-4\" />,\n onClick: () => setActiveTab('services'),\n },\n {\n id: 'reviews',\n label: 'Read client reviews',\n description: 'Check ratings and feedback from past clients.',\n icon: <Star className=\"h-4 w-4\" />,\n onClick: () => setActiveTab('reviews'),\n },\n {\n id: 'contact',\n label: 'Contact the provider',\n description: 'Start a conversation or book a consultation.',\n icon: <MessageSquare className=\"h-4 w-4\" />,\n onClick: () => setActiveTab('overview'),\n },\n ]}\n />\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2\">\n {/* Provider hero — the single emphasised zone for this page */}\n <EmphasisPanel className=\"relative overflow-hidden\">\n <div className=\"flex items-start space-x-6\">\n <div className=\"h-20 w-20 rounded-full bg-accent-soft flex items-center justify-center shrink-0\">\n <span className=\"text-text-primary text-2xl font-bold\">\n {provider.name.charAt(0)}\n {provider.name.split(' ')[1]?.charAt(0)}\n </span>\n </div>\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-3 mb-1\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{provider.businessName}</h1>\n {provider.verified && (\n <Badge variant=\"default\">\n <CheckCircle className=\"h-3 w-3 mr-1\" />\n Verified\n </Badge>\n )}\n </div>\n <p className=\"text-text-secondary mb-2\">{provider.name}</p>\n <p className=\"text-sm text-text-secondary mb-4\">{provider.tagline}</p>\n <div className=\"flex flex-wrap items-center gap-4 text-sm\">\n <div className=\"flex items-center\">\n <Star className=\"h-4 w-4 text-status-warning-text fill-current mr-1\" />\n <span className=\"font-medium tabular-nums\">{provider.rating.toFixed(1)}</span>\n <span className=\"text-text-secondary ml-1\">\n ({provider.totalReviews} reviews)\n </span>\n </div>\n <div className=\"flex items-center text-text-secondary\">\n <MapPin className=\"h-4 w-4 mr-1\" />\n {provider.location}\n </div>\n <div className=\"flex items-center text-text-secondary\">\n <Briefcase className=\"h-4 w-4 mr-1\" />\n {provider.yearsExperience} years\n </div>\n </div>\n </div>\n </div>\n </EmphasisPanel>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"p-6 space-y-4\">\n <div className=\"text-center\">\n <div className=\"text-2xl font-bold tabular-nums\">${provider.hourlyRate}/hr</div>\n <p className=\"text-sm text-text-secondary\">Starting rate</p>\n </div>\n <Button className=\"w-full\">\n <MessageSquare className=\"h-4 w-4 mr-2\" />\n Contact Provider\n </Button>\n <CTAOverflowMenu\n className=\"justify-center\"\n actions={[\n {\n label: 'Book Consultation',\n onSelect: () => {},\n icon: <Calendar className=\"h-4 w-4\" />,\n },\n {\n label: 'Share Profile',\n onSelect: () => {},\n icon: <Share2 className=\"h-4 w-4\" />,\n },\n ]}\n />\n <div className=\"grid grid-cols-2 gap-4 text-sm pt-4 border-t border-border-seam\">\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.responseTime}h</div>\n <div className=\"text-text-secondary\">Response</div>\n </div>\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.completionRate}%</div>\n <div className=\"text-text-secondary\">Completion</div>\n </div>\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.projectsCompleted}</div>\n <div className=\"text-text-secondary\">Projects</div>\n </div>\n <div className=\"text-center p-3 bg-bg-sunken rounded\">\n <div className=\"font-semibold tabular-nums\">{provider.activeProjects}</div>\n <div className=\"text-text-secondary\">Active</div>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n <div className=\"border-b border-border-seam\">\n <nav className=\"-mb-px flex space-x-8\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n aria-pressed={activeTab === tab.id}\n className={`py-3 px-1 border-b-2 font-medium text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${activeTab === tab.id ? 'border-accent-blue text-accent-blue' : 'border-transparent text-text-secondary hover:text-text-primary'}`}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n {activeTab === 'overview' && (\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>About</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-text-secondary\">{provider.description}</p>\n </CardContent>\n </Card>\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Specializations</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex flex-wrap gap-2\">\n {provider.specializations.map((s) => (\n <Badge key={s} variant=\"secondary\">\n {s}\n </Badge>\n ))}\n </div>\n </CardContent>\n </Card>\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Certifications</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {provider.certifications.map((c) => (\n <div key={c} className=\"flex items-center gap-3\">\n <Award className=\"h-5 w-5 text-accent-blue\" />\n <span>{c}</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n <div className=\"space-y-6\">\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Location</span>\n <span>{provider.location}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Languages</span>\n <span>{provider.languages.join(', ')}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Member Since</span>\n <span>\n {new Date(provider.joinedDate).toLocaleDateString('en-US', {\n month: 'short',\n year: 'numeric',\n })}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Category</span>\n <span className=\"capitalize\">{provider.category.replace('_', ' ')}</span>\n </div>\n </CardContent>\n </Card>\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>Similar Providers</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {providers\n .filter((p) => p.id !== provider.id)\n .slice(0, 3)\n .map((p) => (\n <div key={p.id} className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-bg-sunken flex items-center justify-center text-xs font-medium\">\n {p.name.charAt(0)}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{p.businessName}</p>\n <p className=\"text-xs text-text-secondary\">{p.specializations[0]}</p>\n </div>\n <div className=\"flex items-center text-xs\">\n <Star className=\"h-3 w-3 text-status-warning-text fill-current mr-0.5\" />\n <span className=\"tabular-nums\">{p.rating.toFixed(1)}</span>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n )}\n\n {activeTab === 'services' && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {providerServices.length > 0 ? (\n providerServices.map((svc) => (\n <GlassCard\n key={svc.id}\n treatment=\"plain\"\n className=\"border-border-seam transition-shadow hover:shadow-pop\"\n >\n <CardContent className=\"p-6\">\n <h3 className=\"font-semibold mb-2\">{svc.title}</h3>\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">\n {svc.description}\n </p>\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {svc.tags.slice(0, 3).map((t) => (\n <Badge key={t} variant=\"outline\" className=\"text-xs\">\n {t}\n </Badge>\n ))}\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-3\">\n <span className=\"font-medium tabular-nums\">\n From ${svc.pricing.basePrice.toLocaleString()}\n </span>\n <span className=\"text-sm text-text-secondary tabular-nums\">\n {svc.duration.typical} days\n </span>\n </div>\n <Button variant=\"outline\" size=\"sm\" className=\"w-full mt-3\">\n View Details\n </Button>\n </CardContent>\n </GlassCard>\n ))\n ) : (\n <div className=\"col-span-full\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No services listed yet\"\n description=\"This provider has not published any services.\"\n />\n </div>\n )}\n </div>\n )}\n\n {activeTab === 'reviews' && (\n <div className=\"space-y-4\">\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <div className=\"flex flex-col gap-8 sm:flex-row sm:items-center\">\n <div className=\"text-center\">\n <div className=\"text-4xl font-bold tabular-nums\">{provider.rating.toFixed(1)}</div>\n <div className=\"flex justify-center mt-1\">\n {[1, 2, 3, 4, 5].map((s) => (\n <Star\n key={s}\n className={`h-4 w-4 ${s <= Math.round(provider.rating) ? 'text-status-warning-text fill-current' : 'text-text-secondary'}`}\n />\n ))}\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n {provider.totalReviews} reviews\n </p>\n </div>\n <div className=\"flex-1 space-y-1\">\n {[5, 4, 3, 2, 1].map((r) => {\n const c = providerReviews.filter((rv) => Math.round(rv.rating) === r).length;\n const p = providerReviews.length > 0 ? (c / providerReviews.length) * 100 : 0;\n return (\n <div key={r} className=\"flex items-center gap-2\">\n <span className=\"text-sm w-3 tabular-nums\">{r}</span>\n <Star className=\"h-3 w-3 text-status-warning-text fill-current\" />\n <div className=\"flex-1 bg-bg-sunken rounded-full h-2\">\n <div\n className=\"bg-status-warning-text h-2 rounded-full\"\n style={{ width: `${p}%` }}\n />\n </div>\n <span className=\"text-sm text-text-secondary w-6 text-right tabular-nums\">\n {c}\n </span>\n </div>\n );\n })}\n </div>\n </div>\n </CardContent>\n </GlassCard>\n {providerReviews.map((rev) => (\n <Card key={rev.id} className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <div className=\"flex items-center gap-3 mb-3\">\n <div className=\"h-10 w-10 rounded-full bg-accent-soft flex items-center justify-center\">\n <span className=\"text-text-primary font-medium\">\n {rev.clientName.charAt(0)}\n </span>\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{rev.clientName}</span>\n <div className=\"flex\">\n {[1, 2, 3, 4, 5].map((s) => (\n <Star\n key={s}\n className={`h-3 w-3 ${s <= rev.rating ? 'text-status-warning-text fill-current' : 'text-text-secondary'}`}\n />\n ))}\n </div>\n </div>\n <p className=\"text-xs text-text-secondary\">\n {rev.serviceName} -{' '}\n {new Date(rev.createdAt).toLocaleDateString('en-US', {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n })}\n </p>\n </div>\n </div>\n <p className=\"text-sm text-text-secondary mb-3\">{rev.comment}</p>\n <div className=\"flex flex-wrap gap-4 text-xs text-text-secondary\">\n <span className=\"tabular-nums\">Value: ${rev.projectValue.toLocaleString()}</span>\n <span className=\"tabular-nums\">Duration: {rev.projectDuration} days</span>\n <span className=\"flex items-center\">\n <Users className=\"h-3 w-3 mr-1\" />\n <span className=\"tabular-nums\">{rev.helpful}</span> helpful\n </span>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -4,9 +4,9 @@ import { useMemo as n, useState as r } from "react";
4
4
  import { Briefcase as i, CheckCircle as a, Clock as o, Filter as s, MapPin as c, Search as l, Star as u, Users as d } from "lucide-react";
5
5
  import { useI18n as f } from "@burdenoff/fe-libs/shared/providers/shell";
6
6
  import { jsx as p, jsxs as m } from "react/jsx-runtime";
7
- import { AuroraBackground as h, Badge as g, Button as _, Card as v, CardContent as y, EmphasisPanel as b, GlassCard as x, GradientText as S, IllustratedEmptyState as C, Input as w } from "@burdenoff/fe-libs/ui";
7
+ import { AuroraBackground as h, Badge as g, Button as _, Card as v, CardContent as y, EmphasisPanel as b, GlassCard as x, GradientText as S, IllustratedEmptyState as C, Input as w, PagePurpose as T } from "@burdenoff/fe-libs/ui";
8
8
  //#region src/proserviceworld/pages/ProvidersPage.tsx
9
- var T = [
9
+ var E = [
10
10
  {
11
11
  value: "",
12
12
  key: "proserviceworld.shared.filters.allCategories",
@@ -58,25 +58,25 @@ var T = [
58
58
  fallback: "Education & Training"
59
59
  }
60
60
  ];
61
- function E() {
62
- let { t: E } = f(), D = (e, n, r) => t(E, e, n, r), { providers: O } = e(), [k, A] = r(""), [j, M] = r(""), [N, P] = r(""), [F, I] = r(!1), L = n(() => {
63
- let e = [...O];
64
- if (k) {
65
- let t = k.toLowerCase();
61
+ function D() {
62
+ let { t: D } = f(), O = (e, n, r) => t(D, e, n, r), { providers: k } = e(), [A, j] = r(""), [M, N] = r(""), [P, F] = r(""), [I, L] = r(!1), R = n(() => {
63
+ let e = [...k];
64
+ if (A) {
65
+ let t = A.toLowerCase();
66
66
  e = e.filter((e) => e.name.toLowerCase().includes(t) || e.businessName.toLowerCase().includes(t) || e.tagline.toLowerCase().includes(t) || e.specializations.some((e) => e.toLowerCase().includes(t)));
67
67
  }
68
- return j && (e = e.filter((e) => e.category === j)), N && (e = e.filter((e) => e.rating >= N)), e.sort((e, t) => t.rating - e.rating), e;
68
+ return M && (e = e.filter((e) => e.category === M)), P && (e = e.filter((e) => e.rating >= P)), e.sort((e, t) => t.rating - e.rating), e;
69
69
  }, [
70
- O,
71
70
  k,
72
- j,
73
- N
74
- ]), R = L.length > 0 ? (L.reduce((e, t) => e + t.rating, 0) / L.length).toFixed(1) : "0", z = new Set(L.map((e) => e.country)).size, B = () => {
75
- A(""), M(""), P("");
76
- }, V = k ? D("proserviceworld.providers.subtitleWithQuery", "{{count}} providers found for \"{{query}}\"", {
77
- count: L.length,
78
- query: k
79
- }) : D("proserviceworld.providers.subtitle", "{{count}} providers found", { count: L.length });
71
+ A,
72
+ M,
73
+ P
74
+ ]), z = R.length > 0 ? (R.reduce((e, t) => e + t.rating, 0) / R.length).toFixed(1) : "0", B = new Set(R.map((e) => e.country)).size, V = () => {
75
+ j(""), N(""), F("");
76
+ }, H = A ? O("proserviceworld.providers.subtitleWithQuery", "{{count}} providers found for \"{{query}}\"", {
77
+ count: R.length,
78
+ query: A
79
+ }) : O("proserviceworld.providers.subtitle", "{{count}} providers found", { count: R.length });
80
80
  return /* @__PURE__ */ m("div", {
81
81
  className: "space-y-6 p-6 bg-bg-canvas min-h-screen",
82
82
  children: [
@@ -86,32 +86,36 @@ function E() {
86
86
  className: "flex flex-col md:flex-row md:items-center md:justify-between gap-4",
87
87
  children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
88
88
  className: "text-2xl font-semibold tracking-tight",
89
- children: /* @__PURE__ */ p(S, { children: D("proserviceworld.providers.title", "Service Providers") })
89
+ children: /* @__PURE__ */ p(S, { children: O("proserviceworld.providers.title", "Service Providers") })
90
90
  }), /* @__PURE__ */ p("p", {
91
91
  className: "text-sm text-text-secondary",
92
- children: V
92
+ children: H
93
93
  })] }), /* @__PURE__ */ m(_, {
94
94
  variant: "outline",
95
- onClick: () => I(!F),
96
- "aria-expanded": F,
97
- children: [/* @__PURE__ */ p(s, { className: "h-4 w-4 mr-2" }), D("proserviceworld.providers.actions.filters", "Filters")]
95
+ onClick: () => L(!I),
96
+ "aria-expanded": I,
97
+ children: [/* @__PURE__ */ p(s, { className: "h-4 w-4 mr-2" }), O("proserviceworld.providers.actions.filters", "Filters")]
98
98
  })]
99
99
  })]
100
100
  }),
101
+ /* @__PURE__ */ p(T, {
102
+ icon: /* @__PURE__ */ p(d, { className: "h-4 w-4" }),
103
+ children: O("proserviceworld.providers.purpose", "Find and vet the experts behind the work. Search by name, business, or specialization and filter by category and rating to shortlist trusted providers — then open a profile to view their services, reviews, and credentials before reaching out.")
104
+ }),
101
105
  /* @__PURE__ */ p("div", {
102
106
  className: "flex gap-4",
103
107
  children: /* @__PURE__ */ m("div", {
104
108
  className: "flex-1 relative",
105
109
  children: [/* @__PURE__ */ p(l, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-text-secondary" }), /* @__PURE__ */ p(w, {
106
110
  type: "text",
107
- placeholder: D("proserviceworld.providers.search.placeholder", "Search providers by name, business, or specialization..."),
108
- value: k,
109
- onChange: (e) => A(e.target.value),
111
+ placeholder: O("proserviceworld.providers.search.placeholder", "Search providers by name, business, or specialization..."),
112
+ value: A,
113
+ onChange: (e) => j(e.target.value),
110
114
  className: "pl-10 h-12"
111
115
  })]
112
116
  })
113
117
  }),
114
- F && /* @__PURE__ */ p(v, {
118
+ I && /* @__PURE__ */ p(v, {
115
119
  className: "border-border-seam",
116
120
  children: /* @__PURE__ */ p(y, {
117
121
  className: "p-6",
@@ -120,39 +124,39 @@ function E() {
120
124
  children: [
121
125
  /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
122
126
  className: "block text-sm font-medium mb-2",
123
- children: D("proserviceworld.providers.filters.category", "Category")
127
+ children: O("proserviceworld.providers.filters.category", "Category")
124
128
  }), /* @__PURE__ */ p("select", {
125
- value: j,
126
- onChange: (e) => M(e.target.value),
129
+ value: M,
130
+ onChange: (e) => N(e.target.value),
127
131
  className: "w-full p-2 border border-border-seam rounded-md bg-bg-surface text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
128
- children: T.map((e) => /* @__PURE__ */ p("option", {
132
+ children: E.map((e) => /* @__PURE__ */ p("option", {
129
133
  value: e.value,
130
- children: D(e.key, e.fallback)
134
+ children: O(e.key, e.fallback)
131
135
  }, e.value))
132
136
  })] }),
133
137
  /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
134
138
  className: "block text-sm font-medium mb-2",
135
- children: D("proserviceworld.providers.filters.minimumRating", "Minimum Rating")
139
+ children: O("proserviceworld.providers.filters.minimumRating", "Minimum Rating")
136
140
  }), /* @__PURE__ */ m("select", {
137
- value: N,
138
- onChange: (e) => P(e.target.value ? Number(e.target.value) : ""),
141
+ value: P,
142
+ onChange: (e) => F(e.target.value ? Number(e.target.value) : ""),
139
143
  className: "w-full p-2 border border-border-seam rounded-md bg-bg-surface text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
140
144
  children: [
141
145
  /* @__PURE__ */ p("option", {
142
146
  value: "",
143
- children: D("proserviceworld.providers.filters.anyRating", "Any Rating")
147
+ children: O("proserviceworld.providers.filters.anyRating", "Any Rating")
144
148
  }),
145
149
  /* @__PURE__ */ p("option", {
146
150
  value: "4",
147
- children: D("proserviceworld.providers.filters.rating4", "4+ Stars")
151
+ children: O("proserviceworld.providers.filters.rating4", "4+ Stars")
148
152
  }),
149
153
  /* @__PURE__ */ p("option", {
150
154
  value: "4.5",
151
- children: D("proserviceworld.providers.filters.rating45", "4.5+ Stars")
155
+ children: O("proserviceworld.providers.filters.rating45", "4.5+ Stars")
152
156
  }),
153
157
  /* @__PURE__ */ p("option", {
154
158
  value: "4.8",
155
- children: D("proserviceworld.providers.filters.rating48", "4.8+ Stars")
159
+ children: O("proserviceworld.providers.filters.rating48", "4.8+ Stars")
156
160
  })
157
161
  ]
158
162
  })] }),
@@ -160,18 +164,18 @@ function E() {
160
164
  className: "flex items-end",
161
165
  children: /* @__PURE__ */ p(_, {
162
166
  variant: "outline",
163
- onClick: B,
167
+ onClick: V,
164
168
  className: "w-full",
165
- children: D("proserviceworld.providers.filters.clear", "Clear Filters")
169
+ children: O("proserviceworld.providers.filters.clear", "Clear Filters")
166
170
  })
167
171
  })
168
172
  ]
169
173
  })
170
174
  })
171
175
  }),
172
- L.length > 0 ? /* @__PURE__ */ p("div", {
176
+ R.length > 0 ? /* @__PURE__ */ p("div", {
173
177
  className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6",
174
- children: L.map((e) => /* @__PURE__ */ m(x, {
178
+ children: R.map((e) => /* @__PURE__ */ m(x, {
175
179
  treatment: "glass",
176
180
  className: "border-border-seam transition-shadow hover:shadow-pop",
177
181
  children: [
@@ -245,37 +249,37 @@ function E() {
245
249
  className: "grid grid-cols-2 gap-2 text-xs text-text-secondary border-t border-border-seam pt-3",
246
250
  children: [/* @__PURE__ */ m("div", {
247
251
  className: "flex items-center",
248
- children: [/* @__PURE__ */ p(o, { className: "h-3 w-3 mr-1" }), D("proserviceworld.providers.card.responseTime", "{{count}}h response", { count: e.responseTime })]
252
+ children: [/* @__PURE__ */ p(o, { className: "h-3 w-3 mr-1" }), O("proserviceworld.providers.card.responseTime", "{{count}}h response", { count: e.responseTime })]
249
253
  }), /* @__PURE__ */ m("div", {
250
254
  className: "flex items-center",
251
- children: [/* @__PURE__ */ p(i, { className: "h-3 w-3 mr-1" }), D("proserviceworld.providers.card.projects", "{{count}} projects", { count: e.projectsCompleted })]
255
+ children: [/* @__PURE__ */ p(i, { className: "h-3 w-3 mr-1" }), O("proserviceworld.providers.card.projects", "{{count}} projects", { count: e.projectsCompleted })]
252
256
  })]
253
257
  }),
254
258
  /* @__PURE__ */ p(_, {
255
259
  variant: "outline",
256
260
  size: "sm",
257
261
  className: "w-full mt-4",
258
- children: D("proserviceworld.providers.actions.viewProfile", "View Profile")
262
+ children: O("proserviceworld.providers.actions.viewProfile", "View Profile")
259
263
  })
260
264
  ]
261
265
  }, e.id))
262
266
  }) : /* @__PURE__ */ p(C, {
263
267
  illustration: "empty-people",
264
- title: D("proserviceworld.providers.empty.title", "No providers found"),
265
- description: D("proserviceworld.shared.empty.adjustFilters", "Try adjusting your search criteria or filters."),
268
+ title: O("proserviceworld.providers.empty.title", "No providers found"),
269
+ description: O("proserviceworld.shared.empty.adjustFilters", "Try adjusting your search criteria or filters."),
266
270
  action: /* @__PURE__ */ p(_, {
267
271
  variant: "outline",
268
- onClick: B,
269
- children: D("proserviceworld.providers.filters.clear", "Clear Filters")
272
+ onClick: V,
273
+ children: O("proserviceworld.providers.filters.clear", "Clear Filters")
270
274
  })
271
275
  }),
272
- L.length > 0 && /* @__PURE__ */ m(b, {
276
+ R.length > 0 && /* @__PURE__ */ m(b, {
273
277
  className: "p-8",
274
278
  children: [/* @__PURE__ */ p("div", {
275
279
  className: "text-center mb-8",
276
280
  children: /* @__PURE__ */ p("h2", {
277
281
  className: "text-xl font-bold tracking-tight",
278
- children: D("proserviceworld.providers.stats.title", "Provider Statistics")
282
+ children: O("proserviceworld.providers.stats.title", "Provider Statistics")
279
283
  })
280
284
  }), /* @__PURE__ */ m("div", {
281
285
  className: "grid grid-cols-1 md:grid-cols-3 gap-8",
@@ -289,11 +293,11 @@ function E() {
289
293
  }),
290
294
  /* @__PURE__ */ p("div", {
291
295
  className: "text-2xl font-bold tabular-nums",
292
- children: R
296
+ children: z
293
297
  }),
294
298
  /* @__PURE__ */ p("div", {
295
299
  className: "text-sm text-text-secondary",
296
- children: D("proserviceworld.providers.stats.averageRating", "Average Rating")
300
+ children: O("proserviceworld.providers.stats.averageRating", "Average Rating")
297
301
  })
298
302
  ]
299
303
  }),
@@ -306,11 +310,11 @@ function E() {
306
310
  }),
307
311
  /* @__PURE__ */ p("div", {
308
312
  className: "text-2xl font-bold tabular-nums",
309
- children: L.length
313
+ children: R.length
310
314
  }),
311
315
  /* @__PURE__ */ p("div", {
312
316
  className: "text-sm text-text-secondary",
313
- children: D("proserviceworld.providers.stats.expertProviders", "Expert Providers")
317
+ children: O("proserviceworld.providers.stats.expertProviders", "Expert Providers")
314
318
  })
315
319
  ]
316
320
  }),
@@ -323,11 +327,11 @@ function E() {
323
327
  }),
324
328
  /* @__PURE__ */ p("div", {
325
329
  className: "text-2xl font-bold tabular-nums",
326
- children: z
330
+ children: B
327
331
  }),
328
332
  /* @__PURE__ */ p("div", {
329
333
  className: "text-sm text-text-secondary",
330
- children: D("proserviceworld.providers.stats.countries", "Countries")
334
+ children: O("proserviceworld.providers.stats.countries", "Countries")
331
335
  })
332
336
  ]
333
337
  })
@@ -338,6 +342,6 @@ function E() {
338
342
  });
339
343
  }
340
344
  //#endregion
341
- export { E as ProvidersPage };
345
+ export { D as ProvidersPage };
342
346
 
343
347
  //# sourceMappingURL=ProvidersPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProvidersPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ProvidersPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Card,\n CardContent,\n Button,\n Badge,\n Input,\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Search, Filter, Star, Users, MapPin, CheckCircle, Clock, Briefcase } from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { ServiceCategory } from '../types';\nimport { tWithFallback } from '../utils/i18n';\n\nconst categoryOptions: { value: ServiceCategory | ''; key: string; fallback: string }[] = [\n {\n value: '',\n key: 'proserviceworld.shared.filters.allCategories',\n fallback: 'All Categories',\n },\n {\n value: 'business_consulting',\n key: 'proserviceworld.shared.categories.businessConsulting',\n fallback: 'Business Consulting',\n },\n {\n value: 'financial_services',\n key: 'proserviceworld.shared.categories.financialServices',\n fallback: 'Financial Services',\n },\n {\n value: 'legal_services',\n key: 'proserviceworld.shared.categories.legalServices',\n fallback: 'Legal Services',\n },\n {\n value: 'accounting_bookkeeping',\n key: 'proserviceworld.shared.categories.accountingBookkeeping',\n fallback: 'Accounting & Bookkeeping',\n },\n {\n value: 'marketing_advertising',\n key: 'proserviceworld.shared.categories.marketingAdvertising',\n fallback: 'Marketing & Advertising',\n },\n {\n value: 'it_technology',\n key: 'proserviceworld.shared.categories.itTechnology',\n fallback: 'IT & Technology',\n },\n {\n value: 'human_resources',\n key: 'proserviceworld.shared.categories.humanResources',\n fallback: 'Human Resources',\n },\n {\n value: 'creative_design',\n key: 'proserviceworld.shared.categories.creativeDesign',\n fallback: 'Creative & Design',\n },\n {\n value: 'education_training',\n key: 'proserviceworld.shared.categories.educationTraining',\n fallback: 'Education & Training',\n },\n];\n\nexport function ProvidersPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n const { providers } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedCategory, setSelectedCategory] = useState<ServiceCategory | ''>('');\n const [minRating, setMinRating] = useState<number | ''>('');\n const [showFilters, setShowFilters] = useState(false);\n\n const filteredProviders = useMemo(() => {\n let result = [...providers];\n\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (p) =>\n p.name.toLowerCase().includes(q) ||\n p.businessName.toLowerCase().includes(q) ||\n p.tagline.toLowerCase().includes(q) ||\n p.specializations.some((s) => s.toLowerCase().includes(q))\n );\n }\n\n if (selectedCategory) {\n result = result.filter((p) => p.category === selectedCategory);\n }\n\n if (minRating) {\n result = result.filter((p) => p.rating >= minRating);\n }\n\n result.sort((a, b) => b.rating - a.rating);\n return result;\n }, [providers, searchQuery, selectedCategory, minRating]);\n\n const avgRating =\n filteredProviders.length > 0\n ? (\n filteredProviders.reduce((sum, p) => sum + p.rating, 0) / filteredProviders.length\n ).toFixed(1)\n : '0';\n\n const countries = new Set(filteredProviders.map((p) => p.country)).size;\n\n const clearFilters = () => {\n setSearchQuery('');\n setSelectedCategory('');\n setMinRating('');\n };\n const subtitle = searchQuery\n ? tr('proserviceworld.providers.subtitleWithQuery', '{{count}} providers found for \"{{query}}\"', {\n count: filteredProviders.length,\n query: searchQuery,\n })\n : tr('proserviceworld.providers.subtitle', '{{count}} providers found', {\n count: filteredProviders.length,\n });\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n {/* Hero header — the ONE aurora backdrop for this MFE */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.providers.title', 'Service Providers')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{subtitle}</p>\n </div>\n <Button\n variant=\"outline\"\n onClick={() => setShowFilters(!showFilters)}\n aria-expanded={showFilters}\n >\n <Filter className=\"h-4 w-4 mr-2\" />\n {tr('proserviceworld.providers.actions.filters', 'Filters')}\n </Button>\n </div>\n </div>\n\n {/* Search Bar */}\n <div className=\"flex gap-4\">\n <div className=\"flex-1 relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-text-secondary\" />\n <Input\n type=\"text\"\n placeholder={tr(\n 'proserviceworld.providers.search.placeholder',\n 'Search providers by name, business, or specialization...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10 h-12\"\n />\n </div>\n </div>\n\n {/* Filters Panel */}\n {showFilters && (\n <Card className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('proserviceworld.providers.filters.category', 'Category')}\n </label>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as ServiceCategory | '')}\n className=\"w-full p-2 border border-border-seam rounded-md bg-bg-surface text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n {categoryOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {tr(opt.key, opt.fallback)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('proserviceworld.providers.filters.minimumRating', 'Minimum Rating')}\n </label>\n <select\n value={minRating}\n onChange={(e) => setMinRating(e.target.value ? Number(e.target.value) : '')}\n className=\"w-full p-2 border border-border-seam rounded-md bg-bg-surface text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <option value=\"\">\n {tr('proserviceworld.providers.filters.anyRating', 'Any Rating')}\n </option>\n <option value=\"4\">\n {tr('proserviceworld.providers.filters.rating4', '4+ Stars')}\n </option>\n <option value=\"4.5\">\n {tr('proserviceworld.providers.filters.rating45', '4.5+ Stars')}\n </option>\n <option value=\"4.8\">\n {tr('proserviceworld.providers.filters.rating48', '4.8+ Stars')}\n </option>\n </select>\n </div>\n <div className=\"flex items-end\">\n <Button variant=\"outline\" onClick={clearFilters} className=\"w-full\">\n {tr('proserviceworld.providers.filters.clear', 'Clear Filters')}\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Provider Grid */}\n {filteredProviders.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\n {filteredProviders.map((provider) => (\n <GlassCard key={provider.id} treatment=\"glass\" className=\"border-border-seam transition-shadow hover:shadow-pop\">\n <div className=\"flex items-center space-x-4 mb-4\">\n <div className=\"h-12 w-12 rounded-full bg-accent-soft flex items-center justify-center\">\n <span className=\"text-text-primary font-bold\">{provider.name.charAt(0)}</span>\n </div>\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"font-semibold truncate\">{provider.businessName}</h3>\n <p className=\"text-sm text-text-secondary truncate\">{provider.name}</p>\n </div>\n {provider.verified && (\n <CheckCircle className=\"h-5 w-5 text-accent-blue shrink-0\" aria-label=\"Verified\" />\n )}\n </div>\n\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">{provider.tagline}</p>\n\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {provider.specializations.slice(0, 2).map((spec) => (\n <Badge key={spec} variant=\"secondary\" className=\"text-xs\">\n {spec}\n </Badge>\n ))}\n {provider.specializations.length > 2 && (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{provider.specializations.length - 2}\n </Badge>\n )}\n </div>\n\n <div className=\"flex items-center justify-between text-sm mb-3\">\n <div className=\"flex items-center\">\n <Star className=\"h-4 w-4 text-status-warning-text fill-current mr-1\" />\n <span className=\"font-medium tabular-nums\">{provider.rating.toFixed(1)}</span>\n <span className=\"text-text-secondary ml-1 tabular-nums\">\n ({provider.totalReviews})\n </span>\n </div>\n <div className=\"flex items-center text-text-secondary\">\n <MapPin className=\"h-3 w-3 mr-1\" />\n <span>{provider.location}</span>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2 text-xs text-text-secondary border-t border-border-seam pt-3\">\n <div className=\"flex items-center\">\n <Clock className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.providers.card.responseTime', '{{count}}h response', {\n count: provider.responseTime,\n })}\n </div>\n <div className=\"flex items-center\">\n <Briefcase className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.providers.card.projects', '{{count}} projects', {\n count: provider.projectsCompleted,\n })}\n </div>\n </div>\n\n <Button variant=\"outline\" size=\"sm\" className=\"w-full mt-4\">\n {tr('proserviceworld.providers.actions.viewProfile', 'View Profile')}\n </Button>\n </GlassCard>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tr('proserviceworld.providers.empty.title', 'No providers found')}\n description={tr(\n 'proserviceworld.shared.empty.adjustFilters',\n 'Try adjusting your search criteria or filters.'\n )}\n action={\n <Button variant=\"outline\" onClick={clearFilters}>\n {tr('proserviceworld.providers.filters.clear', 'Clear Filters')}\n </Button>\n }\n />\n )}\n\n {/* Provider Statistics — the single emphasised insight zone */}\n {filteredProviders.length > 0 && (\n <EmphasisPanel className=\"p-8\">\n <div className=\"text-center mb-8\">\n <h2 className=\"text-xl font-bold tracking-tight\">\n {tr('proserviceworld.providers.stats.title', 'Provider Statistics')}\n </h2>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-8\">\n <div className=\"text-center\">\n <div className=\"flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4\">\n <Star className=\"h-6 w-6 text-text-primary\" />\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{avgRating}</div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.providers.stats.averageRating', 'Average Rating')}\n </div>\n </div>\n <div className=\"text-center\">\n <div className=\"flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4\">\n <Users className=\"h-6 w-6 text-text-primary\" />\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{filteredProviders.length}</div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.providers.stats.expertProviders', 'Expert Providers')}\n </div>\n </div>\n <div className=\"text-center\">\n <div className=\"flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4\">\n <MapPin className=\"h-6 w-6 text-text-primary\" />\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{countries}</div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.providers.stats.countries', 'Countries')}\n </div>\n </div>\n </div>\n </EmphasisPanel>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProvidersPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ProvidersPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Card,\n CardContent,\n Button,\n Badge,\n Input,\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Filter,\n Star,\n Users,\n MapPin,\n CheckCircle,\n Clock,\n Briefcase,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { ServiceCategory } from '../types';\nimport { tWithFallback } from '../utils/i18n';\n\nconst categoryOptions: { value: ServiceCategory | ''; key: string; fallback: string }[] = [\n {\n value: '',\n key: 'proserviceworld.shared.filters.allCategories',\n fallback: 'All Categories',\n },\n {\n value: 'business_consulting',\n key: 'proserviceworld.shared.categories.businessConsulting',\n fallback: 'Business Consulting',\n },\n {\n value: 'financial_services',\n key: 'proserviceworld.shared.categories.financialServices',\n fallback: 'Financial Services',\n },\n {\n value: 'legal_services',\n key: 'proserviceworld.shared.categories.legalServices',\n fallback: 'Legal Services',\n },\n {\n value: 'accounting_bookkeeping',\n key: 'proserviceworld.shared.categories.accountingBookkeeping',\n fallback: 'Accounting & Bookkeeping',\n },\n {\n value: 'marketing_advertising',\n key: 'proserviceworld.shared.categories.marketingAdvertising',\n fallback: 'Marketing & Advertising',\n },\n {\n value: 'it_technology',\n key: 'proserviceworld.shared.categories.itTechnology',\n fallback: 'IT & Technology',\n },\n {\n value: 'human_resources',\n key: 'proserviceworld.shared.categories.humanResources',\n fallback: 'Human Resources',\n },\n {\n value: 'creative_design',\n key: 'proserviceworld.shared.categories.creativeDesign',\n fallback: 'Creative & Design',\n },\n {\n value: 'education_training',\n key: 'proserviceworld.shared.categories.educationTraining',\n fallback: 'Education & Training',\n },\n];\n\nexport function ProvidersPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n const { providers } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedCategory, setSelectedCategory] = useState<ServiceCategory | ''>('');\n const [minRating, setMinRating] = useState<number | ''>('');\n const [showFilters, setShowFilters] = useState(false);\n\n const filteredProviders = useMemo(() => {\n let result = [...providers];\n\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (p) =>\n p.name.toLowerCase().includes(q) ||\n p.businessName.toLowerCase().includes(q) ||\n p.tagline.toLowerCase().includes(q) ||\n p.specializations.some((s) => s.toLowerCase().includes(q))\n );\n }\n\n if (selectedCategory) {\n result = result.filter((p) => p.category === selectedCategory);\n }\n\n if (minRating) {\n result = result.filter((p) => p.rating >= minRating);\n }\n\n result.sort((a, b) => b.rating - a.rating);\n return result;\n }, [providers, searchQuery, selectedCategory, minRating]);\n\n const avgRating =\n filteredProviders.length > 0\n ? (\n filteredProviders.reduce((sum, p) => sum + p.rating, 0) / filteredProviders.length\n ).toFixed(1)\n : '0';\n\n const countries = new Set(filteredProviders.map((p) => p.country)).size;\n\n const clearFilters = () => {\n setSearchQuery('');\n setSelectedCategory('');\n setMinRating('');\n };\n const subtitle = searchQuery\n ? tr('proserviceworld.providers.subtitleWithQuery', '{{count}} providers found for \"{{query}}\"', {\n count: filteredProviders.length,\n query: searchQuery,\n })\n : tr('proserviceworld.providers.subtitle', '{{count}} providers found', {\n count: filteredProviders.length,\n });\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n {/* Hero header — the ONE aurora backdrop for this MFE */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.providers.title', 'Service Providers')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{subtitle}</p>\n </div>\n <Button\n variant=\"outline\"\n onClick={() => setShowFilters(!showFilters)}\n aria-expanded={showFilters}\n >\n <Filter className=\"h-4 w-4 mr-2\" />\n {tr('proserviceworld.providers.actions.filters', 'Filters')}\n </Button>\n </div>\n </div>\n\n <PagePurpose icon={<Users className=\"h-4 w-4\" />}>\n {tr(\n 'proserviceworld.providers.purpose',\n 'Find and vet the experts behind the work. Search by name, business, or specialization and filter by category and rating to shortlist trusted providers — then open a profile to view their services, reviews, and credentials before reaching out.'\n )}\n </PagePurpose>\n\n {/* Search Bar */}\n <div className=\"flex gap-4\">\n <div className=\"flex-1 relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-text-secondary\" />\n <Input\n type=\"text\"\n placeholder={tr(\n 'proserviceworld.providers.search.placeholder',\n 'Search providers by name, business, or specialization...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10 h-12\"\n />\n </div>\n </div>\n\n {/* Filters Panel */}\n {showFilters && (\n <Card className=\"border-border-seam\">\n <CardContent className=\"p-6\">\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('proserviceworld.providers.filters.category', 'Category')}\n </label>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as ServiceCategory | '')}\n className=\"w-full p-2 border border-border-seam rounded-md bg-bg-surface text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n {categoryOptions.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {tr(opt.key, opt.fallback)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium mb-2\">\n {tr('proserviceworld.providers.filters.minimumRating', 'Minimum Rating')}\n </label>\n <select\n value={minRating}\n onChange={(e) => setMinRating(e.target.value ? Number(e.target.value) : '')}\n className=\"w-full p-2 border border-border-seam rounded-md bg-bg-surface text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <option value=\"\">\n {tr('proserviceworld.providers.filters.anyRating', 'Any Rating')}\n </option>\n <option value=\"4\">\n {tr('proserviceworld.providers.filters.rating4', '4+ Stars')}\n </option>\n <option value=\"4.5\">\n {tr('proserviceworld.providers.filters.rating45', '4.5+ Stars')}\n </option>\n <option value=\"4.8\">\n {tr('proserviceworld.providers.filters.rating48', '4.8+ Stars')}\n </option>\n </select>\n </div>\n <div className=\"flex items-end\">\n <Button variant=\"outline\" onClick={clearFilters} className=\"w-full\">\n {tr('proserviceworld.providers.filters.clear', 'Clear Filters')}\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Provider Grid */}\n {filteredProviders.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6\">\n {filteredProviders.map((provider) => (\n <GlassCard key={provider.id} treatment=\"glass\" className=\"border-border-seam transition-shadow hover:shadow-pop\">\n <div className=\"flex items-center space-x-4 mb-4\">\n <div className=\"h-12 w-12 rounded-full bg-accent-soft flex items-center justify-center\">\n <span className=\"text-text-primary font-bold\">{provider.name.charAt(0)}</span>\n </div>\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"font-semibold truncate\">{provider.businessName}</h3>\n <p className=\"text-sm text-text-secondary truncate\">{provider.name}</p>\n </div>\n {provider.verified && (\n <CheckCircle className=\"h-5 w-5 text-accent-blue shrink-0\" aria-label=\"Verified\" />\n )}\n </div>\n\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">{provider.tagline}</p>\n\n <div className=\"flex flex-wrap gap-1 mb-3\">\n {provider.specializations.slice(0, 2).map((spec) => (\n <Badge key={spec} variant=\"secondary\" className=\"text-xs\">\n {spec}\n </Badge>\n ))}\n {provider.specializations.length > 2 && (\n <Badge variant=\"outline\" className=\"text-xs\">\n +{provider.specializations.length - 2}\n </Badge>\n )}\n </div>\n\n <div className=\"flex items-center justify-between text-sm mb-3\">\n <div className=\"flex items-center\">\n <Star className=\"h-4 w-4 text-status-warning-text fill-current mr-1\" />\n <span className=\"font-medium tabular-nums\">{provider.rating.toFixed(1)}</span>\n <span className=\"text-text-secondary ml-1 tabular-nums\">\n ({provider.totalReviews})\n </span>\n </div>\n <div className=\"flex items-center text-text-secondary\">\n <MapPin className=\"h-3 w-3 mr-1\" />\n <span>{provider.location}</span>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2 text-xs text-text-secondary border-t border-border-seam pt-3\">\n <div className=\"flex items-center\">\n <Clock className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.providers.card.responseTime', '{{count}}h response', {\n count: provider.responseTime,\n })}\n </div>\n <div className=\"flex items-center\">\n <Briefcase className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.providers.card.projects', '{{count}} projects', {\n count: provider.projectsCompleted,\n })}\n </div>\n </div>\n\n <Button variant=\"outline\" size=\"sm\" className=\"w-full mt-4\">\n {tr('proserviceworld.providers.actions.viewProfile', 'View Profile')}\n </Button>\n </GlassCard>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tr('proserviceworld.providers.empty.title', 'No providers found')}\n description={tr(\n 'proserviceworld.shared.empty.adjustFilters',\n 'Try adjusting your search criteria or filters.'\n )}\n action={\n <Button variant=\"outline\" onClick={clearFilters}>\n {tr('proserviceworld.providers.filters.clear', 'Clear Filters')}\n </Button>\n }\n />\n )}\n\n {/* Provider Statistics — the single emphasised insight zone */}\n {filteredProviders.length > 0 && (\n <EmphasisPanel className=\"p-8\">\n <div className=\"text-center mb-8\">\n <h2 className=\"text-xl font-bold tracking-tight\">\n {tr('proserviceworld.providers.stats.title', 'Provider Statistics')}\n </h2>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-8\">\n <div className=\"text-center\">\n <div className=\"flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4\">\n <Star className=\"h-6 w-6 text-text-primary\" />\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{avgRating}</div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.providers.stats.averageRating', 'Average Rating')}\n </div>\n </div>\n <div className=\"text-center\">\n <div className=\"flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4\">\n <Users className=\"h-6 w-6 text-text-primary\" />\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{filteredProviders.length}</div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.providers.stats.expertProviders', 'Expert Providers')}\n </div>\n </div>\n <div className=\"text-center\">\n <div className=\"flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4\">\n <MapPin className=\"h-6 w-6 text-text-primary\" />\n </div>\n <div className=\"text-2xl font-bold tabular-nums\">{countries}</div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.providers.stats.countries', 'Countries')}\n </div>\n </div>\n </div>\n </EmphasisPanel>\n )}\n </div>\n );\n}\n"],"mappings":"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"}