@burdenoff/microfe-proserviceworld 2026.512.1 → 2026.624.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/proserviceworld/pages/AdminReportsPage.js +28 -28
- package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
- package/dist/proserviceworld/pages/AdminUsersPage.js +19 -19
- package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
- package/dist/proserviceworld/pages/AnalyticsPage.js +27 -27
- package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
- package/dist/proserviceworld/pages/BookingsPage.js +24 -24
- package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
- package/dist/proserviceworld/pages/DashboardPage.js +33 -33
- package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
- package/dist/proserviceworld/pages/DocumentsPage.js +29 -29
- package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
- package/dist/proserviceworld/pages/MessagesPage.js +15 -15
- package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
- package/dist/proserviceworld/pages/PaymentsPage.js +19 -19
- package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ProjectsPage.js +36 -36
- package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ProviderDetailPage.js +36 -36
- package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
- package/dist/proserviceworld/pages/ProvidersPage.js +19 -19
- package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
- package/dist/proserviceworld/pages/ReviewsPage.js +22 -22
- package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ServiceDetailsPage.js +35 -35
- package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ServicesPage.js +14 -14
- package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
- package/dist/proserviceworld/pages/VerificationPage.js +23 -23
- package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
- package/package.json +1 -1
- package/dist/dev/main.d.ts +0 -2
- package/dist/dev/main.d.ts.map +0 -1
- package/dist/generated/global-operations.d.ts +0 -2
- package/dist/generated/global-operations.d.ts.map +0 -1
- package/dist/generated/global-types.d.ts +0 -18199
- package/dist/generated/global-types.d.ts.map +0 -1
- package/dist/generated/wspace-operations.d.ts +0 -2
- package/dist/generated/wspace-operations.d.ts.map +0 -1
- package/dist/generated/wspace-types.d.ts +0 -43046
- package/dist/generated/wspace-types.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/proserviceworld/ProServiceWorldRoot.d.ts +0 -5
- package/dist/proserviceworld/ProServiceWorldRoot.d.ts.map +0 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.d.ts +0 -2
- package/dist/proserviceworld/ProServiceWorldRoutes.d.ts.map +0 -1
- package/dist/proserviceworld/index.d.ts +0 -5
- package/dist/proserviceworld/index.d.ts.map +0 -1
- package/dist/proserviceworld/pages/AdminReportsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/AdminReportsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/AdminUsersPage.d.ts +0 -2
- package/dist/proserviceworld/pages/AdminUsersPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/AnalyticsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/AnalyticsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/BookingsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/BookingsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/DashboardPage.d.ts +0 -2
- package/dist/proserviceworld/pages/DashboardPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/DocumentsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/DocumentsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/MessagesPage.d.ts +0 -2
- package/dist/proserviceworld/pages/MessagesPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/PaymentsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/PaymentsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/ProjectsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/ProjectsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/ProviderDetailPage.d.ts +0 -2
- package/dist/proserviceworld/pages/ProviderDetailPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/ProvidersPage.d.ts +0 -2
- package/dist/proserviceworld/pages/ProvidersPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/ReviewsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/ReviewsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/ServiceDetailsPage.d.ts +0 -2
- package/dist/proserviceworld/pages/ServiceDetailsPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/ServicesPage.d.ts +0 -2
- package/dist/proserviceworld/pages/ServicesPage.d.ts.map +0 -1
- package/dist/proserviceworld/pages/VerificationPage.d.ts +0 -2
- package/dist/proserviceworld/pages/VerificationPage.d.ts.map +0 -1
- package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts +0 -6
- package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts.map +0 -1
- package/dist/proserviceworld/store/proserviceworldStore.d.ts +0 -32
- package/dist/proserviceworld/store/proserviceworldStore.d.ts.map +0 -1
- package/dist/proserviceworld/types/index.d.ts +0 -338
- package/dist/proserviceworld/types/index.d.ts.map +0 -1
- package/dist/proserviceworld/utils/cn.d.ts +0 -4
- package/dist/proserviceworld/utils/cn.d.ts.map +0 -1
- package/dist/proserviceworld/utils/i18n.d.ts +0 -6
- package/dist/proserviceworld/utils/i18n.d.ts.map +0 -1
- package/dist/proserviceworld/utils/navigation.d.ts +0 -2
- package/dist/proserviceworld/utils/navigation.d.ts.map +0 -1
|
@@ -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 { Card, CardContent, Button, Badge, Input } from '@burdenoff/fe-libs/ui';\nimport { Search, Filter, 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\">\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {tr('proserviceworld.services.title', 'Services')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{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-muted-foreground\" />\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-input rounded-md bg-background text-foreground\"\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 <Card key={service.id} className=\"hover:shadow-md transition-shadow\">\n <CardContent 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-muted-foreground 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-muted flex items-center justify-center text-xs\">\n {service.providerName.charAt(0)}\n </div>\n <span className=\"text-muted-foreground\">{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-yellow-400 fill-current mr-1\" />\n {service.providerRating.toFixed(1)}\n <span className=\"text-muted-foreground ml-1\">\n ({service.providerReviews})\n </span>\n </div>\n <span className=\"font-medium\">\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-muted text-xs rounded\">\n {t}\n </span>\n ))}\n </div>\n <div className=\"flex items-center gap-4 mt-3 pt-3 border-t text-xs text-muted-foreground\">\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-muted-foreground mb-2 line-clamp-1\">\n {service.description}\n </p>\n <div className=\"flex items-center gap-3 text-sm text-muted-foreground\">\n <span>{service.providerName}</span>\n <span className=\"flex items-center\">\n <Star className=\"h-3 w-3 text-yellow-400 fill-current mr-0.5\" />\n {service.providerRating.toFixed(1)}\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-muted-foreground\">\n {tr('proserviceworld.services.card.meta.days', '{{count}} days', {\n count: service.duration.typical,\n })}\n </div>\n </div>\n </>\n )}\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <div className=\"text-center py-12\">\n <Filter className=\"h-12 w-12 mx-auto text-muted-foreground mb-4\" />\n <h3 className=\"text-lg font-medium mb-2\">\n {tr('proserviceworld.services.empty.title', 'No services found')}\n </h3>\n <p className=\"text-muted-foreground\">\n {tr(\n 'proserviceworld.shared.empty.adjustFilters',\n 'Try adjusting your search criteria or filters.'\n )}\n </p>\n </div>\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-blue-600\" 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 { Card, CardContent, Button, Badge, Input } from '@burdenoff/fe-libs/ui';\nimport { Search, Filter, 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\">\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {tr('proserviceworld.services.title', 'Services')}\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-default rounded-md bg-bg-surface text-text-primary\"\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 <Card key={service.id} className=\"hover:shadow-md transition-shadow\">\n <CardContent 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-yellow-400 fill-current mr-1\" />\n {service.providerRating.toFixed(1)}\n <span className=\"text-text-secondary ml-1\">\n ({service.providerReviews})\n </span>\n </div>\n <span className=\"font-medium\">\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 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-yellow-400 fill-current mr-0.5\" />\n {service.providerRating.toFixed(1)}\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 </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <div className=\"text-center py-12\">\n <Filter className=\"h-12 w-12 mx-auto text-text-secondary mb-4\" />\n <h3 className=\"text-lg font-medium mb-2\">\n {tr('proserviceworld.services.empty.title', 'No services found')}\n </h3>\n <p className=\"text-text-secondary\">\n {tr(\n 'proserviceworld.shared.empty.adjustFilters',\n 'Try adjusting your search criteria or filters.'\n )}\n </p>\n </div>\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-blue-600\" 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":";;;;;;;;AAQA,IAAM,IAAoF;CACxF,wBAAwB;EACtB,KAAK;EACL,UAAU;EACX;CACD,qBAAqB;EACnB,KAAK;EACL,UAAU;EACX;CACD,iBAAiB;EACf,KAAK;EACL,UAAU;EACX;CACD,oBAAoB;EAClB,KAAK;EACL,UAAU;EACX;CACD,oBAAoB;EAClB,KAAK;EACL,UAAU;EACX;CACD,YAAY;EAAE,KAAK;EAAgD,UAAU;EAAc;CAC3F,iBAAiB;EACf,KAAK;EACL,UAAU;EACX;CACD,WAAW;EAAE,KAAK;EAA+C,UAAU;EAAa;CACxF,eAAe;EACb,KAAK;EACL,UAAU;EACX;CACD,gBAAgB;EACd,KAAK;EACL,UAAU;EACX;CACD,uBAAuB;EACrB,KAAK;EACL,UAAU;EACX;CACD,aAAa;EAAE,KAAK;EAAgD,UAAU;EAAe;CAC9F;AAED,SAAgB,IAAe;CAC7B,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,GAAkB,MACzC,EAAc,GAAG,GAAK,GAAU,EAAO,EACnC,EAAE,gBAAa,GAAyB,EACxC,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAkB,KAAuB,EAA+B,GAAG,EAC5E,CAAC,GAAU,KAAe,EAA0B,OAAO,EAC3D,CAAC,GAAa,KAAkB,EAAS,EAAE,EAG3C,IAAW,QAAc;EAC7B,IAAI,IAAS,CAAC,GAAG,EAAS;AAC1B,MAAI,GAAa;GACf,IAAM,IAAI,EAAY,aAAa;AACnC,OAAS,EAAO,QACb,MACC,EAAE,MAAM,aAAa,CAAC,SAAS,EAAE,IACjC,EAAE,YAAY,aAAa,CAAC,SAAS,EAAE,IACvC,EAAE,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CAClD;;AAGH,SADI,MAAkB,IAAS,EAAO,QAAQ,MAAM,EAAE,aAAa,EAAiB,GAC7E;IACN;EAAC;EAAU;EAAa;EAAiB,CAAC,EAEvC,IAAa,KAAK,KAAK,EAAS,SAAS,GAAQ,EACjD,IAAQ,EAAS,OAAO,IAAc,KAAK,IAAS,IAAc,GAAQ,EAC1E,IAAW,IACb,EAAG,8CAA8C,8CAA4C;EAC3F,OAAO,EAAS;EAChB,OAAO;EACR,CAAC,GACF,EAAG,qCAAqC,4BAA4B,EAClE,OAAO,EAAS,QACjB,CAAC,EACA,KAAiB,MAAsC;EAC3D,IAAM,IAAQ,EAAsB;AACpC,SAAO,EAAG,EAAM,KAAK,EAAM,SAAS;;AAGtC,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,kCAAkC,WAAW;KAC9C,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eAA+B;KAAa,CAAA,CACrD,EAAA,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,SAAS,MAAa,SAAS,YAAY;MAC3C,MAAK;MACL,eAAe,EAAY,OAAO;gBAElC,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;MACrB,CAAA,EACT,kBAAC,GAAD;MACE,SAAS,MAAa,SAAS,YAAY;MAC3C,MAAK;MACL,eAAe,EAAY,OAAO;gBAElC,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;MACrB,CAAA,CACL;OACF;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;MACE,aAAa,EAAG,+CAA+C,qBAAqB;MACpF,OAAO;MACP,WAAW,MAAM;AAEf,OADA,EAAe,EAAE,OAAO,MAAM,EAC9B,EAAe,EAAE;;MAEnB,WAAU;MACV,CAAA,CACE;QACN,kBAAC,UAAD;KACE,OAAO;KACP,WAAW,MAAM;AAEf,MADA,EAAoB,EAAE,OAAO,MAA8B,EAC3D,EAAe,EAAE;;KAEnB,WAAU;eANZ;MAQE,kBAAC,UAAD;OAAQ,OAAM;iBACX,EAAG,gDAAgD,iBAAiB;OAC9D,CAAA;MACT,kBAAC,UAAD;OAAQ,OAAM;iBAAsB,EAAc,qBAAqB;OAAU,CAAA;MACjF,kBAAC,UAAD;OAAQ,OAAM;iBAAkB,EAAc,iBAAiB;OAAU,CAAA;MACzE,kBAAC,UAAD;OAAQ,OAAM;iBAAyB,EAAc,wBAAwB;OAAU,CAAA;MACvF,kBAAC,UAAD;OAAQ,OAAM;iBAAiB,EAAc,gBAAgB;OAAU,CAAA;MACvE,kBAAC,UAAD;OAAQ,OAAM;iBAAmB,EAAc,kBAAkB;OAAU,CAAA;MAC3E,kBAAC,UAAD;OAAQ,OAAM;iBAA0B,EAAc,yBAAyB;OAAU,CAAA;MACzF,kBAAC,UAAD;OAAQ,OAAM;iBAAmB,EAAc,kBAAkB;OAAU,CAAA;MAC3E,kBAAC,UAAD;OAAQ,OAAM;iBAAsB,EAAc,qBAAqB;OAAU,CAAA;MAC1E;OACL;;GAEL,EAAM,SAAS,IACd,kBAAC,OAAD;IACE,WACE,MAAa,SACT,yDACA;cAGL,EAAM,KAAK,MACV,kBAAC,GAAD;KAAuB,WAAU;eAC/B,kBAAC,GAAD;MAAa,WAAW,MAAa,SAAS,QAAQ;gBACnD,MAAa,SACZ,kBAAA,GAAA,EAAA,UAAA;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;SAAU,WAAU;mBAChC,EAAc,EAAQ,SAAS;SAC1B,CAAA,EACP,EAAQ,YACP,kBAAC,GAAD,EAAA,UAAQ,EAAG,4CAA4C,WAAW,EAAS,CAAA,CAEzE;;OACN,kBAAC,MAAD;QAAI,WAAU;kBAAsB,EAAQ;QAAW,CAAA;OACvD,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAQ;QACP,CAAA;OACJ,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UAAK,WAAU;oBACZ,EAAQ,aAAa,OAAO,EAAE;UAC3B,CAAA;SACN,kBAAC,QAAD;UAAM,WAAU;oBAAuB,EAAQ;UAAoB,CAAA;SAClE,EAAQ,oBAAoB,kBAAC,GAAD,EAAa,CAAA;SACtC;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,GAAD,EAAM,WAAU,6CAA8C,CAAA;UAC7D,EAAQ,eAAe,QAAQ,EAAE;UAClC,kBAAC,QAAD;WAAM,WAAU;qBAAhB;YAA2C;YACvC,EAAQ;YAAgB;YACrB;;UACH;YACN,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAG,8CAA8C,oBAAoB,EACpE,QAAQ,EAAQ,QAAQ,UAAU,gBAAgB,EACnD,CAAC;SACG,CAAA,CACH;;OACN,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAQ,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,MAC7B,kBAAC,QAAD;SAAc,WAAU;mBACrB;SACI,EAFI,EAEJ,CACP;QACE,CAAA;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,GAAD,EAAO,WAAU,gBAAiB,CAAA,EACjC,EAAG,2CAA2C,kBAAkB,EAC/D,OAAO,EAAQ,SAAS,SACzB,CAAC,CACG;YACP,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,GAAD,EAAK,WAAU,gBAAiB,CAAA,EAC/B,EAAG,+CAA+C,sBAAsB,EACvE,OAAO,EAAQ,eAChB,CAAC,CACG;WACH;;OACL,EAAA,CAAA,GAEH,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,MAAD;UAAI,WAAU;oBAAiB,EAAQ;UAAW,CAAA,EACjD,EAAQ,YACP,kBAAC,GAAD;UAAO,WAAU;oBACd,EAAG,4CAA4C,WAAW;UACrD,CAAA,CAEN;;QACN,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAQ;SACP,CAAA;QACJ,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,QAAD,EAAA,UAAO,EAAQ,cAAoB,CAAA;UACnC,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CACE,kBAAC,GAAD,EAAM,WAAU,+CAAgD,CAAA,EAC/D,EAAQ,eAAe,QAAQ,EAAE,CAC7B;;UACP,kBAAC,QAAD;WAAM,WAAU;qBAAc,EAAc,EAAQ,SAAS;WAAQ,CAAA;UACjE;;QACF;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAG,8CAA8C,oBAAoB,EACpE,QAAQ,EAAQ,QAAQ,UAAU,gBAAgB,EACnD,CAAC;QACE,CAAA,EACN,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAG,2CAA2C,kBAAkB,EAC/D,OAAO,EAAQ,SAAS,SACzB,CAAC;QACE,CAAA,CACF;SACL,EAAA,CAAA;MAEO,CAAA;KACT,EAjGI,EAAQ,GAiGZ,CACP;IACE,CAAA,GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAQ,WAAU,8CAA+C,CAAA;KACjE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,wCAAwC,oBAAoB;MAC7D,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,8CACA,iDACD;MACC,CAAA;KACA;;GAGP,IAAa,KACZ,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,SAAQ;MACR,UAAU,MAAgB;MAC1B,eAAe,GAAgB,MAAM,IAAI,EAAE;gBAE1C,EAAG,8CAA8C,WAAW;MACtD,CAAA;KACT,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAG,8CAA8C,8BAA8B;OAC9E,MAAM;OACN,OAAO;OACR,CAAC;MACG,CAAA;KACP,kBAAC,GAAD;MACE,SAAQ;MACR,UAAU,KAAe;MACzB,eAAe,GAAgB,MAAM,IAAI,EAAE;gBAE1C,EAAG,0CAA0C,OAAO;MAC9C,CAAA;KACL;;GAEJ;;;AAIV,SAAS,IAAY;AACnB,QACE,kBAAC,OAAD;EAAK,WAAU;EAAwB,SAAQ;EAAY,MAAK;YAC9D,kBAAC,QAAD;GACE,UAAS;GACT,GAAE;GACF,UAAS;GACT,CAAA;EACE,CAAA"}
|
|
@@ -49,7 +49,7 @@ function O() {
|
|
|
49
49
|
className: "text-2xl font-semibold",
|
|
50
50
|
children: "Verification"
|
|
51
51
|
}), /* @__PURE__ */ v("p", {
|
|
52
|
-
className: "text-sm text-
|
|
52
|
+
className: "text-sm text-text-secondary",
|
|
53
53
|
children: "Complete verification steps to unlock full platform features and build trust."
|
|
54
54
|
})] }), /* @__PURE__ */ y(b, {
|
|
55
55
|
variant: g === 100 ? "default" : "secondary",
|
|
@@ -70,7 +70,7 @@ function O() {
|
|
|
70
70
|
className: "space-y-2",
|
|
71
71
|
children: [
|
|
72
72
|
/* @__PURE__ */ v("p", {
|
|
73
|
-
className: "text-sm text-
|
|
73
|
+
className: "text-sm text-text-secondary",
|
|
74
74
|
children: "Overall Progress"
|
|
75
75
|
}),
|
|
76
76
|
/* @__PURE__ */ y("p", {
|
|
@@ -82,9 +82,9 @@ function O() {
|
|
|
82
82
|
]
|
|
83
83
|
}),
|
|
84
84
|
/* @__PURE__ */ v("div", {
|
|
85
|
-
className: "h-3 overflow-hidden rounded-full bg-
|
|
85
|
+
className: "h-3 overflow-hidden rounded-full bg-bg-sunken",
|
|
86
86
|
children: /* @__PURE__ */ v("div", {
|
|
87
|
-
className: "h-3 rounded-full bg-primary transition-all",
|
|
87
|
+
className: "h-3 rounded-full bg-action-primary-bg transition-all",
|
|
88
88
|
style: { width: `${g}%` }
|
|
89
89
|
})
|
|
90
90
|
})
|
|
@@ -94,7 +94,7 @@ function O() {
|
|
|
94
94
|
className: "space-y-2",
|
|
95
95
|
children: [
|
|
96
96
|
/* @__PURE__ */ v("p", {
|
|
97
|
-
className: "text-sm text-
|
|
97
|
+
className: "text-sm text-text-secondary",
|
|
98
98
|
children: "Required Steps"
|
|
99
99
|
}),
|
|
100
100
|
/* @__PURE__ */ y("p", {
|
|
@@ -106,7 +106,7 @@ function O() {
|
|
|
106
106
|
]
|
|
107
107
|
}),
|
|
108
108
|
/* @__PURE__ */ v("div", {
|
|
109
|
-
className: "h-3 overflow-hidden rounded-full bg-
|
|
109
|
+
className: "h-3 overflow-hidden rounded-full bg-bg-sunken",
|
|
110
110
|
children: /* @__PURE__ */ v("div", {
|
|
111
111
|
className: "h-3 rounded-full bg-green-500 transition-all",
|
|
112
112
|
style: { width: `${f.length > 0 ? Math.round(p / f.length * 100) : 0}%` }
|
|
@@ -118,7 +118,7 @@ function O() {
|
|
|
118
118
|
className: "space-y-2",
|
|
119
119
|
children: [
|
|
120
120
|
/* @__PURE__ */ v("p", {
|
|
121
|
-
className: "text-sm text-
|
|
121
|
+
className: "text-sm text-text-secondary",
|
|
122
122
|
children: "Trust Level"
|
|
123
123
|
}),
|
|
124
124
|
/* @__PURE__ */ v("p", {
|
|
@@ -133,7 +133,7 @@ function O() {
|
|
|
133
133
|
3,
|
|
134
134
|
4,
|
|
135
135
|
5
|
|
136
|
-
].map((e) => /* @__PURE__ */ v("div", { className: `h-3 flex-1 rounded-full ${e <= Math.ceil(g / 20) ? "bg-primary" : "bg-
|
|
136
|
+
].map((e) => /* @__PURE__ */ v("div", { className: `h-3 flex-1 rounded-full ${e <= Math.ceil(g / 20) ? "bg-action-primary-bg" : "bg-bg-sunken"}` }, e))
|
|
137
137
|
})
|
|
138
138
|
]
|
|
139
139
|
})
|
|
@@ -145,15 +145,15 @@ function O() {
|
|
|
145
145
|
children: [/* @__PURE__ */ y("div", {
|
|
146
146
|
className: "space-y-3 lg:col-span-2",
|
|
147
147
|
children: [/* @__PURE__ */ v("h2", {
|
|
148
|
-
className: "text-sm font-medium text-
|
|
148
|
+
className: "text-sm font-medium text-text-secondary",
|
|
149
149
|
children: "Verification Steps"
|
|
150
150
|
}), i.map((e, t) => {
|
|
151
151
|
let n = E[e.status], r = n.icon, o = D[e.title] ?? m;
|
|
152
152
|
return /* @__PURE__ */ y("div", {
|
|
153
153
|
className: "relative",
|
|
154
|
-
children: [t !== i.length - 1 && /* @__PURE__ */ v("div", { className: "absolute left-[23px] top-[52px] h-[calc(100%-16px)] w-0.5 bg-
|
|
154
|
+
children: [t !== i.length - 1 && /* @__PURE__ */ v("div", { className: "absolute left-[23px] top-[52px] h-[calc(100%-16px)] w-0.5 bg-bg-sunken z-0" }), /* @__PURE__ */ v("button", {
|
|
155
155
|
onClick: () => l(a === e.id ? null : e.id),
|
|
156
|
-
className: `relative z-10 w-full rounded-lg border p-4 text-left transition-colors ${a === e.id ? "border-primary bg-primary/5" : "hover:bg-
|
|
156
|
+
className: `relative z-10 w-full rounded-lg border p-4 text-left transition-colors ${a === e.id ? "border-primary bg-action-primary-bg/5" : "hover:bg-bg-sunken/50"} ${e.status === "completed" ? "opacity-80" : ""}`,
|
|
157
157
|
children: /* @__PURE__ */ y("div", {
|
|
158
158
|
className: "flex items-start gap-4",
|
|
159
159
|
children: [
|
|
@@ -167,7 +167,7 @@ function O() {
|
|
|
167
167
|
/* @__PURE__ */ y("div", {
|
|
168
168
|
className: "flex items-center gap-2",
|
|
169
169
|
children: [/* @__PURE__ */ v("h3", {
|
|
170
|
-
className: `font-medium ${e.status === "completed" ? "line-through text-
|
|
170
|
+
className: `font-medium ${e.status === "completed" ? "line-through text-text-secondary" : ""}`,
|
|
171
171
|
children: e.title
|
|
172
172
|
}), e.required && /* @__PURE__ */ v(b, {
|
|
173
173
|
variant: "destructive",
|
|
@@ -176,7 +176,7 @@ function O() {
|
|
|
176
176
|
})]
|
|
177
177
|
}),
|
|
178
178
|
/* @__PURE__ */ v("p", {
|
|
179
|
-
className: "mt-0.5 text-sm text-
|
|
179
|
+
className: "mt-0.5 text-sm text-text-secondary",
|
|
180
180
|
children: e.description
|
|
181
181
|
}),
|
|
182
182
|
/* @__PURE__ */ y("div", {
|
|
@@ -188,13 +188,13 @@ function O() {
|
|
|
188
188
|
children: n.label
|
|
189
189
|
})]
|
|
190
190
|
}), e.completedAt && /* @__PURE__ */ y("span", {
|
|
191
|
-
className: "text-xs text-
|
|
191
|
+
className: "text-xs text-text-secondary",
|
|
192
192
|
children: ["Completed on ", e.completedAt]
|
|
193
193
|
})]
|
|
194
194
|
})
|
|
195
195
|
]
|
|
196
196
|
}),
|
|
197
|
-
/* @__PURE__ */ v(s, { className: "h-5 w-5 shrink-0 text-
|
|
197
|
+
/* @__PURE__ */ v(s, { className: "h-5 w-5 shrink-0 text-text-secondary" })
|
|
198
198
|
]
|
|
199
199
|
})
|
|
200
200
|
})]
|
|
@@ -209,7 +209,7 @@ function O() {
|
|
|
209
209
|
className: "space-y-4",
|
|
210
210
|
children: [
|
|
211
211
|
/* @__PURE__ */ v("p", {
|
|
212
|
-
className: "text-sm text-
|
|
212
|
+
className: "text-sm text-text-secondary",
|
|
213
213
|
children: O.description
|
|
214
214
|
}),
|
|
215
215
|
/* @__PURE__ */ v("div", {
|
|
@@ -248,7 +248,7 @@ function O() {
|
|
|
248
248
|
className: "flex gap-2",
|
|
249
249
|
children: [/* @__PURE__ */ v("input", {
|
|
250
250
|
type: "tel",
|
|
251
|
-
className: "flex-1 rounded border bg-
|
|
251
|
+
className: "flex-1 rounded border bg-bg-surface px-3 py-2 text-sm",
|
|
252
252
|
placeholder: "+1 (555) 000-0000"
|
|
253
253
|
}), /* @__PURE__ */ y(x, {
|
|
254
254
|
size: "sm",
|
|
@@ -266,13 +266,13 @@ function O() {
|
|
|
266
266
|
/* @__PURE__ */ y("div", {
|
|
267
267
|
className: "flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6",
|
|
268
268
|
children: [
|
|
269
|
-
/* @__PURE__ */ v(h, { className: "h-8 w-8 text-
|
|
269
|
+
/* @__PURE__ */ v(h, { className: "h-8 w-8 text-text-secondary" }),
|
|
270
270
|
/* @__PURE__ */ v("p", {
|
|
271
|
-
className: "mt-2 text-xs text-
|
|
271
|
+
className: "mt-2 text-xs text-text-secondary",
|
|
272
272
|
children: "Drag & drop or click to upload"
|
|
273
273
|
}),
|
|
274
274
|
/* @__PURE__ */ v("p", {
|
|
275
|
-
className: "text-xs text-
|
|
275
|
+
className: "text-xs text-text-secondary",
|
|
276
276
|
children: "Passport, Driver's License, or National ID"
|
|
277
277
|
})
|
|
278
278
|
]
|
|
@@ -298,13 +298,13 @@ function O() {
|
|
|
298
298
|
})] }) : /* @__PURE__ */ v(S, { children: /* @__PURE__ */ y(C, {
|
|
299
299
|
className: "py-12 text-center",
|
|
300
300
|
children: [
|
|
301
|
-
/* @__PURE__ */ v(m, { className: "mx-auto h-10 w-10 text-
|
|
301
|
+
/* @__PURE__ */ v(m, { className: "mx-auto h-10 w-10 text-text-secondary/50" }),
|
|
302
302
|
/* @__PURE__ */ v("p", {
|
|
303
303
|
className: "mt-2 text-sm font-medium",
|
|
304
304
|
children: "Select a step"
|
|
305
305
|
}),
|
|
306
306
|
/* @__PURE__ */ v("p", {
|
|
307
|
-
className: "text-xs text-
|
|
307
|
+
className: "text-xs text-text-secondary",
|
|
308
308
|
children: "Click on a verification step to see details and take action."
|
|
309
309
|
})
|
|
310
310
|
]
|
|
@@ -335,7 +335,7 @@ function O() {
|
|
|
335
335
|
unlockAt: 100
|
|
336
336
|
}
|
|
337
337
|
].map((e) => /* @__PURE__ */ y("div", {
|
|
338
|
-
className: `flex items-center gap-2 rounded p-2 text-sm ${g >= e.unlockAt ? "text-
|
|
338
|
+
className: `flex items-center gap-2 rounded p-2 text-sm ${g >= e.unlockAt ? "text-text-primary" : "text-text-secondary"}`,
|
|
339
339
|
children: [
|
|
340
340
|
g >= e.unlockAt ? /* @__PURE__ */ v(o, { className: "h-4 w-4 text-green-500" }) : /* @__PURE__ */ v(c, { className: "h-4 w-4" }),
|
|
341
341
|
/* @__PURE__ */ v("span", { children: e.label }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerificationPage.js","names":[],"sources":["../../../src/proserviceworld/pages/VerificationPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } 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-green-600',\n bgColor: 'bg-green-100 dark:bg-green-950',\n label: 'Completed',\n },\n pending: {\n icon: Clock,\n color: 'text-gray-400',\n bgColor: 'bg-gray-100 dark:bg-gray-800',\n label: 'Pending',\n },\n in_progress: {\n icon: Clock,\n color: 'text-blue-600',\n bgColor: 'bg-blue-100 dark:bg-blue-950',\n label: 'In Progress',\n },\n failed: {\n icon: XCircle,\n color: 'text-red-600',\n bgColor: 'bg-red-100 dark:bg-red-950',\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\">\n {/* Header */}\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\">Verification</h1>\n <p className=\"text-sm text-muted-foreground\">\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 {progressPercent}% Verified\n </Badge>\n </div>\n\n {/* Overall progress */}\n <Card>\n <CardContent className=\"pt-6\">\n <div className=\"grid gap-6 sm:grid-cols-3\">\n <div className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">Overall Progress</p>\n <p className=\"text-3xl font-bold\">\n {completedCount}/{totalSteps}\n </p>\n <div className=\"h-3 overflow-hidden rounded-full bg-muted\">\n <div\n className=\"h-3 rounded-full bg-primary transition-all\"\n style={{ width: `${progressPercent}%` }}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">Required Steps</p>\n <p className=\"text-3xl font-bold\">\n {requiredCompleted}/{requiredSteps.length}\n </p>\n <div className=\"h-3 overflow-hidden rounded-full bg-muted\">\n <div\n className=\"h-3 rounded-full bg-green-500 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-muted-foreground\">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-primary' : 'bg-muted'\n }`}\n />\n ))}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\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-muted-foreground\">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\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-muted z-0\" />\n )}\n\n <button\n onClick={() => setSelectedStepId(selectedStepId === step.id ? null : step.id)}\n className={`relative z-10 w-full rounded-lg border p-4 text-left transition-colors ${\n selectedStepId === step.id ? 'border-primary bg-primary/5' : 'hover:bg-muted/50'\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-muted-foreground' : ''}`}\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-muted-foreground\">{step.description}</p>\n\n <div className=\"mt-2 flex items-center gap-3\">\n <div className=\"flex items-center gap-1\">\n <StatusIcon className={`h-4 w-4 ${cfg.color}`} />\n <span className={`text-xs font-medium ${cfg.color}`}>{cfg.label}</span>\n </div>\n {step.completedAt && (\n <span className=\"text-xs text-muted-foreground\">\n Completed on {step.completedAt}\n </span>\n )}\n </div>\n </div>\n\n <ChevronRight className=\"h-5 w-5 shrink-0 text-muted-foreground\" />\n </div>\n </button>\n </div>\n );\n })}\n </div>\n\n {/* Detail panel */}\n <div className=\"space-y-4\">\n {selectedStep ? (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">{selectedStep.title}</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">{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-red-50 p-3 dark:bg-red-950\">\n <AlertTriangle className=\"h-4 w-4 text-red-600\" />\n <span className=\"text-sm text-red-700 dark:text-red-400\">\n This step is required for full platform access.\n </span>\n </div>\n )}\n\n {selectedStep.completedAt && (\n <div className=\"rounded-lg bg-green-50 p-3 dark:bg-green-950\">\n <p className=\"text-sm text-green-700 dark:text-green-400\">\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 className=\"flex-1 rounded border bg-background px-3 py-2 text-sm\"\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 p-6\">\n <Upload className=\"h-8 w-8 text-muted-foreground\" />\n <p className=\"mt-2 text-xs text-muted-foreground\">\n Drag & drop or click to upload\n </p>\n <p className=\"text-xs text-muted-foreground\">\n Passport, Driver'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 </Card>\n ) : (\n <Card>\n <CardContent className=\"py-12 text-center\">\n <Shield className=\"mx-auto h-10 w-10 text-muted-foreground/50\" />\n <p className=\"mt-2 text-sm font-medium\">Select a step</p>\n <p className=\"text-xs text-muted-foreground\">\n Click on a verification step to see details and take action.\n </p>\n </CardContent>\n </Card>\n )}\n\n {/* Benefits card */}\n <Card>\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-foreground'\n : 'text-muted-foreground'\n }`}\n >\n {progressPercent >= benefit.unlockAt ? (\n <CheckCircle2 className=\"h-4 w-4 text-green-500\" />\n ) : (\n <Clock className=\"h-4 w-4\" />\n )}\n <span>{benefit.label}</span>\n <span className=\"ml-auto text-xs\">{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 { Badge, Button, Card, CardContent, CardHeader, CardTitle } 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-green-600',\n bgColor: 'bg-green-100 dark:bg-green-950',\n label: 'Completed',\n },\n pending: {\n icon: Clock,\n color: 'text-gray-400',\n bgColor: 'bg-gray-100 dark:bg-gray-800',\n label: 'Pending',\n },\n in_progress: {\n icon: Clock,\n color: 'text-blue-600',\n bgColor: 'bg-blue-100 dark:bg-blue-950',\n label: 'In Progress',\n },\n failed: {\n icon: XCircle,\n color: 'text-red-600',\n bgColor: 'bg-red-100 dark:bg-red-950',\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\">\n {/* Header */}\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\">Verification</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 {progressPercent}% Verified\n </Badge>\n </div>\n\n {/* Overall progress */}\n <Card>\n <CardContent className=\"pt-6\">\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\">\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-action-primary-bg 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\">\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-green-500 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-action-primary-bg' : 'bg-bg-sunken'\n }`}\n />\n ))}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\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\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-bg-sunken z-0\" />\n )}\n\n <button\n onClick={() => setSelectedStepId(selectedStepId === step.id ? null : step.id)}\n className={`relative z-10 w-full rounded-lg border p-4 text-left transition-colors ${\n selectedStepId === step.id ? 'border-primary bg-action-primary-bg/5' : 'hover:bg-bg-sunken/50'\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 className={`h-4 w-4 ${cfg.color}`} />\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 <Card>\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-red-50 p-3 dark:bg-red-950\">\n <AlertTriangle className=\"h-4 w-4 text-red-600\" />\n <span className=\"text-sm text-red-700 dark:text-red-400\">\n This step is required for full platform access.\n </span>\n </div>\n )}\n\n {selectedStep.completedAt && (\n <div className=\"rounded-lg bg-green-50 p-3 dark:bg-green-950\">\n <p className=\"text-sm text-green-700 dark:text-green-400\">\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 className=\"flex-1 rounded border bg-bg-surface px-3 py-2 text-sm\"\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 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'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 </Card>\n ) : (\n <Card>\n <CardContent className=\"py-12 text-center\">\n <Shield className=\"mx-auto h-10 w-10 text-text-secondary/50\" />\n <p className=\"mt-2 text-sm font-medium\">Select a step</p>\n <p className=\"text-xs text-text-secondary\">\n Click on a verification step to see details and take action.\n </p>\n </CardContent>\n </Card>\n )}\n\n {/* Benefits card */}\n <Card>\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-green-500\" />\n ) : (\n <Clock className=\"h-4 w-4\" />\n )}\n <span>{benefit.label}</span>\n <span className=\"ml-auto text-xs\">{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
package/dist/dev/main.d.ts
DELETED
package/dist/dev/main.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/dev/main.tsx"],"names":[],"mappings":"AAIA,OAAO,cAAc,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"global-operations.d.ts","sourceRoot":"","sources":["../../src/generated/global-operations.ts"],"names":[],"mappings":""}
|