mirror of
https://github.com/johndoe6345789/workforce-pay-bill-p.git
synced 2026-04-24 13:24:57 +00:00
Generated by Spark: split app.tsx into 5 parts
This commit is contained in:
46
src/App.tsx
46
src/App.tsx
@@ -9,25 +9,9 @@ import {
|
||||
ShieldCheck,
|
||||
ChartBar,
|
||||
Buildings,
|
||||
CheckCircle,
|
||||
XCircle,
|
||||
ClockCounterClockwise,
|
||||
Plus,
|
||||
MagnifyingGlass,
|
||||
Funnel,
|
||||
Download,
|
||||
ArrowUp,
|
||||
ArrowDown,
|
||||
Warning,
|
||||
MapTrifold,
|
||||
UploadSimple,
|
||||
FileCsv,
|
||||
Envelope,
|
||||
X,
|
||||
CalendarBlank,
|
||||
Notepad,
|
||||
Bell,
|
||||
Camera,
|
||||
ChartLine,
|
||||
CurrencyCircleDollar,
|
||||
QrCode,
|
||||
@@ -35,24 +19,23 @@ import {
|
||||
UserPlus,
|
||||
Gear,
|
||||
FileText,
|
||||
CaretDown,
|
||||
CaretRight,
|
||||
Question
|
||||
Question,
|
||||
UploadSimple,
|
||||
ClockCounterClockwise,
|
||||
CalendarBlank,
|
||||
Envelope,
|
||||
X
|
||||
} from '@phosphor-icons/react'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { toast } from 'sonner'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { NavItem, NavGroup } from '@/components/navigation'
|
||||
import { DashboardView } from '@/components/dashboard-view'
|
||||
import { RoadmapView } from '@/components/roadmap-view'
|
||||
import { ReportsView } from '@/components/ReportsView'
|
||||
import { CurrencyManagement } from '@/components/CurrencyManagement'
|
||||
import { EmailTemplateManager } from '@/components/EmailTemplateManager'
|
||||
@@ -71,7 +54,6 @@ import { CustomReportBuilder } from '@/components/CustomReportBuilder'
|
||||
import { HolidayPayManager } from '@/components/HolidayPayManager'
|
||||
import { PermanentPlacementInvoice } from '@/components/PermanentPlacementInvoice'
|
||||
import { CreditNoteGenerator } from '@/components/CreditNoteGenerator'
|
||||
import { ShiftPremiumCalculator } from '@/components/ShiftPremiumCalculator'
|
||||
import { ContractValidator } from '@/components/ContractValidator'
|
||||
import { DetailedTimesheetEntry } from '@/components/DetailedTimesheetEntry'
|
||||
import { ShiftPatternManager } from '@/components/ShiftPatternManager'
|
||||
@@ -81,6 +63,7 @@ import { ExpenseDetailDialog } from '@/components/ExpenseDetailDialog'
|
||||
import { ComplianceDetailDialog } from '@/components/ComplianceDetailDialog'
|
||||
import { AdvancedSearch, type FilterField } from '@/components/AdvancedSearch'
|
||||
import { QueryLanguageGuide } from '@/components/QueryLanguageGuide'
|
||||
import { TimesheetsView, BillingView, PayrollView, ExpensesView, ComplianceView } from '@/components/views'
|
||||
import type {
|
||||
Timesheet,
|
||||
Invoice,
|
||||
@@ -909,13 +892,7 @@ function App() {
|
||||
)
|
||||
}
|
||||
|
||||
interface NavItemProps {
|
||||
icon: React.ReactNode
|
||||
label: string
|
||||
active?: boolean
|
||||
onClick?: () => void
|
||||
badge?: number
|
||||
}
|
||||
export default App
|
||||
|
||||
function NavItem({ icon, label, active, onClick, badge }: NavItemProps) {
|
||||
return (
|
||||
@@ -3083,4 +3060,3 @@ function RoadmapView() {
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
236
src/components/dashboard-view.tsx
Normal file
236
src/components/dashboard-view.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Clock,
|
||||
Receipt,
|
||||
CurrencyDollar,
|
||||
ClockCounterClockwise,
|
||||
CheckCircle,
|
||||
Warning,
|
||||
Notepad,
|
||||
Download,
|
||||
ArrowUp,
|
||||
ArrowDown
|
||||
} from '@phosphor-icons/react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import type { DashboardMetrics } from '@/lib/types'
|
||||
|
||||
interface DashboardViewProps {
|
||||
metrics: DashboardMetrics
|
||||
}
|
||||
|
||||
export function DashboardView({ metrics }: DashboardViewProps) {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h2 className="text-3xl font-semibold tracking-tight">Dashboard</h2>
|
||||
<p className="text-muted-foreground mt-1">Real-time overview of your workforce operations</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<MetricCard
|
||||
title="Pending Approvals"
|
||||
value={metrics.pendingApprovals}
|
||||
icon={<ClockCounterClockwise size={20} className="text-warning" />}
|
||||
trend={{ value: 12, direction: 'up' }}
|
||||
variant="warning"
|
||||
/>
|
||||
<MetricCard
|
||||
title="Pending Expenses"
|
||||
value={metrics.pendingExpenses}
|
||||
icon={<Notepad size={20} className="text-info" />}
|
||||
variant="default"
|
||||
/>
|
||||
<MetricCard
|
||||
title="Overdue Invoices"
|
||||
value={metrics.overdueInvoices}
|
||||
icon={<Receipt size={20} className="text-destructive" />}
|
||||
trend={{ value: 5, direction: 'down' }}
|
||||
variant="error"
|
||||
/>
|
||||
<MetricCard
|
||||
title="Compliance Alerts"
|
||||
value={metrics.complianceAlerts}
|
||||
icon={<Warning size={20} className="text-warning" />}
|
||||
variant="warning"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
||||
<Card className="lg:col-span-1">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">Monthly Revenue</CardTitle>
|
||||
<CardDescription>Total invoiced this month</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold font-mono">
|
||||
£{metrics.monthlyRevenue.toLocaleString()}
|
||||
</div>
|
||||
<div className="flex items-center gap-1 mt-2 text-sm text-success">
|
||||
<ArrowUp size={16} weight="bold" />
|
||||
<span>12.5% from last month</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="lg:col-span-1">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">Monthly Payroll</CardTitle>
|
||||
<CardDescription>Total payroll costs</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold font-mono">
|
||||
£{metrics.monthlyPayroll.toLocaleString()}
|
||||
</div>
|
||||
<div className="flex items-center gap-1 mt-2 text-sm text-muted-foreground">
|
||||
<ArrowUp size={16} weight="bold" />
|
||||
<span>8.3% from last month</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="lg:col-span-1">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">Gross Margin</CardTitle>
|
||||
<CardDescription>Revenue minus payroll</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold font-mono">
|
||||
{metrics.grossMargin.toFixed(1)}%
|
||||
</div>
|
||||
<div className="flex items-center gap-1 mt-2 text-sm text-success">
|
||||
<ArrowUp size={16} weight="bold" />
|
||||
<span>3.2% from last month</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">Recent Activity</CardTitle>
|
||||
<CardDescription>Latest timesheet and billing events</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<ActivityItem
|
||||
icon={<CheckCircle size={18} className="text-success" />}
|
||||
title="Timesheet approved"
|
||||
description="John Smith - Week ending 15 Jan 2025"
|
||||
time="5 minutes ago"
|
||||
/>
|
||||
<ActivityItem
|
||||
icon={<Receipt size={18} className="text-info" />}
|
||||
title="Invoice generated"
|
||||
description="INV-00234 - Acme Corp - £2,450"
|
||||
time="12 minutes ago"
|
||||
/>
|
||||
<ActivityItem
|
||||
icon={<CheckCircle size={18} className="text-success" />}
|
||||
title="Payroll completed"
|
||||
description="Weekly run - 45 workers - £28,900"
|
||||
time="1 hour ago"
|
||||
/>
|
||||
<ActivityItem
|
||||
icon={<Warning size={18} className="text-warning" />}
|
||||
title="Document expiring soon"
|
||||
description="DBS check for Sarah Johnson - 14 days"
|
||||
time="2 hours ago"
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">Quick Actions</CardTitle>
|
||||
<CardDescription>Common tasks and workflows</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<Button className="w-full justify-start" variant="outline">
|
||||
<Clock size={18} className="mr-2" />
|
||||
Create Timesheet
|
||||
</Button>
|
||||
<Button className="w-full justify-start" variant="outline">
|
||||
<Receipt size={18} className="mr-2" />
|
||||
Generate Invoice
|
||||
</Button>
|
||||
<Button className="w-full justify-start" variant="outline">
|
||||
<CurrencyDollar size={18} className="mr-2" />
|
||||
Run Payroll
|
||||
</Button>
|
||||
<Button className="w-full justify-start" variant="outline">
|
||||
<Download size={18} className="mr-2" />
|
||||
Export Reports
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface MetricCardProps {
|
||||
title: string
|
||||
value: number
|
||||
icon: React.ReactNode
|
||||
trend?: { value: number; direction: 'up' | 'down' }
|
||||
variant?: 'default' | 'success' | 'warning' | 'error'
|
||||
}
|
||||
|
||||
function MetricCard({ title, value, icon, trend, variant = 'default' }: MetricCardProps) {
|
||||
const borderColors = {
|
||||
default: 'border-border',
|
||||
success: 'border-success/20',
|
||||
warning: 'border-warning/20',
|
||||
error: 'border-destructive/20'
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className={cn('border-l-4', borderColors[variant])}>
|
||||
<CardHeader className="flex flex-row items-center justify-between pb-2">
|
||||
<CardTitle className="text-sm font-medium text-muted-foreground">
|
||||
{title}
|
||||
</CardTitle>
|
||||
{icon}
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold">{value}</div>
|
||||
{trend && (
|
||||
<div className={cn(
|
||||
'flex items-center gap-1 mt-1 text-xs',
|
||||
trend.direction === 'up' ? 'text-success' : 'text-muted-foreground'
|
||||
)}>
|
||||
{trend.direction === 'up' ? (
|
||||
<ArrowUp size={14} weight="bold" />
|
||||
) : (
|
||||
<ArrowDown size={14} weight="bold" />
|
||||
)}
|
||||
<span>{trend.value}% vs last week</span>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
interface ActivityItemProps {
|
||||
icon: React.ReactNode
|
||||
title: string
|
||||
description: string
|
||||
time: string
|
||||
}
|
||||
|
||||
function ActivityItem({ icon, title, description, time }: ActivityItemProps) {
|
||||
return (
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="mt-0.5">{icon}</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium">{title}</p>
|
||||
<p className="text-sm text-muted-foreground truncate">{description}</p>
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground whitespace-nowrap">{time}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
62
src/components/navigation.tsx
Normal file
62
src/components/navigation.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { CaretDown, CaretRight } from '@phosphor-icons/react'
|
||||
|
||||
interface NavItemProps {
|
||||
icon: React.ReactNode
|
||||
label: string
|
||||
active?: boolean
|
||||
onClick?: () => void
|
||||
badge?: number
|
||||
}
|
||||
|
||||
export function NavItem({ icon, label, active, onClick, badge }: NavItemProps) {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={cn(
|
||||
'w-full flex items-center gap-3 px-3 py-2 rounded-lg text-sm font-medium transition-colors',
|
||||
active
|
||||
? 'bg-accent text-accent-foreground'
|
||||
: 'text-foreground hover:bg-muted'
|
||||
)}
|
||||
>
|
||||
<span className={active ? 'text-accent-foreground' : 'text-muted-foreground'}>
|
||||
{icon}
|
||||
</span>
|
||||
<span className="flex-1 text-left">{label}</span>
|
||||
{badge !== undefined && badge > 0 && (
|
||||
<Badge variant="destructive" className="ml-auto h-5 px-1.5 text-xs">
|
||||
{badge}
|
||||
</Badge>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
interface NavGroupProps {
|
||||
id: string
|
||||
label: string
|
||||
expanded: boolean
|
||||
onToggle: () => void
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export function NavGroup({ label, expanded, onToggle, children }: NavGroupProps) {
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<button
|
||||
onClick={onToggle}
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wider hover:text-foreground transition-colors"
|
||||
>
|
||||
{expanded ? <CaretDown size={14} weight="bold" /> : <CaretRight size={14} weight="bold" />}
|
||||
<span className="flex-1 text-left">{label}</span>
|
||||
</button>
|
||||
{expanded && (
|
||||
<div className="space-y-1 pl-2">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
393
src/components/roadmap-view.tsx
Normal file
393
src/components/roadmap-view.tsx
Normal file
@@ -0,0 +1,393 @@
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { CheckCircle, ClockCounterClockwise, MapTrifold, Warning, Download } from '@phosphor-icons/react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export function RoadmapView() {
|
||||
const roadmapContent = `# WorkForce Pro - Development Roadmap
|
||||
|
||||
## Phase 1: Foundation & Core Pay/Bill (Quarters 1-2) ✅
|
||||
|
||||
### Core Platform Infrastructure
|
||||
- ✅ Multi-tenancy architecture
|
||||
- ✅ Entity and division management
|
||||
- ✅ User authentication and role-based access control
|
||||
- ✅ Cloud-hosted SaaS deployment
|
||||
- ✅ Basic security and data access controls
|
||||
|
||||
### Timesheet Management - Basic
|
||||
- ✅ Online web portal timesheet entry
|
||||
- ✅ Timesheet approval workflows
|
||||
- ✅ Status tracking (pending/approved/rejected)
|
||||
- ✅ Agency-initiated timesheet creation
|
||||
- ✅ Bulk entry by administrators
|
||||
- ✅ Mobile timesheet submission
|
||||
- 📋 Batch import capabilities
|
||||
- ✅ QR-coded paper timesheet scanning
|
||||
|
||||
### Basic Billing & Invoicing
|
||||
- ✅ Invoice generation from timesheets
|
||||
- ✅ Invoice status tracking
|
||||
- ✅ Multi-currency support (GBP, USD, EUR)
|
||||
- ✅ Electronic invoice delivery
|
||||
- ✅ Sales invoice templates
|
||||
- ✅ Payment terms configuration
|
||||
- 📋 Purchase order tracking
|
||||
|
||||
### Basic Payroll
|
||||
- ✅ Payroll run tracking
|
||||
- ✅ Worker payment calculations
|
||||
- ✅ One-click payroll processing
|
||||
- 📋 PAYE payroll integration
|
||||
- ✅ Holiday pay calculations
|
||||
|
||||
### Dashboard & Core Reporting
|
||||
- ✅ Executive dashboard with key metrics
|
||||
- ✅ Pending approvals tracking
|
||||
- ✅ Overdue invoice monitoring
|
||||
- ✅ Revenue and margin visibility
|
||||
- ✅ Activity feed
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Advanced Operations & Automation (Quarters 3-4) 🔄
|
||||
|
||||
### Expense Management
|
||||
- ✅ Worker expense submission (web portal)
|
||||
- ✅ Agency-created expense entries
|
||||
- ✅ Expense approval workflows
|
||||
- ✅ Integration with billing and payroll
|
||||
- ✅ Reimbursable vs billable expense tracking
|
||||
- 📋 Mobile expense capture with receipt photos
|
||||
|
||||
### Notifications & Workflow Automation
|
||||
- ✅ In-system alert notifications
|
||||
- ✅ Real-time notification center
|
||||
- ✅ Notification history and tracking
|
||||
- ✅ Event-driven processing updates
|
||||
- ✅ Email notification templates
|
||||
- 📋 Configurable notification rules
|
||||
- 📋 Automated follow-up reminders
|
||||
|
||||
### Timesheet Management - Advanced
|
||||
- ✅ Multi-step approval routing
|
||||
- 📋 Time and rate adjustment wizard
|
||||
- 📋 Automated credit generation
|
||||
- 📋 Re-invoicing workflows
|
||||
- 📋 Full audit trail
|
||||
|
||||
### Advanced Billing
|
||||
- 📋 Permanent placement invoices
|
||||
- 📋 Contractor self-billing
|
||||
- 📋 Bespoke invoice templates
|
||||
- 📋 Client self-billing support
|
||||
- 📋 Withholding tax handling
|
||||
|
||||
### Contract, Rate & Rule Enforcement
|
||||
- ✅ Rate templates by role/client/placement
|
||||
- 📋 Automatic shift premium calculations
|
||||
- 📋 Overtime rate automation
|
||||
- 📋 Time pattern validation
|
||||
- 📋 AWR monitoring
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Compliance & Self-Service (Quarters 5-6) 📋
|
||||
|
||||
### Compliance Management - Enhanced
|
||||
- ✅ Document tracking and monitoring
|
||||
- ✅ Expiry alerts and notifications
|
||||
- ✅ Document upload and storage
|
||||
- 📋 Digital onboarding workflows
|
||||
- 📋 Automated contract pack generation
|
||||
- 📋 Compliance enforcement rules
|
||||
- 📋 Statutory reporting support
|
||||
|
||||
### Self-Service Portals
|
||||
- 📋 Branded worker portal
|
||||
- 📋 Branded client portal
|
||||
- 📋 Real-time timesheet visibility
|
||||
- 📋 Invoice and payment status
|
||||
- 📋 Paperless document access
|
||||
- 📋 Mobile-responsive design
|
||||
|
||||
### Advanced Payroll Processing
|
||||
- 📋 CIS processing
|
||||
- 📋 Agency staff payroll
|
||||
- 📋 Multiple employment models
|
||||
- 📋 International payroll preparation
|
||||
- 📋 Holiday pay automation
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Analytics & Integrations (Quarters 7-8) 📋
|
||||
|
||||
### Advanced Reporting & Analytics
|
||||
- ✅ Real-time gross margin reporting
|
||||
- ✅ Forecasting and predictive analytics
|
||||
- ✅ Missing timesheet reports
|
||||
- ✅ Custom report builder
|
||||
- 📋 Client-level performance dashboards
|
||||
- 📋 Placement-level profitability
|
||||
|
||||
### System Integrations
|
||||
- 📋 ATS (Applicant Tracking System) integration
|
||||
- 📋 CRM platform integration
|
||||
- 📋 Accounting system integration (Xero, QuickBooks, Sage)
|
||||
- 📋 RESTful API for third-party integrations
|
||||
- 📋 Webhook support for real-time updates
|
||||
|
||||
### Global & Multi-Currency - Advanced
|
||||
- ✅ Multi-currency billing (expanded)
|
||||
- 📋 International sales tax handling
|
||||
- 📋 Withholding tax automation
|
||||
- 📋 Cross-border margin calculation
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Enterprise & Scale (Quarters 9-10) 📋
|
||||
|
||||
### Multi-Tenancy - Advanced
|
||||
- 📋 Franchise management capabilities
|
||||
- 📋 Agency group consolidation
|
||||
- 📋 Cross-entity reporting
|
||||
- 📋 Delegated administration controls
|
||||
|
||||
### Configuration & Customisation
|
||||
- 📋 Custom system labels
|
||||
- 📋 Agency-defined security roles
|
||||
- ✅ Editable email templates
|
||||
- 📋 White-label capabilities
|
||||
- 📋 Custom workflow builders
|
||||
|
||||
### Performance & Scale
|
||||
- 📋 High-volume processing optimization
|
||||
- 📋 Batch processing improvements
|
||||
- 📋 Performance monitoring dashboards
|
||||
- 📋 Load balancing and scaling
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Innovation & AI (Quarters 11-12) 📋
|
||||
|
||||
### Intelligent Automation
|
||||
- 📋 AI-powered timesheet anomaly detection
|
||||
- 📋 Predictive compliance alerts
|
||||
- 📋 Smart invoice matching
|
||||
- 📋 Automated expense categorization
|
||||
- 📋 Machine learning for margin optimization
|
||||
|
||||
### Advanced Analytics
|
||||
- 📋 Business intelligence dashboards
|
||||
- 📋 Trend analysis and insights
|
||||
- 📋 Benchmarking and KPI tracking
|
||||
- 📋 Predictive workforce planning
|
||||
|
||||
### Mobile Excellence
|
||||
- 📋 Native mobile apps (iOS/Android)
|
||||
- 📋 Offline capability
|
||||
- 📋 Biometric authentication
|
||||
- 📋 Push notifications
|
||||
- 📋 Geolocation-based features
|
||||
|
||||
---
|
||||
|
||||
## Legend
|
||||
- ✅ **Completed** - Feature is implemented and live
|
||||
- 🔄 **In Progress** - Currently under development
|
||||
- 📋 **Planned** - Scheduled for future development
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Operational Efficiency
|
||||
- 80% reduction in timesheet processing time
|
||||
- 95% straight-through invoice processing
|
||||
- 90% reduction in compliance breach incidents
|
||||
|
||||
### User Adoption
|
||||
- 85%+ worker portal adoption
|
||||
- 75%+ client portal adoption
|
||||
- <5% support ticket rate per user
|
||||
|
||||
### Financial Impact
|
||||
- 99.5% billing accuracy
|
||||
- <2% margin leakage
|
||||
- 30% reduction in administrative overhead`
|
||||
|
||||
const parseMarkdown = (text: string) => {
|
||||
const lines = text.split('\n')
|
||||
const elements: React.ReactNode[] = []
|
||||
let inList = false
|
||||
let listItems: React.ReactNode[] = []
|
||||
|
||||
const flushList = (index: number) => {
|
||||
if (inList && listItems.length > 0) {
|
||||
elements.push(
|
||||
<ul key={`list-${index}`} className="space-y-2 mb-4 pl-6">
|
||||
{listItems}
|
||||
</ul>
|
||||
)
|
||||
listItems = []
|
||||
inList = false
|
||||
}
|
||||
}
|
||||
|
||||
lines.forEach((line, i) => {
|
||||
if (line.startsWith('# ')) {
|
||||
flushList(i)
|
||||
elements.push(
|
||||
<h1 key={i} className="text-3xl font-semibold tracking-tight mb-4 mt-6">
|
||||
{line.substring(2)}
|
||||
</h1>
|
||||
)
|
||||
} else if (line.startsWith('## ')) {
|
||||
flushList(i)
|
||||
const text = line.substring(3)
|
||||
elements.push(
|
||||
<h2 key={i} className="text-2xl font-semibold tracking-tight mb-3 mt-6 flex items-center gap-2">
|
||||
{text}
|
||||
</h2>
|
||||
)
|
||||
} else if (line.startsWith('### ')) {
|
||||
flushList(i)
|
||||
elements.push(
|
||||
<h3 key={i} className="text-lg font-semibold mb-2 mt-4">
|
||||
{line.substring(4)}
|
||||
</h3>
|
||||
)
|
||||
} else if (line.startsWith('- ')) {
|
||||
if (!inList) {
|
||||
inList = true
|
||||
}
|
||||
const text = line.substring(2)
|
||||
const isCompleted = text.startsWith('✅')
|
||||
const isInProgress = text.startsWith('🔄')
|
||||
const isPlanned = text.startsWith('📋')
|
||||
|
||||
listItems.push(
|
||||
<li key={i} className="flex items-start gap-2 text-sm">
|
||||
<span className="mt-0.5">
|
||||
{isCompleted && <span className="text-success">✅</span>}
|
||||
{isInProgress && <span className="text-warning">🔄</span>}
|
||||
{isPlanned && <span className="text-muted-foreground">📋</span>}
|
||||
{!isCompleted && !isInProgress && !isPlanned && <span className="text-muted-foreground">•</span>}
|
||||
</span>
|
||||
<span className={cn(
|
||||
isCompleted && 'text-foreground',
|
||||
isInProgress && 'text-foreground font-medium',
|
||||
isPlanned && 'text-muted-foreground'
|
||||
)}>
|
||||
{text.replace(/^[✅🔄📋]\s*/, '')}
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
} else if (line.startsWith('---')) {
|
||||
flushList(i)
|
||||
elements.push(<hr key={i} className="my-6 border-border" />)
|
||||
} else if (line.trim() !== '') {
|
||||
flushList(i)
|
||||
elements.push(
|
||||
<p key={i} className="text-sm text-muted-foreground mb-3">
|
||||
{line}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
flushList(lines.length)
|
||||
return elements
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-semibold tracking-tight">Product Roadmap</h2>
|
||||
<p className="text-muted-foreground mt-1">Development phases and feature timeline</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="outline">
|
||||
<Download size={18} className="mr-2" />
|
||||
Download PDF
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<Card className="border-l-4 border-success/20">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-sm text-muted-foreground flex items-center gap-2">
|
||||
<CheckCircle size={18} className="text-success" weight="fill" />
|
||||
Completed
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold">Phase 1-2 + Features</div>
|
||||
<p className="text-sm text-muted-foreground mt-1">Core platform with advanced features</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-l-4 border-warning/20">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-sm text-muted-foreground flex items-center gap-2">
|
||||
<ClockCounterClockwise size={18} className="text-warning" weight="fill" />
|
||||
In Progress
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold">Phase 2</div>
|
||||
<p className="text-sm text-muted-foreground mt-1">Advanced Operations & Automation</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-l-4 border-accent/20">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-sm text-muted-foreground flex items-center gap-2">
|
||||
<MapTrifold size={18} className="text-accent" weight="fill" />
|
||||
Total Phases
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-semibold">6</div>
|
||||
<p className="text-sm text-muted-foreground mt-1">2 years timeline</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardContent className="p-6 prose prose-sm max-w-none">
|
||||
{parseMarkdown(roadmapContent)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-muted/50">
|
||||
<CardContent className="p-6">
|
||||
<h3 className="font-semibold mb-3 flex items-center gap-2">
|
||||
<Warning size={20} className="text-warning" />
|
||||
Release Cadence
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 text-sm">
|
||||
<div>
|
||||
<p className="text-muted-foreground">Major Releases</p>
|
||||
<p className="font-medium">Quarterly</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-muted-foreground">Minor Updates</p>
|
||||
<p className="font-medium">Monthly</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-muted-foreground">Patches</p>
|
||||
<p className="font-medium">Weekly</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-muted-foreground">Hotfixes</p>
|
||||
<p className="font-medium">As needed</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
5
src/components/views/index.tsx
Normal file
5
src/components/views/index.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
export { TimesheetsView } from './TimesheetsView'
|
||||
export { BillingView } from './BillingView'
|
||||
export { PayrollView } from './PayrollView'
|
||||
export { ExpensesView } from './ExpensesView'
|
||||
export { ComplianceView } from './ComplianceView'
|
||||
Reference in New Issue
Block a user