@burdenoff/microfe-proserviceworld 2026.703.1 → 2026.706.1
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.
- package/dist/index.js +2 -3
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/proserviceworld/ProServiceWorldRoot.js +92 -136
- package/dist/proserviceworld/ProServiceWorldRoot.js.map +1 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.js +18 -26
- package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
- package/dist/proserviceworld/components/ui.js +273 -0
- package/dist/proserviceworld/components/ui.js.map +1 -0
- package/dist/proserviceworld/hooks/useFiles.js +45 -0
- package/dist/proserviceworld/hooks/useFiles.js.map +1 -0
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js +416 -0
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -0
- package/dist/proserviceworld/index.js +0 -1
- package/dist/proserviceworld/pages/AnalyticsPage.js +163 -475
- package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ClientDetailPage.js +238 -0
- package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -0
- package/dist/proserviceworld/pages/ClientsPage.js +295 -0
- package/dist/proserviceworld/pages/ClientsPage.js.map +1 -0
- package/dist/proserviceworld/pages/CompliancePage.js +307 -0
- package/dist/proserviceworld/pages/CompliancePage.js.map +1 -0
- package/dist/proserviceworld/pages/ConflictsPage.js +234 -0
- package/dist/proserviceworld/pages/ConflictsPage.js.map +1 -0
- package/dist/proserviceworld/pages/DashboardPage.js +179 -632
- package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
- package/dist/proserviceworld/pages/DocumentsPage.js +235 -539
- package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
- package/dist/proserviceworld/pages/EngagementDetailPage.js +444 -0
- package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -0
- package/dist/proserviceworld/pages/EngagementsPage.js +256 -0
- package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -0
- package/dist/proserviceworld/pages/InvoicesPage.js +303 -0
- package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -0
- package/dist/proserviceworld/pages/MattersPage.js +275 -0
- package/dist/proserviceworld/pages/MattersPage.js.map +1 -0
- package/dist/proserviceworld/pages/PracticeAreasPage.js +176 -0
- package/dist/proserviceworld/pages/PracticeAreasPage.js.map +1 -0
- package/dist/proserviceworld/pages/TimePage.js +310 -0
- package/dist/proserviceworld/pages/TimePage.js.map +1 -0
- package/dist/proserviceworld/utils/cn.js +10 -0
- package/dist/proserviceworld/utils/cn.js.map +1 -0
- package/dist/proserviceworld/utils/nav.js +11 -0
- package/dist/proserviceworld/utils/nav.js.map +1 -0
- package/package.json +1 -1
- package/dist/proserviceworld/pages/AdminReportsPage.js +0 -579
- package/dist/proserviceworld/pages/AdminReportsPage.js.map +0 -1
- package/dist/proserviceworld/pages/AdminUsersPage.js +0 -468
- package/dist/proserviceworld/pages/AdminUsersPage.js.map +0 -1
- package/dist/proserviceworld/pages/BookingsPage.js +0 -446
- package/dist/proserviceworld/pages/BookingsPage.js.map +0 -1
- package/dist/proserviceworld/pages/MessagesPage.js +0 -238
- package/dist/proserviceworld/pages/MessagesPage.js.map +0 -1
- package/dist/proserviceworld/pages/PaymentsPage.js +0 -537
- package/dist/proserviceworld/pages/PaymentsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ProjectsPage.js +0 -627
- package/dist/proserviceworld/pages/ProjectsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ProviderDetailPage.js +0 -538
- package/dist/proserviceworld/pages/ProviderDetailPage.js.map +0 -1
- package/dist/proserviceworld/pages/ProvidersPage.js +0 -347
- package/dist/proserviceworld/pages/ProvidersPage.js.map +0 -1
- package/dist/proserviceworld/pages/ReviewsPage.js +0 -356
- package/dist/proserviceworld/pages/ReviewsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ServiceDetailsPage.js +0 -631
- package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ServicesPage.js +0 -344
- package/dist/proserviceworld/pages/ServicesPage.js.map +0 -1
- package/dist/proserviceworld/pages/VerificationPage.js +0 -370
- package/dist/proserviceworld/pages/VerificationPage.js.map +0 -1
- package/dist/proserviceworld/store/proserviceworldStore.js +0 -2490
- package/dist/proserviceworld/store/proserviceworldStore.js.map +0 -1
- package/dist/proserviceworld/utils/i18n.js +0 -15
- package/dist/proserviceworld/utils/i18n.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
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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"}
|
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
import { useProServiceWorldStore as e } from "../store/proserviceworldStore.js";
|
|
2
|
-
import { tWithFallback as t } from "../utils/i18n.js";
|
|
3
|
-
import { useMemo as n, useState as r } from "react";
|
|
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
|
-
import { useI18n as f } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
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, PagePurpose as T } from "@burdenoff/fe-libs/ui";
|
|
8
|
-
//#region src/proserviceworld/pages/ProvidersPage.tsx
|
|
9
|
-
var E = [
|
|
10
|
-
{
|
|
11
|
-
value: "",
|
|
12
|
-
key: "proserviceworld.shared.filters.allCategories",
|
|
13
|
-
fallback: "All Categories"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
value: "business_consulting",
|
|
17
|
-
key: "proserviceworld.shared.categories.businessConsulting",
|
|
18
|
-
fallback: "Business Consulting"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
value: "financial_services",
|
|
22
|
-
key: "proserviceworld.shared.categories.financialServices",
|
|
23
|
-
fallback: "Financial Services"
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
value: "legal_services",
|
|
27
|
-
key: "proserviceworld.shared.categories.legalServices",
|
|
28
|
-
fallback: "Legal Services"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
value: "accounting_bookkeeping",
|
|
32
|
-
key: "proserviceworld.shared.categories.accountingBookkeeping",
|
|
33
|
-
fallback: "Accounting & Bookkeeping"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
value: "marketing_advertising",
|
|
37
|
-
key: "proserviceworld.shared.categories.marketingAdvertising",
|
|
38
|
-
fallback: "Marketing & Advertising"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
value: "it_technology",
|
|
42
|
-
key: "proserviceworld.shared.categories.itTechnology",
|
|
43
|
-
fallback: "IT & Technology"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
value: "human_resources",
|
|
47
|
-
key: "proserviceworld.shared.categories.humanResources",
|
|
48
|
-
fallback: "Human Resources"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
value: "creative_design",
|
|
52
|
-
key: "proserviceworld.shared.categories.creativeDesign",
|
|
53
|
-
fallback: "Creative & Design"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
value: "education_training",
|
|
57
|
-
key: "proserviceworld.shared.categories.educationTraining",
|
|
58
|
-
fallback: "Education & Training"
|
|
59
|
-
}
|
|
60
|
-
];
|
|
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
|
-
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
|
-
}
|
|
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
|
-
}, [
|
|
70
|
-
k,
|
|
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
|
-
return /* @__PURE__ */ m("div", {
|
|
81
|
-
className: "space-y-6 p-6 bg-bg-canvas min-h-screen",
|
|
82
|
-
children: [
|
|
83
|
-
/* @__PURE__ */ m("div", {
|
|
84
|
-
className: "relative overflow-hidden rounded-card -mx-2 px-2 pt-1",
|
|
85
|
-
children: [/* @__PURE__ */ p(h, { intensity: "subtle" }), /* @__PURE__ */ m("div", {
|
|
86
|
-
className: "flex flex-col md:flex-row md:items-center md:justify-between gap-4",
|
|
87
|
-
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
|
|
88
|
-
className: "text-2xl font-semibold tracking-tight",
|
|
89
|
-
children: /* @__PURE__ */ p(S, { children: O("proserviceworld.providers.title", "Service Providers") })
|
|
90
|
-
}), /* @__PURE__ */ p("p", {
|
|
91
|
-
className: "text-sm text-text-secondary",
|
|
92
|
-
children: H
|
|
93
|
-
})] }), /* @__PURE__ */ m(_, {
|
|
94
|
-
variant: "outline",
|
|
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
|
-
})]
|
|
99
|
-
})]
|
|
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
|
-
}),
|
|
105
|
-
/* @__PURE__ */ p("div", {
|
|
106
|
-
className: "flex gap-4",
|
|
107
|
-
children: /* @__PURE__ */ m("div", {
|
|
108
|
-
className: "flex-1 relative",
|
|
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, {
|
|
110
|
-
type: "text",
|
|
111
|
-
placeholder: O("proserviceworld.providers.search.placeholder", "Search providers by name, business, or specialization..."),
|
|
112
|
-
value: A,
|
|
113
|
-
onChange: (e) => j(e.target.value),
|
|
114
|
-
className: "pl-10 h-12"
|
|
115
|
-
})]
|
|
116
|
-
})
|
|
117
|
-
}),
|
|
118
|
-
I && /* @__PURE__ */ p(v, {
|
|
119
|
-
className: "border-border-seam",
|
|
120
|
-
children: /* @__PURE__ */ p(y, {
|
|
121
|
-
className: "p-6",
|
|
122
|
-
children: /* @__PURE__ */ m("div", {
|
|
123
|
-
className: "grid grid-cols-1 md:grid-cols-3 gap-4",
|
|
124
|
-
children: [
|
|
125
|
-
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
126
|
-
className: "block text-sm font-medium mb-2",
|
|
127
|
-
children: O("proserviceworld.providers.filters.category", "Category")
|
|
128
|
-
}), /* @__PURE__ */ p("select", {
|
|
129
|
-
value: M,
|
|
130
|
-
onChange: (e) => N(e.target.value),
|
|
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",
|
|
132
|
-
children: E.map((e) => /* @__PURE__ */ p("option", {
|
|
133
|
-
value: e.value,
|
|
134
|
-
children: O(e.key, e.fallback)
|
|
135
|
-
}, e.value))
|
|
136
|
-
})] }),
|
|
137
|
-
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
138
|
-
className: "block text-sm font-medium mb-2",
|
|
139
|
-
children: O("proserviceworld.providers.filters.minimumRating", "Minimum Rating")
|
|
140
|
-
}), /* @__PURE__ */ m("select", {
|
|
141
|
-
value: P,
|
|
142
|
-
onChange: (e) => F(e.target.value ? Number(e.target.value) : ""),
|
|
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",
|
|
144
|
-
children: [
|
|
145
|
-
/* @__PURE__ */ p("option", {
|
|
146
|
-
value: "",
|
|
147
|
-
children: O("proserviceworld.providers.filters.anyRating", "Any Rating")
|
|
148
|
-
}),
|
|
149
|
-
/* @__PURE__ */ p("option", {
|
|
150
|
-
value: "4",
|
|
151
|
-
children: O("proserviceworld.providers.filters.rating4", "4+ Stars")
|
|
152
|
-
}),
|
|
153
|
-
/* @__PURE__ */ p("option", {
|
|
154
|
-
value: "4.5",
|
|
155
|
-
children: O("proserviceworld.providers.filters.rating45", "4.5+ Stars")
|
|
156
|
-
}),
|
|
157
|
-
/* @__PURE__ */ p("option", {
|
|
158
|
-
value: "4.8",
|
|
159
|
-
children: O("proserviceworld.providers.filters.rating48", "4.8+ Stars")
|
|
160
|
-
})
|
|
161
|
-
]
|
|
162
|
-
})] }),
|
|
163
|
-
/* @__PURE__ */ p("div", {
|
|
164
|
-
className: "flex items-end",
|
|
165
|
-
children: /* @__PURE__ */ p(_, {
|
|
166
|
-
variant: "outline",
|
|
167
|
-
onClick: V,
|
|
168
|
-
className: "w-full",
|
|
169
|
-
children: O("proserviceworld.providers.filters.clear", "Clear Filters")
|
|
170
|
-
})
|
|
171
|
-
})
|
|
172
|
-
]
|
|
173
|
-
})
|
|
174
|
-
})
|
|
175
|
-
}),
|
|
176
|
-
R.length > 0 ? /* @__PURE__ */ p("div", {
|
|
177
|
-
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6",
|
|
178
|
-
children: R.map((e) => /* @__PURE__ */ m(x, {
|
|
179
|
-
treatment: "glass",
|
|
180
|
-
className: "border-border-seam transition-shadow hover:shadow-pop",
|
|
181
|
-
children: [
|
|
182
|
-
/* @__PURE__ */ m("div", {
|
|
183
|
-
className: "flex items-center space-x-4 mb-4",
|
|
184
|
-
children: [
|
|
185
|
-
/* @__PURE__ */ p("div", {
|
|
186
|
-
className: "h-12 w-12 rounded-full bg-accent-soft flex items-center justify-center",
|
|
187
|
-
children: /* @__PURE__ */ p("span", {
|
|
188
|
-
className: "text-text-primary font-bold",
|
|
189
|
-
children: e.name.charAt(0)
|
|
190
|
-
})
|
|
191
|
-
}),
|
|
192
|
-
/* @__PURE__ */ m("div", {
|
|
193
|
-
className: "flex-1 min-w-0",
|
|
194
|
-
children: [/* @__PURE__ */ p("h3", {
|
|
195
|
-
className: "font-semibold truncate",
|
|
196
|
-
children: e.businessName
|
|
197
|
-
}), /* @__PURE__ */ p("p", {
|
|
198
|
-
className: "text-sm text-text-secondary truncate",
|
|
199
|
-
children: e.name
|
|
200
|
-
})]
|
|
201
|
-
}),
|
|
202
|
-
e.verified && /* @__PURE__ */ p(a, {
|
|
203
|
-
className: "h-5 w-5 text-accent-blue shrink-0",
|
|
204
|
-
"aria-label": "Verified"
|
|
205
|
-
})
|
|
206
|
-
]
|
|
207
|
-
}),
|
|
208
|
-
/* @__PURE__ */ p("p", {
|
|
209
|
-
className: "text-sm text-text-secondary mb-3 line-clamp-2",
|
|
210
|
-
children: e.tagline
|
|
211
|
-
}),
|
|
212
|
-
/* @__PURE__ */ m("div", {
|
|
213
|
-
className: "flex flex-wrap gap-1 mb-3",
|
|
214
|
-
children: [e.specializations.slice(0, 2).map((e) => /* @__PURE__ */ p(g, {
|
|
215
|
-
variant: "secondary",
|
|
216
|
-
className: "text-xs",
|
|
217
|
-
children: e
|
|
218
|
-
}, e)), e.specializations.length > 2 && /* @__PURE__ */ m(g, {
|
|
219
|
-
variant: "outline",
|
|
220
|
-
className: "text-xs",
|
|
221
|
-
children: ["+", e.specializations.length - 2]
|
|
222
|
-
})]
|
|
223
|
-
}),
|
|
224
|
-
/* @__PURE__ */ m("div", {
|
|
225
|
-
className: "flex items-center justify-between text-sm mb-3",
|
|
226
|
-
children: [/* @__PURE__ */ m("div", {
|
|
227
|
-
className: "flex items-center",
|
|
228
|
-
children: [
|
|
229
|
-
/* @__PURE__ */ p(u, { className: "h-4 w-4 text-status-warning-text fill-current mr-1" }),
|
|
230
|
-
/* @__PURE__ */ p("span", {
|
|
231
|
-
className: "font-medium tabular-nums",
|
|
232
|
-
children: e.rating.toFixed(1)
|
|
233
|
-
}),
|
|
234
|
-
/* @__PURE__ */ m("span", {
|
|
235
|
-
className: "text-text-secondary ml-1 tabular-nums",
|
|
236
|
-
children: [
|
|
237
|
-
"(",
|
|
238
|
-
e.totalReviews,
|
|
239
|
-
")"
|
|
240
|
-
]
|
|
241
|
-
})
|
|
242
|
-
]
|
|
243
|
-
}), /* @__PURE__ */ m("div", {
|
|
244
|
-
className: "flex items-center text-text-secondary",
|
|
245
|
-
children: [/* @__PURE__ */ p(c, { className: "h-3 w-3 mr-1" }), /* @__PURE__ */ p("span", { children: e.location })]
|
|
246
|
-
})]
|
|
247
|
-
}),
|
|
248
|
-
/* @__PURE__ */ m("div", {
|
|
249
|
-
className: "grid grid-cols-2 gap-2 text-xs text-text-secondary border-t border-border-seam pt-3",
|
|
250
|
-
children: [/* @__PURE__ */ m("div", {
|
|
251
|
-
className: "flex items-center",
|
|
252
|
-
children: [/* @__PURE__ */ p(o, { className: "h-3 w-3 mr-1" }), O("proserviceworld.providers.card.responseTime", "{{count}}h response", { count: e.responseTime })]
|
|
253
|
-
}), /* @__PURE__ */ m("div", {
|
|
254
|
-
className: "flex items-center",
|
|
255
|
-
children: [/* @__PURE__ */ p(i, { className: "h-3 w-3 mr-1" }), O("proserviceworld.providers.card.projects", "{{count}} projects", { count: e.projectsCompleted })]
|
|
256
|
-
})]
|
|
257
|
-
}),
|
|
258
|
-
/* @__PURE__ */ p(_, {
|
|
259
|
-
variant: "outline",
|
|
260
|
-
size: "sm",
|
|
261
|
-
className: "w-full mt-4",
|
|
262
|
-
children: O("proserviceworld.providers.actions.viewProfile", "View Profile")
|
|
263
|
-
})
|
|
264
|
-
]
|
|
265
|
-
}, e.id))
|
|
266
|
-
}) : /* @__PURE__ */ p(C, {
|
|
267
|
-
illustration: "empty-people",
|
|
268
|
-
title: O("proserviceworld.providers.empty.title", "No providers found"),
|
|
269
|
-
description: O("proserviceworld.shared.empty.adjustFilters", "Try adjusting your search criteria or filters."),
|
|
270
|
-
action: /* @__PURE__ */ p(_, {
|
|
271
|
-
variant: "outline",
|
|
272
|
-
onClick: V,
|
|
273
|
-
children: O("proserviceworld.providers.filters.clear", "Clear Filters")
|
|
274
|
-
})
|
|
275
|
-
}),
|
|
276
|
-
R.length > 0 && /* @__PURE__ */ m(b, {
|
|
277
|
-
className: "p-8",
|
|
278
|
-
children: [/* @__PURE__ */ p("div", {
|
|
279
|
-
className: "text-center mb-8",
|
|
280
|
-
children: /* @__PURE__ */ p("h2", {
|
|
281
|
-
className: "text-xl font-bold tracking-tight",
|
|
282
|
-
children: O("proserviceworld.providers.stats.title", "Provider Statistics")
|
|
283
|
-
})
|
|
284
|
-
}), /* @__PURE__ */ m("div", {
|
|
285
|
-
className: "grid grid-cols-1 md:grid-cols-3 gap-8",
|
|
286
|
-
children: [
|
|
287
|
-
/* @__PURE__ */ m("div", {
|
|
288
|
-
className: "text-center",
|
|
289
|
-
children: [
|
|
290
|
-
/* @__PURE__ */ p("div", {
|
|
291
|
-
className: "flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4",
|
|
292
|
-
children: /* @__PURE__ */ p(u, { className: "h-6 w-6 text-text-primary" })
|
|
293
|
-
}),
|
|
294
|
-
/* @__PURE__ */ p("div", {
|
|
295
|
-
className: "text-2xl font-bold tabular-nums",
|
|
296
|
-
children: z
|
|
297
|
-
}),
|
|
298
|
-
/* @__PURE__ */ p("div", {
|
|
299
|
-
className: "text-sm text-text-secondary",
|
|
300
|
-
children: O("proserviceworld.providers.stats.averageRating", "Average Rating")
|
|
301
|
-
})
|
|
302
|
-
]
|
|
303
|
-
}),
|
|
304
|
-
/* @__PURE__ */ m("div", {
|
|
305
|
-
className: "text-center",
|
|
306
|
-
children: [
|
|
307
|
-
/* @__PURE__ */ p("div", {
|
|
308
|
-
className: "flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4",
|
|
309
|
-
children: /* @__PURE__ */ p(d, { className: "h-6 w-6 text-text-primary" })
|
|
310
|
-
}),
|
|
311
|
-
/* @__PURE__ */ p("div", {
|
|
312
|
-
className: "text-2xl font-bold tabular-nums",
|
|
313
|
-
children: R.length
|
|
314
|
-
}),
|
|
315
|
-
/* @__PURE__ */ p("div", {
|
|
316
|
-
className: "text-sm text-text-secondary",
|
|
317
|
-
children: O("proserviceworld.providers.stats.expertProviders", "Expert Providers")
|
|
318
|
-
})
|
|
319
|
-
]
|
|
320
|
-
}),
|
|
321
|
-
/* @__PURE__ */ m("div", {
|
|
322
|
-
className: "text-center",
|
|
323
|
-
children: [
|
|
324
|
-
/* @__PURE__ */ p("div", {
|
|
325
|
-
className: "flex items-center justify-center w-12 h-12 mx-auto bg-accent-soft rounded-lg mb-4",
|
|
326
|
-
children: /* @__PURE__ */ p(c, { className: "h-6 w-6 text-text-primary" })
|
|
327
|
-
}),
|
|
328
|
-
/* @__PURE__ */ p("div", {
|
|
329
|
-
className: "text-2xl font-bold tabular-nums",
|
|
330
|
-
children: B
|
|
331
|
-
}),
|
|
332
|
-
/* @__PURE__ */ p("div", {
|
|
333
|
-
className: "text-sm text-text-secondary",
|
|
334
|
-
children: O("proserviceworld.providers.stats.countries", "Countries")
|
|
335
|
-
})
|
|
336
|
-
]
|
|
337
|
-
})
|
|
338
|
-
]
|
|
339
|
-
})]
|
|
340
|
-
})
|
|
341
|
-
]
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
//#endregion
|
|
345
|
-
export { D as ProvidersPage };
|
|
346
|
-
|
|
347
|
-
//# sourceMappingURL=ProvidersPage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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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"}
|