diff --git a/src/data/mockStore.jsx b/src/data/mockStore.jsx index 37e418c..db0ef24 100644 --- a/src/data/mockStore.jsx +++ b/src/data/mockStore.jsx @@ -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}