feat(data): add org skill catalog + two-layer person profiles + profile store API
This commit is contained in:
@@ -6941,6 +6941,18 @@ const MOCK_SUBCONTRACTORS = [
|
||||
},
|
||||
];
|
||||
|
||||
// --- ORG SKILL CATALOG ---
|
||||
|
||||
export const SKILL_CATALOG = [
|
||||
{ id: 'sk_insurance_claim', name: 'Insurance Claim Handling', description: 'Files & negotiates carrier claims/supplements.' },
|
||||
{ id: 'sk_roof_inspection', name: 'Roof Inspection', description: 'Damage assessment, measurements, documentation.' },
|
||||
{ id: 'sk_emergency_tarp', name: 'Emergency Tarp', description: 'Rapid storm tarp / water mitigation.' },
|
||||
{ id: 'sk_retail_estimate', name: 'Retail Estimate', description: 'Cash/retail bid preparation & close.' },
|
||||
{ id: 'sk_electrical', name: 'Electrical', description: 'Panel/wiring/EV per NEC.' },
|
||||
{ id: 'sk_drone_survey', name: 'Drone Survey', description: 'Aerial roof imaging & measurement.' },
|
||||
{ id: 'sk_customer_comms', name: 'Customer Communication', description: 'Homeowner rapport & expectation-setting.' },
|
||||
];
|
||||
|
||||
const MOCK_SUBCONTRACTOR_TASKS = [
|
||||
// -------------------------------------------------------------------
|
||||
// sct_001 — Maya Patel (sub_002) — fully populated reference task
|
||||
@@ -8033,6 +8045,585 @@ function seedLeadsFromAttribution() {
|
||||
});
|
||||
}
|
||||
|
||||
// --- PERSON PROFILES ---
|
||||
|
||||
function seedProfiles() {
|
||||
return {
|
||||
// ── Field Agents ──────────────────────────────────────────────────────
|
||||
e1: {
|
||||
self: {
|
||||
preferredName: 'Cody',
|
||||
photo: '',
|
||||
phone: '972-555-1040',
|
||||
altContact: '',
|
||||
address: '4210 Park Blvd, Plano, TX 75093',
|
||||
emergencyContact: 'Kim Tatum · 972-555-1041',
|
||||
nickname: 'The Storm Dog',
|
||||
pronouns: 'he/him',
|
||||
gender: 'Male',
|
||||
sex: '',
|
||||
bio: 'Six-year field vet who lives for storm season. Built his reputation on same-day tarp calls and bulletproof supplement packages. Runs a DJI drone for every steep-slope job.',
|
||||
yearsExperience: 6,
|
||||
languages: ['English', 'Spanish (conversational)'],
|
||||
specialties: ['Storm Damage', 'Insurance Claims', 'Emergency Tarping'],
|
||||
equipment: ['ladder rack', 'drone', 'tarp kit'],
|
||||
availability: 'Mon–Sat 7 am–7 pm',
|
||||
serviceAreas: ['Plano', 'Allen', 'Frisco', 'McKinney'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Top revenue producer. Mentor candidate for Travis Boone.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 88 },
|
||||
{ skillId: 'sk_roof_inspection', score: 81 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 92 },
|
||||
{ skillId: 'sk_retail_estimate', score: 74 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 85 },
|
||||
{ skillId: 'sk_customer_comms', score: 79 },
|
||||
],
|
||||
payTerms: 'Commission 12% gross',
|
||||
hireDate: '2020-03-15',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 8,
|
||||
xp: 12450,
|
||||
streak: 5,
|
||||
badges: ['Hot Spot Hunter', 'Storm Chaser'],
|
||||
tiers: ['Silver'],
|
||||
},
|
||||
},
|
||||
|
||||
e2: {
|
||||
self: {
|
||||
preferredName: 'Hannah',
|
||||
photo: '',
|
||||
phone: '972-555-1041',
|
||||
altContact: '',
|
||||
address: '812 Ridgecrest Dr, Richardson, TX 75080',
|
||||
emergencyContact: 'Marco Reyes · 214-555-8821',
|
||||
nickname: '',
|
||||
pronouns: 'she/her',
|
||||
gender: 'Female',
|
||||
sex: '',
|
||||
bio: 'High-volume grinder with a talent for retail closes on cash-pay jobs. Reliable on gutters and siding add-ons. Building out drone cert for next season.',
|
||||
yearsExperience: 4,
|
||||
languages: ['English', 'Spanish'],
|
||||
specialties: ['Retail Estimate', 'Gutters', 'Customer Relations'],
|
||||
equipment: ['ladder rack', 'measuring wheel', 'pitch gauge'],
|
||||
availability: 'Mon–Fri 8 am–6 pm, Sat 9 am–3 pm',
|
||||
serviceAreas: ['Plano', 'Richardson', 'Garland'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Consistent mid-tier producer. Great at converting retail leads.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 65 },
|
||||
{ skillId: 'sk_roof_inspection', score: 70 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 55 },
|
||||
{ skillId: 'sk_retail_estimate', score: 89 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 38 },
|
||||
{ skillId: 'sk_customer_comms', score: 91 },
|
||||
],
|
||||
payTerms: 'Commission 10% gross',
|
||||
hireDate: '2021-08-02',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 6,
|
||||
xp: 8200,
|
||||
streak: 2,
|
||||
badges: ['Star Closer'],
|
||||
tiers: ['Silver'],
|
||||
},
|
||||
},
|
||||
|
||||
e3: {
|
||||
self: {
|
||||
preferredName: 'Travis',
|
||||
photo: '',
|
||||
phone: '972-555-1042',
|
||||
altContact: '',
|
||||
address: '231 Maple Creek Ln, Plano, TX 75025',
|
||||
emergencyContact: 'Sue Boone · 972-555-3310',
|
||||
nickname: 'Rookie',
|
||||
pronouns: '',
|
||||
gender: '',
|
||||
sex: '',
|
||||
bio: 'First season in residential roofing after two years in HVAC sales. Still building his route and supplement knowledge — eager learner with good people skills.',
|
||||
yearsExperience: 1,
|
||||
languages: ['English'],
|
||||
specialties: ['Customer Communication'],
|
||||
equipment: ['tape measure', 'clipboard'],
|
||||
availability: 'Mon–Fri 9 am–5 pm',
|
||||
serviceAreas: ['Plano', 'Frisco'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'New hire — needs coaching on insurance claims and roof measurements. Paired with Cody for shadow rides.',
|
||||
statusTags: ['probation'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 28 },
|
||||
{ skillId: 'sk_roof_inspection', score: 41 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 33 },
|
||||
{ skillId: 'sk_retail_estimate', score: 50 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 67 },
|
||||
],
|
||||
payTerms: 'Draw $2,000/mo against commission 8%',
|
||||
hireDate: '2025-11-01',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 2,
|
||||
xp: 2100,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
e4: {
|
||||
self: {
|
||||
preferredName: 'Shelby',
|
||||
photo: '',
|
||||
phone: '972-555-1043',
|
||||
altContact: '214-555-7730',
|
||||
address: '6801 Collin McKinney Pkwy #114, McKinney, TX 75070',
|
||||
emergencyContact: 'Drew Greer · 972-555-0442',
|
||||
nickname: 'Map Master',
|
||||
pronouns: 'she/her',
|
||||
gender: 'Female',
|
||||
sex: '',
|
||||
bio: 'Top canvasser with the firmest door-knock-to-appointment ratio on the team. Consistently earns Map Master badge each storm season. Doubles as an informal team lead on big-event deployments.',
|
||||
yearsExperience: 5,
|
||||
languages: ['English'],
|
||||
specialties: ['Storm Damage', 'Insurance Claims', 'Canvassing Ops'],
|
||||
equipment: ['ladder rack', 'drone', 'moisture meter', 'tarp kit'],
|
||||
availability: 'Mon–Sat 7 am–8 pm',
|
||||
serviceAreas: ['Plano', 'Allen', 'McKinney', 'Frisco', 'Murphy'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Highest XP on the team. Ready for team-lead responsibility when headcount grows.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 85 },
|
||||
{ skillId: 'sk_roof_inspection', score: 88 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 78 },
|
||||
{ skillId: 'sk_retail_estimate', score: 72 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 80 },
|
||||
{ skillId: 'sk_customer_comms', score: 84 },
|
||||
],
|
||||
payTerms: 'Commission 12% gross + team bonus',
|
||||
hireDate: '2021-01-10',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 10,
|
||||
xp: 15600,
|
||||
streak: 8,
|
||||
badges: ['Map Master', 'Hot Spot Hunter', 'Storm Chaser'],
|
||||
tiers: ['Gold'],
|
||||
},
|
||||
},
|
||||
|
||||
e5: {
|
||||
self: {
|
||||
preferredName: 'Dalton',
|
||||
photo: '',
|
||||
phone: '972-555-1044',
|
||||
altContact: '',
|
||||
address: '1501 Custer Rd Apt 202, Plano, TX 75075',
|
||||
emergencyContact: 'Pam Pruitt · 903-555-1188',
|
||||
nickname: '',
|
||||
pronouns: '',
|
||||
gender: 'Male',
|
||||
sex: '',
|
||||
bio: "Selective deal-maker who rarely loses a close. Prefers retail cash jobs and works a tight territory around west Plano. First Knock badge holder from onboarding week — hasn't looked back.",
|
||||
yearsExperience: 2,
|
||||
languages: ['English'],
|
||||
specialties: ['Retail Estimate', 'Windows', 'Customer Communication'],
|
||||
equipment: ['ladder rack', 'window measuring kit'],
|
||||
availability: 'Mon–Fri 9 am–6 pm',
|
||||
serviceAreas: ['West Plano', 'Carrollton', 'Addison'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'High win-rate, low volume. Encourage expanding territory and storm supplement skills.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 60 },
|
||||
{ skillId: 'sk_roof_inspection', score: 65 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 45 },
|
||||
{ skillId: 'sk_retail_estimate', score: 87 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 88 },
|
||||
],
|
||||
payTerms: 'Commission 10% gross',
|
||||
hireDate: '2024-04-22',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 4,
|
||||
xp: 5400,
|
||||
streak: 1,
|
||||
badges: ['First Knock'],
|
||||
tiers: ['Bronze'],
|
||||
},
|
||||
},
|
||||
|
||||
// ── Sales Reps ────────────────────────────────────────────────────────
|
||||
p1: {
|
||||
self: {
|
||||
preferredName: 'Jesus',
|
||||
photo: '',
|
||||
phone: '214-555-0101',
|
||||
altContact: '',
|
||||
address: '3002 Ave K, Plano, TX 75074',
|
||||
emergencyContact: 'Maria Gonzales · 214-555-0110',
|
||||
nickname: 'JG',
|
||||
pronouns: '',
|
||||
gender: 'Male',
|
||||
sex: '',
|
||||
bio: 'W2 sales manager for Team A. Eight years in residential restoration sales; oversees Sarah Calloway and coordinates agent territory assignments.',
|
||||
yearsExperience: 8,
|
||||
languages: ['English', 'Spanish'],
|
||||
specialties: ['Insurance Claims', 'Team Leadership', 'Territory Planning'],
|
||||
equipment: ['company vehicle', 'laptop', 'CRM tablet'],
|
||||
availability: 'Mon–Fri 8 am–5 pm',
|
||||
serviceAreas: ['Plano', 'Allen', 'McKinney', 'Frisco'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Team A lead. Strong carrier supplement background. Enforce pay-plan signature for direct reports.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 94 },
|
||||
{ skillId: 'sk_roof_inspection', score: 82 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 60 },
|
||||
{ skillId: 'sk_retail_estimate', score: 78 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 55 },
|
||||
{ skillId: 'sk_customer_comms', score: 90 },
|
||||
],
|
||||
payTerms: 'W2 salary $72,000 + 3% override on team revenue',
|
||||
hireDate: '2018-06-01',
|
||||
managerId: 'own_001',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
p2: {
|
||||
self: {
|
||||
preferredName: 'Sarah',
|
||||
photo: '',
|
||||
phone: '214-555-0102',
|
||||
altContact: '',
|
||||
address: '500 Spring Creek Pkwy, Plano, TX 75023',
|
||||
emergencyContact: 'Brian Calloway · 972-555-4422',
|
||||
nickname: '',
|
||||
pronouns: 'she/her',
|
||||
gender: 'Female',
|
||||
sex: '',
|
||||
bio: '1099 sales rep specializing in residential retail and insurance-funded jobs. Has a strong referral network in the east Plano HOA belt. Driver license expiring soon — remind to renew.',
|
||||
yearsExperience: 3,
|
||||
languages: ['English'],
|
||||
specialties: ['Retail Estimate', 'HOA Accounts', 'Customer Communication'],
|
||||
equipment: ['personal vehicle', 'iPad with Xactimate viewer'],
|
||||
availability: 'Tue–Sat 9 am–5 pm',
|
||||
serviceAreas: ['East Plano', 'Garland', 'Wylie'],
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Pay plan not yet signed — follow up immediately. DL expiring 2025-12-01.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 62 },
|
||||
{ skillId: 'sk_roof_inspection', score: 58 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 'N/A' },
|
||||
{ skillId: 'sk_retail_estimate', score: 83 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 86 },
|
||||
],
|
||||
payTerms: '1099 flat $2,000/job closed + 5% bonus on monthly gross > $60k',
|
||||
hireDate: '2023-03-14',
|
||||
managerId: 'p1',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
// ── Subcontractors ────────────────────────────────────────────────────
|
||||
sub_001: {
|
||||
self: {
|
||||
preferredName: 'Carlos',
|
||||
photo: '',
|
||||
phone: '469-555-9012',
|
||||
altContact: '469-555-9013',
|
||||
address: '811 Industrial Blvd, Garland, TX 75042',
|
||||
emergencyContact: 'Rosa Mendoza · 469-555-9015',
|
||||
nickname: 'Sparky',
|
||||
pronouns: '',
|
||||
gender: 'Male',
|
||||
sex: '',
|
||||
bio: 'Licensed master electrician with 14 years in residential and light commercial. Specializes in panel replacements, EV charger installs, and storm-related electrical rehab. Runs a bucket truck for 2-story work.',
|
||||
yearsExperience: 14,
|
||||
languages: ['English', 'Spanish'],
|
||||
specialties: ['Panel Replacement', 'EV Charger Install', 'Storm Electrical Rehab'],
|
||||
equipment: ['tarp', 'panel tester', 'bucket truck'],
|
||||
availability: 'Mon–Fri 7 am–5 pm',
|
||||
serviceAreas: ['Plano', 'Allen', 'Garland', 'Richardson'],
|
||||
license: 'TX-ELEC-ME-88234',
|
||||
insurance: { coi: 'COI-CARLOS-2025', expiry: '2026-09-30' },
|
||||
w9Status: 'signed',
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Preferred electrical sub for panel replacements. Fast turnaround on permits.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 35 },
|
||||
{ skillId: 'sk_roof_inspection', score: 'N/A' },
|
||||
{ skillId: 'sk_emergency_tarp', score: 58 },
|
||||
{ skillId: 'sk_retail_estimate', score: 60 },
|
||||
{ skillId: 'sk_electrical', score: 96 },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 71 },
|
||||
],
|
||||
payTerms: 'Net-15, 1099',
|
||||
hireDate: '2024-08-01',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
sub_002: {
|
||||
self: {
|
||||
preferredName: 'Maya',
|
||||
photo: '',
|
||||
phone: '214-555-1247',
|
||||
altContact: '',
|
||||
address: '2200 Skyline Dr, Carrollton, TX 75006',
|
||||
emergencyContact: 'Ravi Patel · 214-555-1248',
|
||||
nickname: '',
|
||||
pronouns: 'she/her',
|
||||
gender: 'Female',
|
||||
sex: '',
|
||||
bio: 'Roofing crew lead with 10 years running residential and commercial re-roofs. Detail-oriented on measurements and documentation — consistently produces clean Xactimate-ready inspection reports.',
|
||||
yearsExperience: 10,
|
||||
languages: ['English', 'Hindi'],
|
||||
specialties: ['Roof Inspection', 'Steep Slope', 'TPO Commercial', 'Damage Documentation'],
|
||||
equipment: ['drone', 'aerial measurement software', 'moisture scanner', 'pitch gauge'],
|
||||
availability: 'Mon–Sat 6 am–4 pm',
|
||||
serviceAreas: ['Plano', 'Frisco', 'Carrollton', 'Allen', 'McKinney'],
|
||||
license: 'TX-ROOFING-CR-44512',
|
||||
insurance: { coi: 'COI-MAYA-2025', expiry: '2026-12-31' },
|
||||
w9Status: 'signed',
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Top-rated roofing sub. Works with two org portfolios. Priority dispatch on large storm jobs.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 50 },
|
||||
{ skillId: 'sk_roof_inspection', score: 95 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 72 },
|
||||
{ skillId: 'sk_retail_estimate', score: 68 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 88 },
|
||||
{ skillId: 'sk_customer_comms', score: 74 },
|
||||
],
|
||||
payTerms: 'Net-10, 1099',
|
||||
hireDate: '2024-05-12',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
sub_003: {
|
||||
self: {
|
||||
preferredName: 'Dwayne',
|
||||
photo: '',
|
||||
phone: '972-555-8312',
|
||||
altContact: '',
|
||||
address: '408 Pecan St, Plano, TX 75074',
|
||||
emergencyContact: 'Celeste Boudreaux · 972-555-8313',
|
||||
nickname: 'D-Wayne',
|
||||
pronouns: '',
|
||||
gender: 'Male',
|
||||
sex: '',
|
||||
bio: 'Second-generation painter running a four-man crew. Does interior and exterior residential. Known for clean lines and staying on schedule — no callbacks on paint work in two years.',
|
||||
yearsExperience: 11,
|
||||
languages: ['English', 'Cajun French (limited)'],
|
||||
specialties: ['Exterior Repaint', 'Interior Touch-up', 'Deck Stain'],
|
||||
equipment: ['airless sprayer', 'scaffolding', 'color matching tools'],
|
||||
availability: 'Mon–Fri 8 am–5 pm',
|
||||
serviceAreas: ['Plano', 'Allen', 'McKinney'],
|
||||
license: 'TX-PAINT-CONT-31109',
|
||||
insurance: { coi: 'COI-DWAYNE-2025', expiry: '2026-07-31' },
|
||||
w9Status: 'signed',
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Reliable painter. Often the last trade on a job — keep informed of schedule changes.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 'N/A' },
|
||||
{ skillId: 'sk_roof_inspection', score: 'N/A' },
|
||||
{ skillId: 'sk_emergency_tarp', score: 30 },
|
||||
{ skillId: 'sk_retail_estimate', score: 55 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 69 },
|
||||
],
|
||||
payTerms: 'Net-15, 1099',
|
||||
hireDate: '2024-09-21',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
sub_004: {
|
||||
self: {
|
||||
preferredName: 'Jennifer',
|
||||
photo: '',
|
||||
phone: '469-555-3340',
|
||||
altContact: '469-555-3341',
|
||||
address: '3900 Eldorado Pkwy, McKinney, TX 75070',
|
||||
emergencyContact: 'David Castillo · 469-555-3342',
|
||||
nickname: 'Jenn',
|
||||
pronouns: 'she/her',
|
||||
gender: 'Female',
|
||||
sex: '',
|
||||
bio: 'Master plumber with licenses in Texas and Oklahoma. Her crew handles storm-related plumbing rehab, re-pipes, and fixture installs. Highest rating on the platform at 4.9.',
|
||||
yearsExperience: 12,
|
||||
languages: ['English', 'Spanish'],
|
||||
specialties: ['Storm Plumbing Rehab', 'Re-pipe', 'Fixture Install', 'Leak Detection'],
|
||||
equipment: ['pipe camera', 'hydro-jetter', 'leak detector', 'service van'],
|
||||
availability: 'Mon–Sat 7 am–6 pm + emergency on-call',
|
||||
serviceAreas: ['Plano', 'Allen', 'McKinney', 'Frisco', 'Prosper'],
|
||||
license: 'TX-PLUMB-MP-77421',
|
||||
insurance: { coi: 'COI-JENN-2025', expiry: '2027-03-15' },
|
||||
w9Status: 'signed',
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Highest-rated sub on the roster. First call for any water intrusion / storm plumbing job.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 42 },
|
||||
{ skillId: 'sk_roof_inspection', score: 'N/A' },
|
||||
{ skillId: 'sk_emergency_tarp', score: 48 },
|
||||
{ skillId: 'sk_retail_estimate', score: 66 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 80 },
|
||||
],
|
||||
payTerms: 'Net-10, 1099',
|
||||
hireDate: '2024-02-10',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
|
||||
sub_005: {
|
||||
self: {
|
||||
preferredName: 'Greg',
|
||||
photo: '',
|
||||
phone: '214-555-0299',
|
||||
altContact: '',
|
||||
address: '1723 Oak Hollow Ln, Carrollton, TX 75007',
|
||||
emergencyContact: 'Diane Alston · 214-555-0300',
|
||||
nickname: '',
|
||||
pronouns: '',
|
||||
gender: 'Male',
|
||||
sex: '',
|
||||
bio: 'Window and glazing specialist with a decade on residential and light commercial installs. Currently on inactive roster while managing a family situation — available for project-by-project work.',
|
||||
yearsExperience: 10,
|
||||
languages: ['English'],
|
||||
specialties: ['Window Replacement', 'Storm Window Install', 'Sliding Door Rehab'],
|
||||
equipment: ['glass handler', 'suction cups', 'truck ladder', 'silicone kit'],
|
||||
availability: 'Flexible – project basis only',
|
||||
serviceAreas: ['Plano', 'Carrollton', 'Addison', 'Farmers Branch'],
|
||||
license: 'TX-GLAZING-CR-55831',
|
||||
insurance: { coi: 'COI-GREG-2025', expiry: '2026-06-30' },
|
||||
w9Status: 'signed',
|
||||
},
|
||||
company: {
|
||||
internalNotes: 'Inactive status. Still preferred when available — quality work, zero callbacks. Check in quarterly.',
|
||||
statusTags: ['preferred'],
|
||||
skillScores: [
|
||||
{ skillId: 'sk_insurance_claim', score: 'N/A' },
|
||||
{ skillId: 'sk_roof_inspection', score: 35 },
|
||||
{ skillId: 'sk_emergency_tarp', score: 40 },
|
||||
{ skillId: 'sk_retail_estimate', score: 58 },
|
||||
{ skillId: 'sk_electrical', score: 'N/A' },
|
||||
{ skillId: 'sk_drone_survey', score: 'N/A' },
|
||||
{ skillId: 'sk_customer_comms', score: 72 },
|
||||
],
|
||||
payTerms: 'Net-15, 1099',
|
||||
hireDate: '2023-11-15',
|
||||
managerId: 'a1',
|
||||
},
|
||||
achievements: {
|
||||
level: 0,
|
||||
xp: 0,
|
||||
streak: 0,
|
||||
badges: [],
|
||||
tiers: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Default empty profile for people who have no seed entry.
|
||||
const DEFAULT_EMPTY_PROFILE = {
|
||||
self: {
|
||||
preferredName: '', photo: '', phone: '', altContact: '', address: '',
|
||||
emergencyContact: '', nickname: '', pronouns: '', gender: '', sex: '',
|
||||
bio: '', yearsExperience: 0, languages: [], specialties: [], equipment: [],
|
||||
availability: '', serviceAreas: [],
|
||||
},
|
||||
company: {
|
||||
internalNotes: '', statusTags: [], skillScores: [],
|
||||
payTerms: '', hireDate: '', managerId: '',
|
||||
},
|
||||
achievements: { level: 0, xp: 0, streak: 0, badges: [], tiers: [] },
|
||||
};
|
||||
|
||||
// --- CONTEXT SETUP ---
|
||||
|
||||
const MockStoreContext = createContext();
|
||||
@@ -8179,6 +8770,10 @@ export const MockStoreProvider = ({ children }) => {
|
||||
const [subcontractorTasks, setSubcontractorTasks] = useState(MOCK_SUBCONTRACTOR_TASKS);
|
||||
const [notifications, setNotifications] = useState(MOCK_NOTIFICATIONS);
|
||||
|
||||
// ── Skill Catalog & Person Profiles ──────────────────────────────────────
|
||||
const [skillCatalog, setSkillCatalog] = useState(SKILL_CATALOG);
|
||||
const [profiles, setProfiles] = useState(seedProfiles);
|
||||
|
||||
// One lookup for any person across users/personnel/owners/subcontractors.
|
||||
const peopleIndex = useMemo(() => {
|
||||
const idx = {};
|
||||
@@ -8194,6 +8789,44 @@ export const MockStoreProvider = ({ children }) => {
|
||||
return { id: p.id, name: p.name || p.fullName || 'Unknown', email: p.email || p.emailAddress || '', role: p.role || '' };
|
||||
};
|
||||
|
||||
// ── Profile mutators & selectors ─────────────────────────────────────────
|
||||
const resolveProfile = (personId) => ({
|
||||
...resolvePerson(personId),
|
||||
profile: profiles[personId] || DEFAULT_EMPTY_PROFILE,
|
||||
});
|
||||
|
||||
const updateOwnProfile = (personId, selfPatch) =>
|
||||
setProfiles(prev => ({
|
||||
...prev,
|
||||
[personId]: {
|
||||
...prev[personId],
|
||||
self: { ...(prev[personId]?.self || {}), ...selfPatch },
|
||||
},
|
||||
}));
|
||||
|
||||
const setSkillScore = (personId, skillId, score) =>
|
||||
setProfiles(prev => {
|
||||
const existing = prev[personId] || { ...DEFAULT_EMPTY_PROFILE };
|
||||
const oldScores = existing.company?.skillScores || [];
|
||||
const idx = oldScores.findIndex(s => s.skillId === skillId);
|
||||
const newScores = idx >= 0
|
||||
? oldScores.map((s, i) => i === idx ? { ...s, score } : s)
|
||||
: [...oldScores, { skillId, score }];
|
||||
return {
|
||||
...prev,
|
||||
[personId]: {
|
||||
...existing,
|
||||
company: { ...(existing.company || {}), skillScores: newScores },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const addCatalogSkill = (skill) =>
|
||||
setSkillCatalog(prev => [...prev, skill]);
|
||||
|
||||
const updateCatalogSkill = (id, patch) =>
|
||||
setSkillCatalog(prev => prev.map(s => s.id === id ? { ...s, ...patch } : s));
|
||||
|
||||
// Initialize properties once
|
||||
useEffect(() => {
|
||||
const data = generateProperties();
|
||||
@@ -8949,6 +9582,15 @@ export const MockStoreProvider = ({ children }) => {
|
||||
addNotification,
|
||||
markNotificationRead,
|
||||
resolvePerson,
|
||||
// ── Skill Catalog ──
|
||||
skillCatalog,
|
||||
addCatalogSkill,
|
||||
updateCatalogSkill,
|
||||
// ── Person Profiles ──
|
||||
profiles,
|
||||
resolveProfile,
|
||||
updateOwnProfile,
|
||||
setSkillScore,
|
||||
}}>
|
||||
{children}
|
||||
</MockStoreContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user