Fix up a ton of pages, settings/help/wiki need improvements, report generation needs slight updates. Otherwise completed

This commit is contained in:
Ra
2025-08-25 02:08:21 -07:00
parent 1ed3e16ff6
commit df7020cdd4
29 changed files with 3671 additions and 4684 deletions

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { useAuth } from './AuthContext';
import { Employee, Report, Submission, CompanyReport } from '../types';
import { Employee, EmployeeReport, Submission, CompanyReport } from '../types';
import { SAMPLE_COMPANY_REPORT, API_URL } from '../constants';
import { apiPost, apiPut } from '../services/api';
import { User } from 'firebase/auth';
@@ -9,29 +9,10 @@ import { secureApi } from '../services/secureApi';
interface OrgData {
orgId: string;
name: string;
industry?: string;
size?: string;
description?: string;
mission?: string;
vision?: string;
values?: string;
foundingYear?: string;
evolution?: string;
majorMilestones?: string;
advantages?: string;
vulnerabilities?: string;
competitors?: string;
marketPosition?: string;
currentChallenges?: string;
shortTermGoals?: string;
longTermGoals?: string;
keyMetrics?: string;
cultureDescription?: string;
workEnvironment?: string;
leadershipStyle?: string;
communicationStyle?: string;
additionalContext?: string;
companyName?: string;
onboardingData?: Record<string, any>;
companyLogo?: string;
updatedAt?: number;
onboardingCompleted?: boolean;
}
@@ -41,16 +22,16 @@ interface OrgContextType {
orgId: string;
employees: Employee[];
submissions: Record<string, Submission>;
reports: Record<string, Report>;
reports: Record<string, EmployeeReport>;
loading: boolean;
upsertOrg: (data: Partial<OrgData>) => Promise<void>;
saveReport: (employeeId: string, report: Report) => Promise<void>;
saveReport: (employeeId: string, report: EmployeeReport) => Promise<void>;
inviteEmployee: (args: { name: string; email: string }) => Promise<{ employeeId: string; inviteLink: string }>;
issueInviteViaApi: (args: { name: string; email: string; role?: string; department?: string }) => Promise<{ code: string; inviteLink: string; emailLink: string; employee: any }>;
getInviteStatus: (code: string) => Promise<{ used: boolean; employee: any } | null>;
consumeInvite: (code: string) => Promise<{ employee: any; orgId?: string } | null>;
getReportVersions: (employeeId: string) => Promise<Array<{ id: string; createdAt: number; report: Report }>>;
saveReportVersion: (employeeId: string, report: Report) => Promise<void>;
getReportVersions: (employeeId: string) => Promise<Array<{ id: string; createdAt: number; report: EmployeeReport }>>;
saveReportVersion: (employeeId: string, report: EmployeeReport) => Promise<void>;
acceptInvite: (code: string) => Promise<void>;
saveCompanyReport: (summary: string) => Promise<void>;
getCompanyReportHistory: () => Promise<Array<{ id: string; createdAt: number; summary: string }>>;
@@ -61,9 +42,9 @@ interface OrgContextType {
seedInitialData: () => Promise<void>;
isOwner: (employeeId?: string) => boolean;
submitEmployeeAnswers: (employeeId: string, answers: Record<string, string>) => Promise<any>;
generateEmployeeReport: (employee: Employee) => Promise<Report | null>;
getEmployeeReport: (employeeId: string) => Promise<{ success: boolean; report?: Report; error?: string }>;
getEmployeeReports: () => Promise<{ success: boolean; reports?: Report[]; error?: string }>;
generateEmployeeReport: (employee: Employee) => Promise<EmployeeReport | null>;
getEmployeeReport: (employeeId: string) => Promise<{ success: boolean; report?: EmployeeReport; error?: string }>;
getEmployeeReports: () => Promise<{ success: boolean; reports?: EmployeeReport[]; error?: string }>;
}
const OrgContext = createContext<OrgContextType | undefined>(undefined);
@@ -73,8 +54,8 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
const [org, setOrg] = useState<OrgData | null>(null);
const [employees, setEmployees] = useState<Employee[]>([]);
const [submissions, setSubmissions] = useState<Record<string, Submission>>({});
const [reports, setReports] = useState<Record<string, Report>>({});
const [reportVersions, setReportVersions] = useState<Record<string, Array<{ id: string; createdAt: number; report: Report }>>>({});
const [reports, setReports] = useState<Record<string, EmployeeReport>>({});
const [reportVersions, setReportVersions] = useState<Record<string, Array<{ id: string; createdAt: number; report: EmployeeReport }>>>({});
const [companyReports, setCompanyReports] = useState<Array<{ id: string; createdAt: number; summary: string }>>([]);
const [fullCompanyReports, setFullCompanyReports] = useState<CompanyReport[]>([]);
const [loading, setLoading] = useState(true);
@@ -97,19 +78,19 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
// Load organization data
try {
const orgData = await secureApi.getOrgData(orgId, user.uid);
const orgData = await secureApi.getOrgData();
setOrg({ orgId, ...orgData });
} catch (error) {
console.warn('Could not load org data, creating default:', error);
// Create default org if not found
const defaultOrg = { name: 'Your Company', onboardingCompleted: false };
await secureApi.updateOrgData(orgId, user.uid, defaultOrg);
await secureApi.updateOrgData(defaultOrg);
setOrg({ orgId, ...defaultOrg });
}
// Load employees
try {
const employeesData = await secureApi.getEmployees(orgId, user.uid);
const employeesData = await secureApi.getEmployees();
setEmployees(employeesData.map(emp => ({
...emp,
initials: emp.name ? emp.name.split(' ').map(n => n[0]).join('').toUpperCase() : emp.email?.substring(0, 2).toUpperCase() || 'U'
@@ -121,7 +102,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
// Load submissions
try {
const submissionsData = await secureApi.getSubmissions(orgId, user.uid);
const submissionsData = await secureApi.getSubmissions();
setSubmissions(submissionsData);
} catch (error) {
console.warn('Could not load submissions:', error);
@@ -130,8 +111,8 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
// Load reports
try {
const reportsData = await secureApi.getReports(orgId, user.uid);
setReports(reportsData as Record<string, Report>);
const reportsData = await secureApi.getReports();
setReports(reportsData as Record<string, EmployeeReport>);
} catch (error) {
console.warn('Could not load reports:', error);
setReports({});
@@ -139,7 +120,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
// Load company reports
try {
const companyReportsData = await secureApi.getCompanyReports(orgId, user.uid);
const companyReportsData = await secureApi.getCompanyReports();
setFullCompanyReports(companyReportsData);
} catch (error) {
console.warn('Could not load company reports:', error);
@@ -162,7 +143,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
try {
await secureApi.updateOrgData(orgId, user.uid, data);
await secureApi.updateOrgData(data);
// Update local state
const updatedOrg = { ...(org || { orgId, name: 'Your Company' }), ...data } as OrgData;
@@ -185,13 +166,13 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
};
const saveReport = async (employeeId: string, report: Report) => {
const saveReport = async (employeeId: string, report: EmployeeReport) => {
if (!user?.uid) {
throw new Error('User authentication required');
}
try {
const savedReport = await secureApi.saveReport(orgId, user.uid, employeeId, report);
const savedReport = await secureApi.saveReport(employeeId, report);
// Update local state
setReports(prev => ({ ...prev, [employeeId]: savedReport }));
@@ -206,7 +187,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
try {
// Use secure API for invites
const data = await secureApi.createInvitation(orgId, name, email);
const data = await secureApi.createInvitation(name, email);
console.log('Invite created successfully:', { code: data.code, employee: data.employee.name, inviteLink: data.inviteLink });
@@ -241,7 +222,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
return [];
};
const saveReportVersion = async (employeeId: string, report: Report) => {
const saveReportVersion = async (employeeId: string, report: EmployeeReport) => {
// This feature is not yet implemented in secure API
console.warn('Report versions not yet supported in secure API');
const version = { id: Date.now().toString(), createdAt: Date.now(), report };
@@ -271,7 +252,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
summary
};
await secureApi.saveCompanyReport(orgId, report);
await secureApi.saveCompanyReport(report);
// Update local state
setCompanyReports(prev => [{ id: report.id, createdAt: report.createdAt, summary }, ...prev]);
@@ -287,11 +268,11 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
try {
const reports = await secureApi.getCompanyReports(orgId, user.uid);
const reports = await secureApi.getCompanyReports();
return reports.map(report => ({
id: report.id,
createdAt: report.createdAt || 0,
summary: report.summary || ''
summary: report.executiveSummary || ''
})).sort((a, b) => b.createdAt - a.createdAt);
} catch (error) {
console.error('Failed to get company report history:', error);
@@ -318,7 +299,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
try {
await secureApi.saveCompanyReport(orgId, report);
await secureApi.saveCompanyReport(report);
// Update local state after successful save
setFullCompanyReports(prev => [report, ...prev]);
@@ -334,7 +315,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
try {
const reports = await secureApi.getCompanyReports(orgId, user.uid);
const reports = await secureApi.getCompanyReports();
return reports.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0));
} catch (error) {
console.error('Failed to get full company report history:', error);
@@ -477,7 +458,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
// Use secure API for all employee report operations
const report = await secureApi.getReports(orgId, user.uid);
const report = await secureApi.getReports();
const employeeReport = report[employeeId];
if (employeeReport) {
@@ -497,7 +478,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
// Use secure API for all employee report operations
const reportsData = await secureApi.getReports(orgId, user.uid);
const reportsData = await secureApi.getReports();
const reports = Object.values(reportsData);
return { success: true, reports };
} catch (error) {
@@ -533,7 +514,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
throw new Error('User authentication required');
}
const data = await secureApi.createInvitation(orgId, name, email, role, department);
const data = await secureApi.createInvitation(name, email, role, department);
// Optimistically add employee shell (not yet active until consume)
setEmployees(prev => prev.find(e => e.id === data.employee.id) ? prev : [...prev, {
@@ -580,7 +561,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
}
// Use secure API for submission
await secureApi.submitEmployeeAnswers(orgId, employeeId, answers);
await secureApi.submitEmployeeAnswers(employeeId, answers);
// Update local state for immediate UI feedback
const convertedSubmission: Submission = {
@@ -647,7 +628,7 @@ export const OrgProvider: React.FC<{ children: React.ReactNode; selectedOrgId: s
if ((data as any).report) {
console.log('Employee report generated successfully');
const report = (data as any).report as Report;
const report = (data as any).report as EmployeeReport;
setReports(prev => ({ ...prev, [employee.id]: report }));
return report;
} else {