Changed Dashboards

This commit is contained in:
2026-06-18 15:37:08 +02:00
37 changed files with 2004 additions and 495 deletions
+43 -41
View File
@@ -1,52 +1,54 @@
import { DashboardStats } from "@/types"
import { leads } from "./leads"
import { filterLeadsByPeriod, groupLeadsByInterval } from "@/lib/date-utils"
function getLeadsPerMonth() {
const months: { month: string; leads: number; closed: number }[] = []
const now = new Date()
for (let i = 5; i >= 0; i--) {
const d = new Date(now.getFullYear(), now.getMonth() - i, 1)
const monthStr = d.toLocaleDateString("en-US", { month: "short", year: "2-digit" })
const yearMonth = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`
const leadsCount = leads.filter((l) => l.createdAt.startsWith(yearMonth)).length
const closedCount = leads.filter(
(l) => l.status === "closed" && l.updatedAt.startsWith(yearMonth)
).length
months.push({ month: monthStr, leads: leadsCount, closed: closedCount })
}
return months
const periodLabels: Record<string, string> = {
"7days": "Last 7 days",
"30days": "Last 30 days",
"6months": "Last 6 months",
"12months": "Last 12 months",
}
function getStatusDistribution() {
const statusCounts: Record<string, number> = { open: 0, contacted: 0, pending: 0, closed: 0, ignored: 0 }
leads.forEach((l) => {
statusCounts[l.status]++
})
export function getDashboardStats(period: string): DashboardStats {
const filtered = filterLeadsByPeriod(leads, period)
const label = periodLabels[period] ?? "Selected period"
const totalLeads = filtered.length
const openLeads = filtered.filter((l) => l.status === "open").length
const contactedLeads = filtered.filter((l) => l.status === "contacted").length
const pendingLeads = filtered.filter((l) => l.status === "pending").length
const closedLeads = filtered.filter((l) => l.status === "closed").length
const ignoredLeads = filtered.filter((l) => l.status === "ignored").length
const conversionRate = totalLeads > 0
? Math.round((closedLeads / totalLeads) * 100)
: 0
function getStatusDistribution() {
const statusCounts: Record<string, number> = { open: 0, contacted: 0, pending: 0, closed: 0, ignored: 0 }
filtered.forEach((l) => {
statusCounts[l.status]++
})
return [
{ name: "Open", value: statusCounts.open, color: "#0d9488" },
{ name: "Contacted", value: statusCounts.contacted, color: "#5eead4" },
{ name: "Pending", value: statusCounts.pending, color: "#c9a96e" },
{ name: "Closed", value: statusCounts.closed, color: "#f43f5e" },
{ name: "Ignored", value: statusCounts.ignored, color: "#94a3b8" },
{ name: "Open", value: statusCounts.open, color: "#3b82f6" },
{ name: "Contacted", value: statusCounts.contacted, color: "#f59e0b" },
{ name: "Pending", value: statusCounts.pending, color: "#8b5cf6" },
{ name: "Closed", value: statusCounts.closed, color: "#10b981" },
{ name: "Ignored", value: statusCounts.ignored, color: "#6B7280" },
]
}
export const dashboardStats: DashboardStats = {
totalLeads: leads.length,
openLeads: leads.filter((l) => l.status === "open").length,
contactedLeads: leads.filter((l) => l.status === "contacted").length,
pendingLeads: leads.filter((l) => l.status === "pending").length,
closedLeads: leads.filter((l) => l.status === "closed").length,
ignoredLeads: leads.filter((l) => l.status === "ignored").length,
conversionRate: Math.round(
(leads.filter((l) => l.status === "closed").length / leads.length) * 100
),
leadsPerMonth: getLeadsPerMonth(),
recentLeads: leads.slice(0, 10),
statusDistribution: getStatusDistribution(),
return {
totalLeads,
openLeads,
contactedLeads,
pendingLeads,
closedLeads,
ignoredLeads,
conversionRate,
leadsPerMonth: groupLeadsByInterval(filtered, period),
recentLeads: filtered.slice(0, 10),
statusDistribution: getStatusDistribution(),
periodLabel: label,
}
}
+8 -10
View File
@@ -1,4 +1,4 @@
import { User } from "@/types"
import { User, UserRole } from "@/types"
export const users: User[] = [
{
@@ -14,7 +14,7 @@ export const users: User[] = [
id: "u2",
name: "Marcus Johnson",
email: "marcus@coastalit.com",
role: "sales",
role: "sales_user",
active: true,
avatar: "https://ui-avatars.com/api/?name=Marcus+Johnson&background=2563eb&color=fff&size=128",
createdAt: "2025-02-01T09:00:00Z",
@@ -23,7 +23,7 @@ export const users: User[] = [
id: "u3",
name: "Emily Rodriguez",
email: "emily@coastalit.com",
role: "sales",
role: "sales_user",
active: true,
avatar: "https://ui-avatars.com/api/?name=Emily+Rodriguez&background=3b82f6&color=fff&size=128",
createdAt: "2025-02-15T10:00:00Z",
@@ -32,7 +32,7 @@ export const users: User[] = [
id: "u4",
name: "David Kim",
email: "david@coastalit.com",
role: "sales",
role: "sales_user",
active: true,
avatar: "https://ui-avatars.com/api/?name=David+Kim&background=60a5fa&color=fff&size=128",
createdAt: "2025-03-01T08:00:00Z",
@@ -41,7 +41,7 @@ export const users: User[] = [
id: "u5",
name: "Jessica Patel",
email: "jessica@coastalit.com",
role: "sales",
role: "sales_user",
active: false,
avatar: "https://ui-avatars.com/api/?name=Jessica+Patel&background=93c5fd&color=fff&size=128",
createdAt: "2025-03-10T09:00:00Z",
@@ -50,7 +50,7 @@ export const users: User[] = [
id: "u6",
name: "Alex Thompson",
email: "alex@coastalit.com",
role: "sales",
role: "sales_user",
active: true,
avatar: "https://ui-avatars.com/api/?name=Alex+Thompson&background=1d4ed8&color=fff&size=128",
createdAt: "2025-04-01T08:00:00Z",
@@ -59,7 +59,7 @@ export const users: User[] = [
id: "u7",
name: "Rachel Williams",
email: "rachel@coastalit.com",
role: "sales",
role: "sales_user",
active: true,
avatar: "https://ui-avatars.com/api/?name=Rachel+Williams&background=2563eb&color=fff&size=128",
createdAt: "2025-04-15T10:00:00Z",
@@ -75,13 +75,11 @@ export const users: User[] = [
},
]
export const currentUser: User = users[0]
export function getUserById(id: string): User | undefined {
return users.find((u) => u.id === id)
}
export function getUsersByRole(role: "admin" | "sales"): User[] {
export function getUsersByRole(role: UserRole): User[] {
return users.filter((u) => u.role === role)
}