@burdenoff/microfe-proserviceworld 2026.625.1 → 2026.626.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.
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":"ServicesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ServicesPage.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 AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Search, Grid, List, Star, Clock, Tag } from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { ServiceCategory } from '../types';\nimport { tWithFallback } from '../utils/i18n';\n\nconst serviceCategoryLabels: Record<ServiceCategory, { key: string; fallback: string }> = {\n accounting_bookkeeping: {\n key: 'proserviceworld.shared.categories.accountingBookkeeping',\n fallback: 'Accounting & Bookkeeping',\n },\n business_consulting: {\n key: 'proserviceworld.shared.categories.businessConsulting',\n fallback: 'Business Consulting',\n },\n creative_design: {\n key: 'proserviceworld.shared.categories.creativeDesign',\n fallback: 'Creative & Design',\n },\n education_training: {\n key: 'proserviceworld.shared.categories.educationTraining',\n fallback: 'Education & Training',\n },\n financial_services: {\n key: 'proserviceworld.shared.categories.financialServices',\n fallback: 'Financial Services',\n },\n healthcare: { key: 'proserviceworld.shared.categories.healthcare', fallback: 'Healthcare' },\n human_resources: {\n key: 'proserviceworld.shared.categories.humanResources',\n fallback: 'Human Resources',\n },\n insurance: { key: 'proserviceworld.shared.categories.insurance', fallback: 'Insurance' },\n it_technology: {\n key: 'proserviceworld.shared.categories.itTechnology',\n fallback: 'IT & Technology',\n },\n legal_services: {\n key: 'proserviceworld.shared.categories.legalServices',\n fallback: 'Legal Services',\n },\n marketing_advertising: {\n key: 'proserviceworld.shared.categories.marketingAdvertising',\n fallback: 'Marketing & Advertising',\n },\n real_estate: { key: 'proserviceworld.shared.categories.realEstate', fallback: 'Real Estate' },\n};\n\nexport function ServicesPage() {\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 { services } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedCategory, setSelectedCategory] = useState<ServiceCategory | ''>('');\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [currentPage, setCurrentPage] = useState(1);\n const perPage = 12;\n\n const filtered = useMemo(() => {\n let result = [...services];\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (s) =>\n s.title.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.tags.some((t) => t.toLowerCase().includes(q))\n );\n }\n if (selectedCategory) result = result.filter((s) => s.category === selectedCategory);\n return result;\n }, [services, searchQuery, selectedCategory]);\n\n const totalPages = Math.ceil(filtered.length / perPage);\n const paged = filtered.slice((currentPage - 1) * perPage, currentPage * perPage);\n const subtitle = searchQuery\n ? tr('proserviceworld.services.subtitleWithQuery', '{{count}} services found for \"{{query}}\"', {\n count: filtered.length,\n query: searchQuery,\n })\n : tr('proserviceworld.services.subtitle', '{{count}} services found', {\n count: filtered.length,\n });\n const categoryLabel = (category: ServiceCategory): string => {\n const entry = serviceCategoryLabels[category];\n return tr(entry.key, entry.fallback);\n };\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1 flex flex-col md:flex-row md:items-center md:justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.services.title', 'Services')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{subtitle}</p>\n </div>\n <div className=\"flex items-center gap-2 mt-4 md:mt-0\">\n <Button\n variant={viewMode === 'grid' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setViewMode('grid')}\n >\n <Grid className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n <div className=\"flex flex-col sm:flex-row gap-4\">\n <div className=\"flex-1 relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tr('proserviceworld.services.search.placeholder', 'Search services...')}\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setCurrentPage(1);\n }}\n className=\"pl-10\"\n />\n </div>\n <select\n value={selectedCategory}\n onChange={(e) => {\n setSelectedCategory(e.target.value as ServiceCategory | '');\n setCurrentPage(1);\n }}\n className=\"px-4 py-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.shared.filters.allCategories', 'All Categories')}\n </option>\n <option value=\"financial_services\">{categoryLabel('financial_services')}</option>\n <option value=\"legal_services\">{categoryLabel('legal_services')}</option>\n <option value=\"marketing_advertising\">{categoryLabel('marketing_advertising')}</option>\n <option value=\"it_technology\">{categoryLabel('it_technology')}</option>\n <option value=\"human_resources\">{categoryLabel('human_resources')}</option>\n <option value=\"accounting_bookkeeping\">{categoryLabel('accounting_bookkeeping')}</option>\n <option value=\"creative_design\">{categoryLabel('creative_design')}</option>\n <option value=\"education_training\">{categoryLabel('education_training')}</option>\n </select>\n </div>\n\n {paged.length > 0 ? (\n <div\n className={\n viewMode === 'grid'\n ? 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'\n : 'space-y-4'\n }\n >\n {paged.map((service) => (\n <GlassCard\n key={service.id}\n treatment=\"glass\"\n glow={service.featured}\n className=\"border-border-seam p-0 transition-shadow hover:shadow-pop\"\n >\n <div className={viewMode === 'grid' ? 'p-6' : 'p-4 flex items-center gap-6'}>\n {viewMode === 'grid' ? (\n <>\n <div className=\"flex items-center justify-between mb-3\">\n <Badge variant=\"outline\" className=\"text-xs capitalize\">\n {categoryLabel(service.category)}\n </Badge>\n {service.featured && (\n <Badge>{tr('proserviceworld.services.badges.featured', 'Featured')}</Badge>\n )}\n </div>\n <h3 className=\"font-semibold mb-2\">{service.title}</h3>\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">\n {service.description}\n </p>\n <div className=\"flex items-center gap-2 mb-3 text-sm\">\n <div className=\"h-6 w-6 rounded-full bg-bg-sunken flex items-center justify-center text-xs\">\n {service.providerName.charAt(0)}\n </div>\n <span className=\"text-text-secondary\">{service.providerName}</span>\n {service.providerVerified && <CheckMark />}\n </div>\n <div className=\"flex items-center justify-between 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=\"tabular-nums\">{service.providerRating.toFixed(1)}</span>\n <span className=\"text-text-secondary ml-1 tabular-nums\">\n ({service.providerReviews})\n </span>\n </div>\n <span className=\"font-medium tabular-nums\">\n {tr('proserviceworld.services.card.pricing.from', 'From ${{amount}}', {\n amount: service.pricing.basePrice.toLocaleString(),\n })}\n </span>\n </div>\n <div className=\"flex flex-wrap gap-1 mt-3\">\n {service.tags.slice(0, 3).map((t) => (\n <span key={t} className=\"inline-block px-2 py-0.5 bg-bg-sunken text-xs rounded\">\n {t}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-4 mt-3 pt-3 border-t border-border-seam text-xs text-text-secondary\">\n <span className=\"flex items-center\">\n <Clock className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.services.card.meta.days', '{{count}} days', {\n count: service.duration.typical,\n })}\n </span>\n <span className=\"flex items-center\">\n <Tag className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.services.card.meta.bookings', '{{count}} bookings', {\n count: service.totalBookings,\n })}\n </span>\n </div>\n </>\n ) : (\n <>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <h3 className=\"font-semibold\">{service.title}</h3>\n {service.featured && (\n <Badge className=\"text-xs\">\n {tr('proserviceworld.services.badges.featured', 'Featured')}\n </Badge>\n )}\n </div>\n <p className=\"text-sm text-text-secondary mb-2 line-clamp-1\">\n {service.description}\n </p>\n <div className=\"flex items-center gap-3 text-sm text-text-secondary\">\n <span>{service.providerName}</span>\n <span className=\"flex items-center\">\n <Star className=\"h-3 w-3 text-status-warning-text fill-current mr-0.5\" />\n <span className=\"tabular-nums\">{service.providerRating.toFixed(1)}</span>\n </span>\n <span className=\"capitalize\">{categoryLabel(service.category)}</span>\n </div>\n </div>\n <div className=\"text-right shrink-0\">\n <div className=\"font-medium\">\n {tr('proserviceworld.services.card.pricing.from', 'From ${{amount}}', {\n amount: service.pricing.basePrice.toLocaleString(),\n })}\n </div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.services.card.meta.days', '{{count}} days', {\n count: service.duration.typical,\n })}\n </div>\n </div>\n </>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tr('proserviceworld.services.empty.title', 'No services found')}\n description={tr(\n 'proserviceworld.shared.empty.adjustFilters',\n 'Try adjusting your search criteria or filters.'\n )}\n />\n )}\n\n {totalPages > 1 && (\n <div className=\"flex justify-center gap-2\">\n <Button\n variant=\"outline\"\n disabled={currentPage === 1}\n onClick={() => setCurrentPage((p) => p - 1)}\n >\n {tr('proserviceworld.shared.pagination.previous', 'Previous')}\n </Button>\n <span className=\"flex items-center px-4 text-sm\">\n {tr('proserviceworld.shared.pagination.pageInfo', 'Page {{page}} of {{total}}', {\n page: currentPage,\n total: totalPages,\n })}\n </span>\n <Button\n variant=\"outline\"\n disabled={currentPage >= totalPages}\n onClick={() => setCurrentPage((p) => p + 1)}\n >\n {tr('proserviceworld.shared.pagination.next', 'Next')}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nfunction CheckMark() {\n return (\n <svg className=\"h-4 w-4 text-accent-blue\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ServicesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ServicesPage.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 AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Search, Grid, List, Star, Clock, Tag, Compass } from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { ServiceCategory } from '../types';\nimport { tWithFallback } from '../utils/i18n';\n\nconst serviceCategoryLabels: Record<ServiceCategory, { key: string; fallback: string }> = {\n accounting_bookkeeping: {\n key: 'proserviceworld.shared.categories.accountingBookkeeping',\n fallback: 'Accounting & Bookkeeping',\n },\n business_consulting: {\n key: 'proserviceworld.shared.categories.businessConsulting',\n fallback: 'Business Consulting',\n },\n creative_design: {\n key: 'proserviceworld.shared.categories.creativeDesign',\n fallback: 'Creative & Design',\n },\n education_training: {\n key: 'proserviceworld.shared.categories.educationTraining',\n fallback: 'Education & Training',\n },\n financial_services: {\n key: 'proserviceworld.shared.categories.financialServices',\n fallback: 'Financial Services',\n },\n healthcare: { key: 'proserviceworld.shared.categories.healthcare', fallback: 'Healthcare' },\n human_resources: {\n key: 'proserviceworld.shared.categories.humanResources',\n fallback: 'Human Resources',\n },\n insurance: { key: 'proserviceworld.shared.categories.insurance', fallback: 'Insurance' },\n it_technology: {\n key: 'proserviceworld.shared.categories.itTechnology',\n fallback: 'IT & Technology',\n },\n legal_services: {\n key: 'proserviceworld.shared.categories.legalServices',\n fallback: 'Legal Services',\n },\n marketing_advertising: {\n key: 'proserviceworld.shared.categories.marketingAdvertising',\n fallback: 'Marketing & Advertising',\n },\n real_estate: { key: 'proserviceworld.shared.categories.realEstate', fallback: 'Real Estate' },\n};\n\nexport function ServicesPage() {\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 { services } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedCategory, setSelectedCategory] = useState<ServiceCategory | ''>('');\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [currentPage, setCurrentPage] = useState(1);\n const perPage = 12;\n\n const filtered = useMemo(() => {\n let result = [...services];\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (s) =>\n s.title.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.tags.some((t) => t.toLowerCase().includes(q))\n );\n }\n if (selectedCategory) result = result.filter((s) => s.category === selectedCategory);\n return result;\n }, [services, searchQuery, selectedCategory]);\n\n const totalPages = Math.ceil(filtered.length / perPage);\n const paged = filtered.slice((currentPage - 1) * perPage, currentPage * perPage);\n const subtitle = searchQuery\n ? tr('proserviceworld.services.subtitleWithQuery', '{{count}} services found for \"{{query}}\"', {\n count: filtered.length,\n query: searchQuery,\n })\n : tr('proserviceworld.services.subtitle', '{{count}} services found', {\n count: filtered.length,\n });\n const categoryLabel = (category: ServiceCategory): string => {\n const entry = serviceCategoryLabels[category];\n return tr(entry.key, entry.fallback);\n };\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1 flex flex-col md:flex-row md:items-center md:justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.services.title', 'Services')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{subtitle}</p>\n </div>\n <div className=\"flex items-center gap-2 mt-4 md:mt-0\">\n <Button\n variant={viewMode === 'grid' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setViewMode('grid')}\n >\n <Grid className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n <PagePurpose icon={<Compass className=\"h-4 w-4\" />}>\n {tr(\n 'proserviceworld.services.purpose',\n 'Discover professional services from vetted providers. Search and filter by category to compare offerings, pricing, and ratings — then open a service to review packages and book the right fit for your project.'\n )}\n </PagePurpose>\n\n <div className=\"flex flex-col sm:flex-row gap-4\">\n <div className=\"flex-1 relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tr('proserviceworld.services.search.placeholder', 'Search services...')}\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setCurrentPage(1);\n }}\n className=\"pl-10\"\n />\n </div>\n <select\n value={selectedCategory}\n onChange={(e) => {\n setSelectedCategory(e.target.value as ServiceCategory | '');\n setCurrentPage(1);\n }}\n className=\"px-4 py-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.shared.filters.allCategories', 'All Categories')}\n </option>\n <option value=\"financial_services\">{categoryLabel('financial_services')}</option>\n <option value=\"legal_services\">{categoryLabel('legal_services')}</option>\n <option value=\"marketing_advertising\">{categoryLabel('marketing_advertising')}</option>\n <option value=\"it_technology\">{categoryLabel('it_technology')}</option>\n <option value=\"human_resources\">{categoryLabel('human_resources')}</option>\n <option value=\"accounting_bookkeeping\">{categoryLabel('accounting_bookkeeping')}</option>\n <option value=\"creative_design\">{categoryLabel('creative_design')}</option>\n <option value=\"education_training\">{categoryLabel('education_training')}</option>\n </select>\n </div>\n\n {paged.length > 0 ? (\n <div\n className={\n viewMode === 'grid'\n ? 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'\n : 'space-y-4'\n }\n >\n {paged.map((service) => (\n <GlassCard\n key={service.id}\n treatment=\"glass\"\n glow={service.featured}\n className=\"border-border-seam p-0 transition-shadow hover:shadow-pop\"\n >\n <div className={viewMode === 'grid' ? 'p-6' : 'p-4 flex items-center gap-6'}>\n {viewMode === 'grid' ? (\n <>\n <div className=\"flex items-center justify-between mb-3\">\n <Badge variant=\"outline\" className=\"text-xs capitalize\">\n {categoryLabel(service.category)}\n </Badge>\n {service.featured && (\n <Badge>{tr('proserviceworld.services.badges.featured', 'Featured')}</Badge>\n )}\n </div>\n <h3 className=\"font-semibold mb-2\">{service.title}</h3>\n <p className=\"text-sm text-text-secondary mb-3 line-clamp-2\">\n {service.description}\n </p>\n <div className=\"flex items-center gap-2 mb-3 text-sm\">\n <div className=\"h-6 w-6 rounded-full bg-bg-sunken flex items-center justify-center text-xs\">\n {service.providerName.charAt(0)}\n </div>\n <span className=\"text-text-secondary\">{service.providerName}</span>\n {service.providerVerified && <CheckMark />}\n </div>\n <div className=\"flex items-center justify-between 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=\"tabular-nums\">{service.providerRating.toFixed(1)}</span>\n <span className=\"text-text-secondary ml-1 tabular-nums\">\n ({service.providerReviews})\n </span>\n </div>\n <span className=\"font-medium tabular-nums\">\n {tr('proserviceworld.services.card.pricing.from', 'From ${{amount}}', {\n amount: service.pricing.basePrice.toLocaleString(),\n })}\n </span>\n </div>\n <div className=\"flex flex-wrap gap-1 mt-3\">\n {service.tags.slice(0, 3).map((t) => (\n <span key={t} className=\"inline-block px-2 py-0.5 bg-bg-sunken text-xs rounded\">\n {t}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-4 mt-3 pt-3 border-t border-border-seam text-xs text-text-secondary\">\n <span className=\"flex items-center\">\n <Clock className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.services.card.meta.days', '{{count}} days', {\n count: service.duration.typical,\n })}\n </span>\n <span className=\"flex items-center\">\n <Tag className=\"h-3 w-3 mr-1\" />\n {tr('proserviceworld.services.card.meta.bookings', '{{count}} bookings', {\n count: service.totalBookings,\n })}\n </span>\n </div>\n </>\n ) : (\n <>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <h3 className=\"font-semibold\">{service.title}</h3>\n {service.featured && (\n <Badge className=\"text-xs\">\n {tr('proserviceworld.services.badges.featured', 'Featured')}\n </Badge>\n )}\n </div>\n <p className=\"text-sm text-text-secondary mb-2 line-clamp-1\">\n {service.description}\n </p>\n <div className=\"flex items-center gap-3 text-sm text-text-secondary\">\n <span>{service.providerName}</span>\n <span className=\"flex items-center\">\n <Star className=\"h-3 w-3 text-status-warning-text fill-current mr-0.5\" />\n <span className=\"tabular-nums\">{service.providerRating.toFixed(1)}</span>\n </span>\n <span className=\"capitalize\">{categoryLabel(service.category)}</span>\n </div>\n </div>\n <div className=\"text-right shrink-0\">\n <div className=\"font-medium\">\n {tr('proserviceworld.services.card.pricing.from', 'From ${{amount}}', {\n amount: service.pricing.basePrice.toLocaleString(),\n })}\n </div>\n <div className=\"text-sm text-text-secondary\">\n {tr('proserviceworld.services.card.meta.days', '{{count}} days', {\n count: service.duration.typical,\n })}\n </div>\n </div>\n </>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tr('proserviceworld.services.empty.title', 'No services found')}\n description={tr(\n 'proserviceworld.shared.empty.adjustFilters',\n 'Try adjusting your search criteria or filters.'\n )}\n />\n )}\n\n {totalPages > 1 && (\n <div className=\"flex justify-center gap-2\">\n <Button\n variant=\"outline\"\n disabled={currentPage === 1}\n onClick={() => setCurrentPage((p) => p - 1)}\n >\n {tr('proserviceworld.shared.pagination.previous', 'Previous')}\n </Button>\n <span className=\"flex items-center px-4 text-sm\">\n {tr('proserviceworld.shared.pagination.pageInfo', 'Page {{page}} of {{total}}', {\n page: currentPage,\n total: totalPages,\n })}\n </span>\n <Button\n variant=\"outline\"\n disabled={currentPage >= totalPages}\n onClick={() => setCurrentPage((p) => p + 1)}\n >\n {tr('proserviceworld.shared.pagination.next', 'Next')}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nfunction CheckMark() {\n return (\n <svg className=\"h-4 w-4 text-accent-blue\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n"],"mappings":"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"}
@@ -2,9 +2,9 @@ import { useProServiceWorldStore as e } from "../store/proserviceworldStore.js";
2
2
  import { useState as t } from "react";
3
3
  import { AlertTriangle as n, ArrowRight as r, Award as i, Building2 as a, CheckCircle2 as o, ChevronRight as s, Clock as c, FileSearch as l, Fingerprint as u, Mail as d, MapPin as f, Phone as p, Shield as m, Upload as h, XCircle as g } from "lucide-react";
4
4
  import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
5
- import { AuroraBackground as b, Badge as x, Button as S, Card as C, CardContent as w, CardHeader as T, CardTitle as E, EmphasisPanel as D, GlassCard as O, GradientText as k, IllustratedEmptyState as A } from "@burdenoff/fe-libs/ui";
5
+ import { AuroraBackground as b, Badge as x, Button as S, Card as C, CardContent as w, CardHeader as T, CardTitle as E, EmphasisPanel as D, GlassCard as O, GradientText as k, IllustratedEmptyState as A, PagePurpose as j } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/proserviceworld/pages/VerificationPage.tsx
7
- var j = {
7
+ var M = {
8
8
  completed: {
9
9
  icon: o,
10
10
  color: "text-status-success-text",
@@ -29,7 +29,7 @@ var j = {
29
29
  bgColor: "bg-status-error-bg-subtle",
30
30
  label: "Failed"
31
31
  }
32
- }, M = {
32
+ }, N = {
33
33
  "Email Verification": d,
34
34
  "Phone Verification": p,
35
35
  "Identity Verification": u,
@@ -38,8 +38,8 @@ var j = {
38
38
  "Professional Verification": i,
39
39
  "Background Check": l
40
40
  };
41
- function N() {
42
- let { verificationSteps: i } = e(), [a, l] = t(null), u = i.filter((e) => e.status === "completed").length, d = i.length, f = i.filter((e) => e.required), p = f.filter((e) => e.status === "completed").length, g = Math.round(u / d * 100), N = a ? i.find((e) => e.id === a) : null;
41
+ function P() {
42
+ let { verificationSteps: i } = e(), [a, l] = t(null), u = i.filter((e) => e.status === "completed").length, d = i.length, f = i.filter((e) => e.required), p = f.filter((e) => e.status === "completed").length, g = Math.round(u / d * 100), P = a ? i.find((e) => e.id === a) : null;
43
43
  return /* @__PURE__ */ y("div", {
44
44
  className: "space-y-6 p-6 bg-bg-canvas min-h-screen",
45
45
  children: [
@@ -67,6 +67,10 @@ function N() {
67
67
  })]
68
68
  })]
69
69
  }),
70
+ /* @__PURE__ */ v(j, {
71
+ icon: /* @__PURE__ */ v(m, { className: "h-4 w-4" }),
72
+ children: "Verification is how you earn trust on ProServiceWorld. Completing these steps — email, phone, identity, and more — unlocks higher search ranking, badges, and premium listings. Pick a step to see what is needed and start, and watch your trust level climb as you go."
73
+ }),
70
74
  /* @__PURE__ */ v(D, { children: /* @__PURE__ */ y("div", {
71
75
  className: "grid gap-6 sm:grid-cols-3",
72
76
  children: [
@@ -151,7 +155,7 @@ function N() {
151
155
  className: "text-sm font-medium text-text-secondary",
152
156
  children: "Verification Steps"
153
157
  }), i.map((e, t) => {
154
- let n = j[e.status], r = n.icon, o = M[e.title] ?? m, c = t === i.length - 1, u = e.status === "in_progress";
158
+ let n = M[e.status], r = n.icon, o = N[e.title] ?? m, c = t === i.length - 1, u = e.status === "in_progress";
155
159
  return /* @__PURE__ */ y("div", {
156
160
  className: "relative",
157
161
  children: [!c && /* @__PURE__ */ v("div", { className: "absolute left-[23px] top-[52px] h-[calc(100%-16px)] w-0.5 bg-border-seam z-0" }), /* @__PURE__ */ v("button", {
@@ -206,47 +210,47 @@ function N() {
206
210
  })]
207
211
  }), /* @__PURE__ */ y("div", {
208
212
  className: "space-y-4",
209
- children: [N ? /* @__PURE__ */ y(O, {
213
+ children: [P ? /* @__PURE__ */ y(O, {
210
214
  treatment: "insight",
211
215
  className: "border-border-seam",
212
216
  children: [/* @__PURE__ */ v(T, { children: /* @__PURE__ */ v(E, {
213
217
  className: "text-base",
214
- children: N.title
218
+ children: P.title
215
219
  }) }), /* @__PURE__ */ y(w, {
216
220
  className: "space-y-4",
217
221
  children: [
218
222
  /* @__PURE__ */ v("p", {
219
223
  className: "text-sm text-text-secondary",
220
- children: N.description
224
+ children: P.description
221
225
  }),
222
226
  /* @__PURE__ */ v("div", {
223
227
  className: "flex items-center gap-2",
224
228
  children: (() => {
225
- let e = j[N.status], t = e.icon;
229
+ let e = M[P.status], t = e.icon;
226
230
  return /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v(t, { className: `h-5 w-5 ${e.color}` }), /* @__PURE__ */ v("span", {
227
231
  className: `font-medium ${e.color}`,
228
232
  children: e.label
229
233
  })] });
230
234
  })()
231
235
  }),
232
- N.required && /* @__PURE__ */ y("div", {
236
+ P.required && /* @__PURE__ */ y("div", {
233
237
  className: "flex items-center gap-2 rounded-lg bg-status-error-bg-subtle p-3",
234
238
  children: [/* @__PURE__ */ v(n, { className: "h-4 w-4 text-status-error-text" }), /* @__PURE__ */ v("span", {
235
239
  className: "text-sm text-status-error-text",
236
240
  children: "This step is required for full platform access."
237
241
  })]
238
242
  }),
239
- N.completedAt && /* @__PURE__ */ v("div", {
243
+ P.completedAt && /* @__PURE__ */ v("div", {
240
244
  className: "rounded-lg bg-status-success-bg-subtle p-3",
241
245
  children: /* @__PURE__ */ y("p", {
242
246
  className: "text-sm text-status-success-text",
243
- children: ["Completed on ", N.completedAt]
247
+ children: ["Completed on ", P.completedAt]
244
248
  })
245
249
  }),
246
- N.status === "pending" && /* @__PURE__ */ y("div", {
250
+ P.status === "pending" && /* @__PURE__ */ y("div", {
247
251
  className: "space-y-3",
248
252
  children: [
249
- N.title === "Phone Verification" && /* @__PURE__ */ y("div", {
253
+ P.title === "Phone Verification" && /* @__PURE__ */ y("div", {
250
254
  className: "space-y-2",
251
255
  children: [/* @__PURE__ */ v("p", {
252
256
  className: "text-sm font-medium",
@@ -264,7 +268,7 @@ function N() {
264
268
  })]
265
269
  })]
266
270
  }),
267
- N.title === "Identity Verification" && /* @__PURE__ */ y("div", {
271
+ P.title === "Identity Verification" && /* @__PURE__ */ y("div", {
268
272
  className: "space-y-2",
269
273
  children: [
270
274
  /* @__PURE__ */ v("p", {
@@ -291,13 +295,13 @@ function N() {
291
295
  })
292
296
  ]
293
297
  }),
294
- N.title !== "Phone Verification" && N.title !== "Identity Verification" && /* @__PURE__ */ y(S, {
298
+ P.title !== "Phone Verification" && P.title !== "Identity Verification" && /* @__PURE__ */ y(S, {
295
299
  className: "w-full",
296
300
  children: ["Start Verification ", /* @__PURE__ */ v(r, { className: "ml-2 h-4 w-4" })]
297
301
  })
298
302
  ]
299
303
  }),
300
- N.status === "failed" && /* @__PURE__ */ v(S, {
304
+ P.status === "failed" && /* @__PURE__ */ v(S, {
301
305
  variant: "destructive",
302
306
  className: "w-full",
303
307
  children: "Retry Verification"
@@ -361,6 +365,6 @@ function N() {
361
365
  });
362
366
  }
363
367
  //#endregion
364
- export { N as VerificationPage };
368
+ export { P as VerificationPage };
365
369
 
366
370
  //# sourceMappingURL=VerificationPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VerificationPage.js","names":[],"sources":["../../../src/proserviceworld/pages/VerificationPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n CheckCircle2,\n Clock,\n AlertTriangle,\n XCircle,\n Shield,\n Mail,\n Phone,\n Fingerprint,\n MapPin,\n Building2,\n Award,\n FileSearch,\n ChevronRight,\n Upload,\n ArrowRight,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { VerificationStepStatus } from '../types';\n\nconst statusConfig: Record<\n VerificationStepStatus,\n { icon: typeof CheckCircle2; color: string; bgColor: string; label: string }\n> = {\n completed: {\n icon: CheckCircle2,\n color: 'text-status-success-text',\n bgColor: 'bg-status-success-bg-subtle',\n label: 'Completed',\n },\n pending: {\n icon: Clock,\n color: 'text-text-secondary',\n bgColor: 'bg-bg-sunken',\n label: 'Pending',\n },\n in_progress: {\n icon: Clock,\n color: 'text-accent-blue',\n bgColor: 'bg-accent-blue-subtle',\n label: 'In Progress',\n },\n failed: {\n icon: XCircle,\n color: 'text-status-error-text',\n bgColor: 'bg-status-error-bg-subtle',\n label: 'Failed',\n },\n};\n\nconst stepIcons: Record<string, typeof Mail> = {\n 'Email Verification': Mail,\n 'Phone Verification': Phone,\n 'Identity Verification': Fingerprint,\n 'Address Verification': MapPin,\n 'Business Verification': Building2,\n 'Professional Verification': Award,\n 'Background Check': FileSearch,\n};\n\nexport function VerificationPage() {\n const { verificationSteps } = useProServiceWorldStore();\n const [selectedStepId, setSelectedStepId] = useState<string | null>(null);\n\n const completedCount = verificationSteps.filter((s) => s.status === 'completed').length;\n const totalSteps = verificationSteps.length;\n const requiredSteps = verificationSteps.filter((s) => s.required);\n const requiredCompleted = requiredSteps.filter((s) => s.status === 'completed').length;\n const progressPercent = Math.round((completedCount / totalSteps) * 100);\n\n const selectedStep = selectedStepId\n ? verificationSteps.find((s) => s.id === selectedStepId)\n : null;\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 page. */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>Verification</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Complete verification steps to unlock full platform features and build trust.\n </p>\n </div>\n <Badge variant={progressPercent === 100 ? 'default' : 'secondary'} className=\"text-sm\">\n <Shield className=\"mr-2 h-4 w-4\" />\n <span className=\"tabular-nums\">{progressPercent}%</span> Verified\n </Badge>\n </div>\n </div>\n\n {/* Overall progress — the single emphasised insight zone */}\n <EmphasisPanel>\n <div className=\"grid gap-6 sm:grid-cols-3\">\n <div className=\"space-y-2\">\n <p className=\"text-sm text-text-secondary\">Overall Progress</p>\n <p className=\"text-3xl font-bold tabular-nums\">\n {completedCount}/{totalSteps}\n </p>\n <div className=\"h-3 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-3 rounded-full bg-accent-blue transition-all\"\n style={{ width: `${progressPercent}%` }}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <p className=\"text-sm text-text-secondary\">Required Steps</p>\n <p className=\"text-3xl font-bold tabular-nums\">\n {requiredCompleted}/{requiredSteps.length}\n </p>\n <div className=\"h-3 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-3 rounded-full bg-status-success-text transition-all\"\n style={{\n width: `${requiredSteps.length > 0 ? Math.round((requiredCompleted / requiredSteps.length) * 100) : 0}%`,\n }}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <p className=\"text-sm text-text-secondary\">Trust Level</p>\n <p className=\"text-3xl font-bold\">\n {progressPercent >= 80 ? 'High' : progressPercent >= 40 ? 'Medium' : 'Low'}\n </p>\n <div className=\"flex gap-1\">\n {[1, 2, 3, 4, 5].map((level) => (\n <div\n key={level}\n className={`h-3 flex-1 rounded-full ${\n level <= Math.ceil(progressPercent / 20) ? 'bg-accent-blue' : 'bg-bg-sunken'\n }`}\n />\n ))}\n </div>\n </div>\n </div>\n </EmphasisPanel>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Steps list */}\n <div className=\"space-y-3 lg:col-span-2\">\n <h2 className=\"text-sm font-medium text-text-secondary\">Verification Steps</h2>\n {verificationSteps.map((step, idx) => {\n const cfg = statusConfig[step.status];\n const StatusIcon = cfg.icon;\n const StepIcon = stepIcons[step.title] ?? Shield;\n const isLast = idx === verificationSteps.length - 1;\n const isActive = step.status === 'in_progress';\n\n return (\n <div key={step.id} className=\"relative\">\n {/* Connector line */}\n {!isLast && (\n <div className=\"absolute left-[23px] top-[52px] h-[calc(100%-16px)] w-0.5 bg-border-seam z-0\" />\n )}\n\n <button\n onClick={() => setSelectedStepId(selectedStepId === step.id ? null : step.id)}\n aria-pressed={selectedStepId === step.id}\n className={`relative z-10 w-full rounded-lg border p-4 text-left transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n selectedStepId === step.id\n ? 'border-accent-blue bg-accent-blue-subtle'\n : 'border-border-seam hover:shadow-pop'\n } ${step.status === 'completed' ? 'opacity-80' : ''}`}\n >\n <div className=\"flex items-start gap-4\">\n {/* Step icon */}\n <div className={`shrink-0 rounded-full p-2 ${cfg.bgColor}`}>\n <StepIcon className={`h-5 w-5 ${cfg.color}`} />\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <h3\n className={`font-medium ${step.status === 'completed' ? 'line-through text-text-secondary' : ''}`}\n >\n {step.title}\n </h3>\n {step.required && (\n <Badge variant=\"destructive\" className=\"text-xs\">\n Required\n </Badge>\n )}\n </div>\n <p className=\"mt-0.5 text-sm text-text-secondary\">{step.description}</p>\n\n <div className=\"mt-2 flex items-center gap-3\">\n <div className=\"flex items-center gap-1\">\n <StatusIcon\n className={`h-4 w-4 ${cfg.color} ${isActive ? 'motion-safe:animate-vc-glow-pulse' : ''}`}\n />\n <span className={`text-xs font-medium ${cfg.color}`}>{cfg.label}</span>\n </div>\n {step.completedAt && (\n <span className=\"text-xs text-text-secondary\">\n Completed on {step.completedAt}\n </span>\n )}\n </div>\n </div>\n\n <ChevronRight className=\"h-5 w-5 shrink-0 text-text-secondary\" />\n </div>\n </button>\n </div>\n );\n })}\n </div>\n\n {/* Detail panel */}\n <div className=\"space-y-4\">\n {selectedStep ? (\n <GlassCard treatment=\"insight\" className=\"border-border-seam\">\n <CardHeader>\n <CardTitle className=\"text-base\">{selectedStep.title}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">{selectedStep.description}</p>\n\n <div className=\"flex items-center gap-2\">\n {(() => {\n const cfg = statusConfig[selectedStep.status];\n const Icon = cfg.icon;\n return (\n <>\n <Icon className={`h-5 w-5 ${cfg.color}`} />\n <span className={`font-medium ${cfg.color}`}>{cfg.label}</span>\n </>\n );\n })()}\n </div>\n\n {selectedStep.required && (\n <div className=\"flex items-center gap-2 rounded-lg bg-status-error-bg-subtle p-3\">\n <AlertTriangle className=\"h-4 w-4 text-status-error-text\" />\n <span className=\"text-sm text-status-error-text\">\n This step is required for full platform access.\n </span>\n </div>\n )}\n\n {selectedStep.completedAt && (\n <div className=\"rounded-lg bg-status-success-bg-subtle p-3\">\n <p className=\"text-sm text-status-success-text\">\n Completed on {selectedStep.completedAt}\n </p>\n </div>\n )}\n\n {selectedStep.status === 'pending' && (\n <div className=\"space-y-3\">\n {selectedStep.title === 'Phone Verification' && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Enter your phone number</p>\n <div className=\"flex gap-2\">\n <input\n type=\"tel\"\n aria-label=\"Phone number\"\n className=\"flex-1 rounded border border-border-seam bg-bg-surface px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n placeholder=\"+1 (555) 000-0000\"\n />\n <Button size=\"sm\">\n Send Code <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Button>\n </div>\n </div>\n )}\n {selectedStep.title === 'Identity Verification' && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Upload a government-issued ID</p>\n <div className=\"flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-border-seam p-6\">\n <Upload className=\"h-8 w-8 text-text-secondary\" />\n <p className=\"mt-2 text-xs text-text-secondary\">\n Drag & drop or click to upload\n </p>\n <p className=\"text-xs text-text-secondary\">\n Passport, Driver&apos;s License, or National ID\n </p>\n </div>\n <Button className=\"w-full\">\n <Upload className=\"mr-2 h-4 w-4\" /> Upload Document\n </Button>\n </div>\n )}\n {selectedStep.title !== 'Phone Verification' &&\n selectedStep.title !== 'Identity Verification' && (\n <Button className=\"w-full\">\n Start Verification <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n\n {selectedStep.status === 'failed' && (\n <Button variant=\"destructive\" className=\"w-full\">\n Retry Verification\n </Button>\n )}\n </CardContent>\n </GlassCard>\n ) : (\n <Card className=\"border-border-seam\">\n <CardContent className=\"py-6\">\n <IllustratedEmptyState\n illustration=\"onboarding\"\n title=\"Select a step\"\n description=\"Click on a verification step to see details and take action.\"\n />\n </CardContent>\n </Card>\n )}\n\n {/* Benefits card */}\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle className=\"text-base\">Verification Benefits</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {[\n { label: 'Higher search ranking', unlockAt: 20 },\n { label: 'Featured provider badge', unlockAt: 40 },\n { label: 'Priority support access', unlockAt: 60 },\n { label: 'Premium service listings', unlockAt: 80 },\n { label: 'Verified trust seal', unlockAt: 100 },\n ].map((benefit) => (\n <div\n key={benefit.label}\n className={`flex items-center gap-2 rounded p-2 text-sm ${\n progressPercent >= benefit.unlockAt\n ? 'text-text-primary'\n : 'text-text-secondary'\n }`}\n >\n {progressPercent >= benefit.unlockAt ? (\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text\" />\n ) : (\n <Clock className=\"h-4 w-4\" />\n )}\n <span>{benefit.label}</span>\n <span className=\"ml-auto text-xs tabular-nums\">{benefit.unlockAt}%</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VerificationPage.js","names":[],"sources":["../../../src/proserviceworld/pages/VerificationPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport {\n CheckCircle2,\n Clock,\n AlertTriangle,\n XCircle,\n Shield,\n Mail,\n Phone,\n Fingerprint,\n MapPin,\n Building2,\n Award,\n FileSearch,\n ChevronRight,\n Upload,\n ArrowRight,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { VerificationStepStatus } from '../types';\n\nconst statusConfig: Record<\n VerificationStepStatus,\n { icon: typeof CheckCircle2; color: string; bgColor: string; label: string }\n> = {\n completed: {\n icon: CheckCircle2,\n color: 'text-status-success-text',\n bgColor: 'bg-status-success-bg-subtle',\n label: 'Completed',\n },\n pending: {\n icon: Clock,\n color: 'text-text-secondary',\n bgColor: 'bg-bg-sunken',\n label: 'Pending',\n },\n in_progress: {\n icon: Clock,\n color: 'text-accent-blue',\n bgColor: 'bg-accent-blue-subtle',\n label: 'In Progress',\n },\n failed: {\n icon: XCircle,\n color: 'text-status-error-text',\n bgColor: 'bg-status-error-bg-subtle',\n label: 'Failed',\n },\n};\n\nconst stepIcons: Record<string, typeof Mail> = {\n 'Email Verification': Mail,\n 'Phone Verification': Phone,\n 'Identity Verification': Fingerprint,\n 'Address Verification': MapPin,\n 'Business Verification': Building2,\n 'Professional Verification': Award,\n 'Background Check': FileSearch,\n};\n\nexport function VerificationPage() {\n const { verificationSteps } = useProServiceWorldStore();\n const [selectedStepId, setSelectedStepId] = useState<string | null>(null);\n\n const completedCount = verificationSteps.filter((s) => s.status === 'completed').length;\n const totalSteps = verificationSteps.length;\n const requiredSteps = verificationSteps.filter((s) => s.required);\n const requiredCompleted = requiredSteps.filter((s) => s.status === 'completed').length;\n const progressPercent = Math.round((completedCount / totalSteps) * 100);\n\n const selectedStep = selectedStepId\n ? verificationSteps.find((s) => s.id === selectedStepId)\n : null;\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 page. */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>Verification</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Complete verification steps to unlock full platform features and build trust.\n </p>\n </div>\n <Badge variant={progressPercent === 100 ? 'default' : 'secondary'} className=\"text-sm\">\n <Shield className=\"mr-2 h-4 w-4\" />\n <span className=\"tabular-nums\">{progressPercent}%</span> Verified\n </Badge>\n </div>\n </div>\n\n <PagePurpose icon={<Shield className=\"h-4 w-4\" />}>\n Verification is how you earn trust on ProServiceWorld. Completing these steps — email,\n phone, identity, and more — unlocks higher search ranking, badges, and premium listings.\n Pick a step to see what is needed and start, and watch your trust level climb as you go.\n </PagePurpose>\n\n {/* Overall progress — the single emphasised insight zone */}\n <EmphasisPanel>\n <div className=\"grid gap-6 sm:grid-cols-3\">\n <div className=\"space-y-2\">\n <p className=\"text-sm text-text-secondary\">Overall Progress</p>\n <p className=\"text-3xl font-bold tabular-nums\">\n {completedCount}/{totalSteps}\n </p>\n <div className=\"h-3 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-3 rounded-full bg-accent-blue transition-all\"\n style={{ width: `${progressPercent}%` }}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <p className=\"text-sm text-text-secondary\">Required Steps</p>\n <p className=\"text-3xl font-bold tabular-nums\">\n {requiredCompleted}/{requiredSteps.length}\n </p>\n <div className=\"h-3 overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-3 rounded-full bg-status-success-text transition-all\"\n style={{\n width: `${requiredSteps.length > 0 ? Math.round((requiredCompleted / requiredSteps.length) * 100) : 0}%`,\n }}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <p className=\"text-sm text-text-secondary\">Trust Level</p>\n <p className=\"text-3xl font-bold\">\n {progressPercent >= 80 ? 'High' : progressPercent >= 40 ? 'Medium' : 'Low'}\n </p>\n <div className=\"flex gap-1\">\n {[1, 2, 3, 4, 5].map((level) => (\n <div\n key={level}\n className={`h-3 flex-1 rounded-full ${\n level <= Math.ceil(progressPercent / 20) ? 'bg-accent-blue' : 'bg-bg-sunken'\n }`}\n />\n ))}\n </div>\n </div>\n </div>\n </EmphasisPanel>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Steps list */}\n <div className=\"space-y-3 lg:col-span-2\">\n <h2 className=\"text-sm font-medium text-text-secondary\">Verification Steps</h2>\n {verificationSteps.map((step, idx) => {\n const cfg = statusConfig[step.status];\n const StatusIcon = cfg.icon;\n const StepIcon = stepIcons[step.title] ?? Shield;\n const isLast = idx === verificationSteps.length - 1;\n const isActive = step.status === 'in_progress';\n\n return (\n <div key={step.id} className=\"relative\">\n {/* Connector line */}\n {!isLast && (\n <div className=\"absolute left-[23px] top-[52px] h-[calc(100%-16px)] w-0.5 bg-border-seam z-0\" />\n )}\n\n <button\n onClick={() => setSelectedStepId(selectedStepId === step.id ? null : step.id)}\n aria-pressed={selectedStepId === step.id}\n className={`relative z-10 w-full rounded-lg border p-4 text-left transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n selectedStepId === step.id\n ? 'border-accent-blue bg-accent-blue-subtle'\n : 'border-border-seam hover:shadow-pop'\n } ${step.status === 'completed' ? 'opacity-80' : ''}`}\n >\n <div className=\"flex items-start gap-4\">\n {/* Step icon */}\n <div className={`shrink-0 rounded-full p-2 ${cfg.bgColor}`}>\n <StepIcon className={`h-5 w-5 ${cfg.color}`} />\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <h3\n className={`font-medium ${step.status === 'completed' ? 'line-through text-text-secondary' : ''}`}\n >\n {step.title}\n </h3>\n {step.required && (\n <Badge variant=\"destructive\" className=\"text-xs\">\n Required\n </Badge>\n )}\n </div>\n <p className=\"mt-0.5 text-sm text-text-secondary\">{step.description}</p>\n\n <div className=\"mt-2 flex items-center gap-3\">\n <div className=\"flex items-center gap-1\">\n <StatusIcon\n className={`h-4 w-4 ${cfg.color} ${isActive ? 'motion-safe:animate-vc-glow-pulse' : ''}`}\n />\n <span className={`text-xs font-medium ${cfg.color}`}>{cfg.label}</span>\n </div>\n {step.completedAt && (\n <span className=\"text-xs text-text-secondary\">\n Completed on {step.completedAt}\n </span>\n )}\n </div>\n </div>\n\n <ChevronRight className=\"h-5 w-5 shrink-0 text-text-secondary\" />\n </div>\n </button>\n </div>\n );\n })}\n </div>\n\n {/* Detail panel */}\n <div className=\"space-y-4\">\n {selectedStep ? (\n <GlassCard treatment=\"insight\" className=\"border-border-seam\">\n <CardHeader>\n <CardTitle className=\"text-base\">{selectedStep.title}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">{selectedStep.description}</p>\n\n <div className=\"flex items-center gap-2\">\n {(() => {\n const cfg = statusConfig[selectedStep.status];\n const Icon = cfg.icon;\n return (\n <>\n <Icon className={`h-5 w-5 ${cfg.color}`} />\n <span className={`font-medium ${cfg.color}`}>{cfg.label}</span>\n </>\n );\n })()}\n </div>\n\n {selectedStep.required && (\n <div className=\"flex items-center gap-2 rounded-lg bg-status-error-bg-subtle p-3\">\n <AlertTriangle className=\"h-4 w-4 text-status-error-text\" />\n <span className=\"text-sm text-status-error-text\">\n This step is required for full platform access.\n </span>\n </div>\n )}\n\n {selectedStep.completedAt && (\n <div className=\"rounded-lg bg-status-success-bg-subtle p-3\">\n <p className=\"text-sm text-status-success-text\">\n Completed on {selectedStep.completedAt}\n </p>\n </div>\n )}\n\n {selectedStep.status === 'pending' && (\n <div className=\"space-y-3\">\n {selectedStep.title === 'Phone Verification' && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Enter your phone number</p>\n <div className=\"flex gap-2\">\n <input\n type=\"tel\"\n aria-label=\"Phone number\"\n className=\"flex-1 rounded border border-border-seam bg-bg-surface px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n placeholder=\"+1 (555) 000-0000\"\n />\n <Button size=\"sm\">\n Send Code <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Button>\n </div>\n </div>\n )}\n {selectedStep.title === 'Identity Verification' && (\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Upload a government-issued ID</p>\n <div className=\"flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-border-seam p-6\">\n <Upload className=\"h-8 w-8 text-text-secondary\" />\n <p className=\"mt-2 text-xs text-text-secondary\">\n Drag & drop or click to upload\n </p>\n <p className=\"text-xs text-text-secondary\">\n Passport, Driver&apos;s License, or National ID\n </p>\n </div>\n <Button className=\"w-full\">\n <Upload className=\"mr-2 h-4 w-4\" /> Upload Document\n </Button>\n </div>\n )}\n {selectedStep.title !== 'Phone Verification' &&\n selectedStep.title !== 'Identity Verification' && (\n <Button className=\"w-full\">\n Start Verification <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n\n {selectedStep.status === 'failed' && (\n <Button variant=\"destructive\" className=\"w-full\">\n Retry Verification\n </Button>\n )}\n </CardContent>\n </GlassCard>\n ) : (\n <Card className=\"border-border-seam\">\n <CardContent className=\"py-6\">\n <IllustratedEmptyState\n illustration=\"onboarding\"\n title=\"Select a step\"\n description=\"Click on a verification step to see details and take action.\"\n />\n </CardContent>\n </Card>\n )}\n\n {/* Benefits card */}\n <Card className=\"border-border-seam\">\n <CardHeader>\n <CardTitle className=\"text-base\">Verification Benefits</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {[\n { label: 'Higher search ranking', unlockAt: 20 },\n { label: 'Featured provider badge', unlockAt: 40 },\n { label: 'Priority support access', unlockAt: 60 },\n { label: 'Premium service listings', unlockAt: 80 },\n { label: 'Verified trust seal', unlockAt: 100 },\n ].map((benefit) => (\n <div\n key={benefit.label}\n className={`flex items-center gap-2 rounded p-2 text-sm ${\n progressPercent >= benefit.unlockAt\n ? 'text-text-primary'\n : 'text-text-secondary'\n }`}\n >\n {progressPercent >= benefit.unlockAt ? (\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text\" />\n ) : (\n <Clock className=\"h-4 w-4\" />\n )}\n <span>{benefit.label}</span>\n <span className=\"ml-auto text-xs tabular-nums\">{benefit.unlockAt}%</span>\n </div>\n ))}\n </CardContent>\n </Card>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-proserviceworld",
3
- "version": "2026.625.1",
3
+ "version": "2026.626.1",
4
4
  "description": "Burdenoff ProServiceWorld Microfrontend",
5
5
  "type": "module",
6
6
  "files": [
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@apollo/client": "^4.0.11",
42
- "@burdenoff/fe-libs": "2026.625.3",
42
+ "@burdenoff/fe-libs": "2026.625.5",
43
43
  "@tanstack/react-query": "^5.90.16",
44
44
  "clsx": "^2.1.1",
45
45
  "graphql": "^16.10.0",