From daa89b6cbf50bc6ff27eb9578caebbbe8b55c81d Mon Sep 17 00:00:00 2001 From: Ra Date: Mon, 25 Aug 2025 10:46:46 -0700 Subject: [PATCH] update, not done --- index.css | 2 + index.tsx | 4 +- src/App.tsx | 6 +- .../CompanyWiki/CompanyWikiCompletedState.tsx | 6 +- .../CompanyWiki/CompanyWikiEmptyState.tsx | 16 +- .../CompanyWiki/CompanyWikiEmptyStateDark.tsx | 8 +- .../CompanyWiki/InviteEmployeesModal.tsx | 4 +- .../InviteMultipleEmployeesModal.tsx | 6 +- src/constants.ts | 194 +++--- src/data/onboardingSteps.ts | 322 ++++----- src/pages/Chat.tsx | 2 +- src/pages/CompanyWiki.tsx | 396 ++++++++--- src/pages/CompanyWikiNew.tsx | 263 +++++++ src/pages/HelpNew.tsx | 4 +- src/pages/Onboarding.tsx | 1 - src/pages/Reports.tsx | 649 ++++++++---------- src/pages/SettingsNew.tsx | 6 +- src/pages/Submissions.tsx | 326 +++++++++ src/pages/figma/ChatAIResponse.tsx | 8 +- src/pages/figma/ChatLight.tsx | 12 +- src/services/secureApi.ts | 13 +- src/types.ts | 63 +- 22 files changed, 1526 insertions(+), 785 deletions(-) create mode 100644 src/pages/CompanyWikiNew.tsx create mode 100644 src/pages/Submissions.tsx diff --git a/index.css b/index.css index 69acd8b..68952e4 100644 --- a/index.css +++ b/index.css @@ -79,6 +79,8 @@ --button-bg-primary : #5E48FC; --button-border-primary: #7B64FF; + + --white: #FFFFFF; } .dark { diff --git a/index.tsx b/index.tsx index 8c06fba..7a8e858 100644 --- a/index.tsx +++ b/index.tsx @@ -11,7 +11,5 @@ if (!rootElement) { const root = ReactDOM.createRoot(rootElement); root.render( - - - + ); diff --git a/src/App.tsx b/src/App.tsx index 9102103..0e22328 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import { Layout } from './components/UiKit'; import CompanyWiki from './pages/CompanyWiki'; // import Report from '../deprecated/pages/EmployeeData'; import Reports from './pages/Reports'; +import Submissions from './pages/Submissions'; import Chat from './pages/Chat'; import HelpNew from './pages/HelpNew'; import SettingsNew from './pages/SettingsNew'; @@ -257,10 +258,7 @@ function App() { > } /> } /> - {/* - This is the old reports page - } /> - */} + } /> } /> } /> } /> diff --git a/src/components/CompanyWiki/CompanyWikiCompletedState.tsx b/src/components/CompanyWiki/CompanyWikiCompletedState.tsx index b108369..ebe5664 100644 --- a/src/components/CompanyWiki/CompanyWikiCompletedState.tsx +++ b/src/components/CompanyWiki/CompanyWikiCompletedState.tsx @@ -70,9 +70,9 @@ export const CompanyWikiCompletedState: React.FC
onSectionClick?.(sectionNumber)} - className={`self-stretch p-2 rounded-[10px] inline-flex justify-start items-center gap-2 overflow-hidden cursor-pointer hover:bg-Main-BG-Gray-50 dark:hover:bg-[--Neutrals-NeutralSlate700] ${isActive ? 'bg-Main-BG-Gray-100 dark:bg-[--Neutrals-NeutralSlate700] shadow-[0px_1px_2px_0px_rgba(10,13,20,0.03)]' : ''}`} + className={`self-stretch p-2 rounded-[10px] inline-flex justify-start items-center gap-2 overflow-hidden cursor-pointer hover:bg-[--Neutrals-NeutralSlate50] dark:hover:bg-[--Neutrals-NeutralSlate700] ${isActive ? 'bg-[--Neutrals-NeutralSlate100] dark:bg-[--Neutrals-NeutralSlate700] shadow-[0px_1px_2px_0px_rgba(10,13,20,0.03)]' : ''}`} > -
+
{sectionNumber}
@@ -116,7 +116,7 @@ export const CompanyWikiCompletedState: React.FC ))} {/* Additional Questions */} -
+
What is the mission of your company?
diff --git a/src/components/CompanyWiki/CompanyWikiEmptyState.tsx b/src/components/CompanyWiki/CompanyWikiEmptyState.tsx index 22395a3..47d2b9c 100644 --- a/src/components/CompanyWiki/CompanyWikiEmptyState.tsx +++ b/src/components/CompanyWiki/CompanyWikiEmptyState.tsx @@ -20,50 +20,50 @@ export const CompanyWikiEmptyState: React.FC = ({
Table of contents
-
+
1
Company Overview & Vision
-
+
2
Leadership & Organizational Structure
-
+
3
Operations & Execution
-
+
4
Culture & Team Health
-
+
5
Sales, Marketing & Growth
-
+
6
Financial Health & Metrics
-
+
7
Innovation & Product/Service Strategy
-
+
8
Personal Leadership & Risk
diff --git a/src/components/CompanyWiki/CompanyWikiEmptyStateDark.tsx b/src/components/CompanyWiki/CompanyWikiEmptyStateDark.tsx index 1aff944..cb99a18 100644 --- a/src/components/CompanyWiki/CompanyWikiEmptyStateDark.tsx +++ b/src/components/CompanyWiki/CompanyWikiEmptyStateDark.tsx @@ -39,9 +39,9 @@ export const CompanyWikiEmptyState: React.FC = ({ return (
-
+
{sectionNumber}
@@ -65,7 +65,7 @@ export const CompanyWikiEmptyState: React.FC = ({
{/* Progress Illustration Placeholder */} -
+
@@ -87,7 +87,7 @@ export const CompanyWikiEmptyState: React.FC = ({
{/* Progress Bar */} -
+
= ({
diff --git a/src/components/CompanyWiki/InviteMultipleEmployeesModal.tsx b/src/components/CompanyWiki/InviteMultipleEmployeesModal.tsx index 9cab93a..1602d1b 100644 --- a/src/components/CompanyWiki/InviteMultipleEmployeesModal.tsx +++ b/src/components/CompanyWiki/InviteMultipleEmployeesModal.tsx @@ -70,7 +70,7 @@ export const InviteMultipleEmployeesModal: React.FC diff --git a/src/constants.ts b/src/constants.ts index be9085e..27bf9cb 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -128,88 +128,118 @@ export const SAMPLE_COMPANY_REPORT: CompanyReport = { { title: 'Lack of Structure', description: 'People are confused about their roles. No one knows who\'s responsible.' }, { title: 'Communication Gaps', description: 'Information doesn\'t flow effectively between departments.' } ], - gradingBreakdown: { - departmentNameShort: 'Campaigns', - departmentName: 'Campaigns Department', - lead: 'Sarah Johnson', - support: 'Mike Chen', - departmentGrade: 'A', - executiveSummary: 'Campaigns team shows exceptional performance with strong collaboration and innovative approaches to client work.', - teamScores: [ - { - employeeName: 'Sarah Johnson', - grade: 'A+', - reliability: 9, - roleFit: 10, - scalability: 8, - output: 9, - initiative: 9 - }, - { - employeeName: 'Mike Chen', - grade: 'A', - reliability: 8, - roleFit: 9, - scalability: 7, - output: 8, - initiative: 8 - }, - { - employeeName: 'Lisa Wong', - grade: 'B+', - reliability: 7, - roleFit: 8, - scalability: 6, - output: 7, - initiative: 7 - }, - { - employeeName: 'Alex Rivera', - grade: 'A', - reliability: 8, - roleFit: 9, - scalability: 7, - output: 8, - initiative: 8 - }, - { - employeeName: 'Jamie Park', - grade: 'B', - reliability: 6, - roleFit: 7, - scalability: 6, - output: 6, - initiative: 7 - }, - { - employeeName: 'Taylor Smith', - grade: 'A', - reliability: 9, - roleFit: 9, - scalability: 8, - output: 9, - initiative: 8 - }, - { - employeeName: 'Jordan Lee', - grade: 'B+', - reliability: 7, - roleFit: 8, - scalability: 7, - output: 8, - initiative: 7 - }, - { - employeeName: 'Casey Johnson', - grade: 'A+', - reliability: 10, - roleFit: 9, - scalability: 9, - output: 10, - initiative: 9 - } - ] - }, + gradingBreakdown: [ + { + departmentNameShort: 'Campaigns', + departmentName: 'Campaigns Department', + lead: 'Sarah Johnson', + support: 'Mike Chen', + departmentGrade: 'A', + executiveSummary: 'Campaigns team shows exceptional performance with strong collaboration and innovative approaches to client work.', + teamScores: [ + { + employeeName: 'Sarah Johnson', + grade: 'A+', + reliability: 9, + roleFit: 10, + scalability: 8, + output: 9, + initiative: 9 + }, + { + employeeName: 'Mike Chen', + grade: 'A', + reliability: 8, + roleFit: 9, + scalability: 7, + output: 8, + initiative: 8 + }, + { + employeeName: 'Lisa Wong', + grade: 'B+', + reliability: 7, + roleFit: 8, + scalability: 6, + output: 7, + initiative: 7 + }, + { + employeeName: 'Alex Rivera', + grade: 'A', + reliability: 8, + roleFit: 9, + scalability: 7, + output: 8, + initiative: 8 + }, + { + employeeName: 'Jamie Park', + grade: 'B', + reliability: 6, + roleFit: 7, + scalability: 6, + output: 6, + initiative: 7 + }, + { + employeeName: 'Taylor Smith', + grade: 'A', + reliability: 9, + roleFit: 9, + scalability: 8, + output: 9, + initiative: 8 + }, + { + employeeName: 'Jordan Lee', + grade: 'B+', + reliability: 7, + roleFit: 8, + scalability: 7, + output: 8, + initiative: 7 + }, + { + employeeName: 'Casey Johnson', + grade: 'A+', + reliability: 10, + roleFit: 9, + scalability: 9, + output: 10, + initiative: 9 + } + ] + }, + { + departmentNameShort: 'Social Media', + departmentName: 'Social Media Department', + lead: 'Alex Rivera', + support: 'Taylor Smith', + departmentGrade: 'A-', + executiveSummary: 'Social Media team excels in engagement and content creation, driving significant brand awareness.', + teamScores: [ + { + employeeName: 'Alex Rivera', + grade: 'A', + reliability: 9, + roleFit: 9, + scalability: 8, + output: 9, + initiative: 8 + }, + { + employeeName: 'Taylor Smith', + grade: 'A-', + reliability: 8, + roleFit: 8, + scalability: 7, + output: 8, + initiative: 7 + } + ] + } + ], operatingPlan: { nextQuarterGoals: [], keyInitiatives: [], resourceNeeds: [], riskMitigation: [] }, personnelChanges: { newHires: [ diff --git a/src/data/onboardingSteps.ts b/src/data/onboardingSteps.ts index cb632a1..b5e6dc6 100644 --- a/src/data/onboardingSteps.ts +++ b/src/data/onboardingSteps.ts @@ -112,7 +112,7 @@ export const onboardingSteps: OnboardingStep[] = [ sectionPosition: 5, totalInSection: 9, type: 'question', - title: 'What is your company\'s vision for the future?', + title: 'What is your 5-year vision for the company?', placeholder: 'Type your answer....', field: 'vision', required: true, @@ -125,9 +125,9 @@ export const onboardingSteps: OnboardingStep[] = [ sectionPosition: 6, totalInSection: 9, type: 'question', - title: 'What does success look like for your company?', + title: 'What are your company\'s top 3 strategic advantages?', placeholder: 'Type your answer....', - field: 'successDefinition', + field: 'strategicAdvantages', required: true, rows: 6 }, @@ -138,9 +138,9 @@ export const onboardingSteps: OnboardingStep[] = [ sectionPosition: 7, totalInSection: 9, type: 'question', - title: 'What are your core company values?', + title: 'What are the biggest vulnerabilities or threats?', placeholder: 'Type your answer....', - field: 'coreValues', + field: 'vulnerabilities', required: true, rows: 6 }, @@ -151,9 +151,9 @@ export const onboardingSteps: OnboardingStep[] = [ sectionPosition: 8, totalInSection: 9, type: 'question', - title: 'What do you want to be known for in your industry?', + title: 'If the business were to double in size tomorrow, what would break first?', placeholder: 'Type your answer....', - field: 'industryReputation', + field: 'scalabilityChallenges', required: true, rows: 6 }, @@ -344,9 +344,9 @@ export const onboardingSteps: OnboardingStep[] = [ sectionPosition: 6, totalInSection: 7, type: 'question', - title: 'What recurring problems never seem to get solved?', + title: 'What processes feel fragile or inconsistent?', placeholder: 'Type your answer....', - field: 'recurringProblems', + field: 'fragileProcesses', required: true, rows: 6 }, @@ -357,9 +357,9 @@ export const onboardingSteps: OnboardingStep[] = [ sectionPosition: 7, totalInSection: 7, type: 'question', - title: 'What would you fix first if you had unlimited resources?', + title: 'What recurring problems never seem to get solved?', placeholder: 'Type your answer....', - field: 'wouldFixFirst', + field: 'recurringProblems', required: true, rows: 6 }, @@ -473,7 +473,7 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 1, - totalInSection: 9, + totalInSection: 8, type: 'intro', title: 'Sales, Marketing & Growth', description: 'Description about the topic and what it means.' @@ -483,11 +483,11 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 2, - totalInSection: 9, + totalInSection: 8, type: 'question', - title: 'How do customers typically find you?', + title: 'How consistent is your revenue pipeline?', placeholder: 'Type your answer....', - field: 'customerAcquisition', + field: 'revenuePipeline', required: true, rows: 6 }, @@ -496,11 +496,11 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 3, - totalInSection: 9, + totalInSection: 8, type: 'question', - title: 'What is your competitive advantage?', + title: 'Where do most of your customers come from?', placeholder: 'Type your answer....', - field: 'competitiveAdvantage', + field: 'customerAcquisition', required: true, rows: 6 }, @@ -509,11 +509,11 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 4, - totalInSection: 9, + totalInSection: 8, type: 'question', - title: 'Where do you lose potential customers?', + title: 'What is your customer acquisition cost (CAC)?', placeholder: 'Type your answer....', - field: 'customerLoss', + field: 'customerAcquisitionCost', required: true, rows: 6 }, @@ -522,11 +522,11 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 5, - totalInSection: 9, + totalInSection: 8, type: 'question', - title: 'What drives customer loyalty and retention?', + title: 'What\'s your average customer lifetime value (LTV)?', placeholder: 'Type your answer....', - field: 'customerLoyalty', + field: 'customerLifetimeValue', required: true, rows: 6 }, @@ -535,11 +535,11 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 6, - totalInSection: 9, + totalInSection: 8, type: 'question', - title: 'What marketing efforts have the best ROI?', + title: 'What channels or strategies are underutilized?', placeholder: 'Type your answer....', - field: 'marketingROI', + field: 'underutilizedChannels', required: true, rows: 6 }, @@ -548,11 +548,11 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 7, - totalInSection: 9, + totalInSection: 8, type: 'question', title: 'Where are you overspending with low ROI?', placeholder: 'Type your answer....', - field: 'overspending', + field: 'overspendingROI', required: true, rows: 6 }, @@ -561,252 +561,252 @@ export const onboardingSteps: OnboardingStep[] = [ section: 5, sectionName: "Sales, Marketing & Growth", sectionPosition: 8, - totalInSection: 9, + totalInSection: 8, type: 'question', - title: 'What would accelerate your growth the most?', + title: 'What is your current bottleneck in scaling revenue?', placeholder: 'Type your answer....', - field: 'growthAccelerator', - required: true, - rows: 6 - }, - { - id: 42, - section: 5, - sectionName: "Sales, Marketing & Growth", - sectionPosition: 9, - totalInSection: 9, - type: 'question', - title: 'What markets or opportunities are you not pursuing?', - placeholder: 'Type your answer....', - field: 'untappedOpportunities', + field: 'currentBottleneck', required: true, rows: 6 }, - // Section 6: Innovation & Product/Service Strategy (Steps 43-53) + // Section 6: Financial Health & Metrics + { + id: 42, + section: 6, + sectionName: "Financial Health & Metrics", + sectionPosition: 1, + totalInSection: 8, + type: 'intro', + title: 'Financial Health & Metrics', + description: 'Description about the topic and what it means.' + }, { id: 43, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 1, - totalInSection: 11, - type: 'intro', - title: 'Innovation & Product/Service Strategy', - description: 'Description about the topic and what it means.' + sectionName: "Financial Health & Metrics", + sectionPosition: 2, + totalInSection: 8, + type: 'question', + title: 'What is your monthly burn or overhead?', + placeholder: 'Type your answer....', + field: 'monthlyBurnOverhead', + required: true, + rows: 6 }, { id: 44, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 2, - totalInSection: 11, + sectionName: "Financial Health & Metrics", + sectionPosition: 3, + totalInSection: 8, type: 'question', - title: 'What new products or services are you considering?', + title: 'What is your current monthly/annual revenue?', placeholder: 'Type your answer....', - field: 'newProducts', + field: 'currentRevenue', required: true, rows: 6 }, { id: 45, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 3, - totalInSection: 11, + sectionName: "Financial Health & Metrics", + sectionPosition: 4, + totalInSection: 8, type: 'question', - title: 'How do you stay innovative and ahead of trends?', + title: 'What is your current net profit margin?', placeholder: 'Type your answer....', - field: 'innovationProcess', + field: 'netProfitMargin', required: true, rows: 6 }, { id: 46, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 4, - totalInSection: 11, + sectionName: "Financial Health & Metrics", + sectionPosition: 5, + totalInSection: 8, type: 'question', - title: 'What customer problems are you uniquely positioned to solve?', + title: 'Are your financials up to date and properly reported?', placeholder: 'Type your answer....', - field: 'uniquePosition', + field: 'financialsUpToDate', required: true, rows: 6 }, { id: 47, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 5, - totalInSection: 11, + sectionName: "Financial Health & Metrics", + sectionPosition: 6, + totalInSection: 8, type: 'question', - title: 'Where do you see your industry heading?', + title: 'What would your team do differently if they had full financial transparency?', placeholder: 'Type your answer....', - field: 'industryDirection', + field: 'financialGrowthPlanning', required: true, rows: 6 }, { id: 48, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 6, - totalInSection: 11, + sectionName: "Financial Health & Metrics", + sectionPosition: 7, + totalInSection: 8, type: 'question', - title: 'What technology or trends could disrupt your business?', + title: 'What does your cash runway look like?', placeholder: 'Type your answer....', - field: 'disruptionThreats', + field: 'cashRunway', required: true, rows: 6 }, { id: 49, section: 6, - sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 7, - totalInSection: 11, + sectionName: "Financial Health & Metrics", + sectionPosition: 8, + totalInSection: 8, type: 'question', - title: 'How do you test and validate new ideas?', + title: 'What are you underpricing or undervaluing?', placeholder: 'Type your answer....', - field: 'ideaValidation', + field: 'underpricing', required: true, rows: 6 }, + + // Section 7: Innovation & Product/Service Strategy (Steps 43-53) { id: 50, - section: 6, + section: 7, sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 8, - totalInSection: 11, - type: 'question', - title: 'What would your ideal product/service portfolio look like?', - placeholder: 'Type your answer....', - field: 'idealPortfolio', - required: true, - rows: 6 + sectionPosition: 1, + totalInSection: 6, + type: 'intro', + title: 'Innovation & Product/Service Strategy', + description: 'Description about the topic and what it means.' }, { id: 51, - section: 6, + section: 7, sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 9, - totalInSection: 11, + sectionPosition: 2, + totalInSection: 6, type: 'question', - title: 'How do you balance innovation with operational stability?', + title: 'What is your most unique offering?', placeholder: 'Type your answer....', - field: 'innovationBalance', + field: 'uniqueOffering', required: true, rows: 6 }, { id: 52, - section: 6, + section: 7, sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 10, - totalInSection: 11, + sectionPosition: 3, + totalInSection: 6, type: 'question', - title: 'What partnerships could accelerate your innovation?', + title: 'What part of the product/service is outdated or stagnant?', placeholder: 'Type your answer....', - field: 'innovationPartnerships', + field: 'productStagnation', required: true, rows: 6 }, { id: 53, - section: 6, + section: 7, sectionName: "Innovation & Product/Service Strategy", - sectionPosition: 11, - totalInSection: 11, + sectionPosition: 4, + totalInSection: 6, type: 'question', - title: 'How do you measure innovation success?', + title: 'What trends are you tracking in your industry?', placeholder: 'Type your answer....', - field: 'innovationMetrics', + field: 'industryTrends', + required: true, + rows: 6 + }, + { + id: 54, + section: 7, + sectionName: "Innovation & Product/Service Strategy", + sectionPosition: 5, + totalInSection: 6, + type: 'question', + title: 'How does your company stay ahead of innovation?', + placeholder: 'Type your answer....', + field: 'innovationAhead', + required: true, + rows: 6 + }, + { + id: 55, + section: 7, + sectionName: "Innovation & Product/Service Strategy", + sectionPosition: 6, + totalInSection: 6, + type: 'question', + title: 'What new product/service do you believe could change the game for you?', + placeholder: 'Type your answer....', + field: 'industryDirection', required: true, rows: 6 }, - // Section 7: Personal Leadership & Risk (Steps 54-63) + + // Section 8: Personal Leadership & Risk { id: 54, - section: 7, + section: 8, sectionName: "Personal Leadership & Risk", sectionPosition: 1, - totalInSection: 10, + totalInSection: 8, type: 'intro', title: 'Personal Leadership & Risk', description: 'Description about the topic and what it means.' }, { id: 55, - section: 7, + section: 8, sectionName: "Personal Leadership & Risk", sectionPosition: 2, - totalInSection: 10, + totalInSection: 8, type: 'question', - title: 'What keeps you up at night about the business?', + title: 'What decisions are you avoiding right now?', placeholder: 'Type your answer....', - field: 'businessWorries', + field: 'avoidedDecisions', required: true, rows: 6 }, { id: 56, - section: 7, + section: 8, sectionName: "Personal Leadership & Risk", sectionPosition: 3, - totalInSection: 10, + totalInSection: 8, type: 'question', - title: 'What are your biggest blind spots as a leader?', + title: 'What\'s been the hardest call you\'ve had to make in the last year?', placeholder: 'Type your answer....', - field: 'leadershipBlindSpots', + field: 'hardestCall', required: true, rows: 6 }, { id: 57, - section: 7, + section: 8, sectionName: "Personal Leadership & Risk", sectionPosition: 4, - totalInSection: 10, + totalInSection: 8, type: 'question', - title: 'How do you handle stress and pressure?', + title: 'What part of the business drains your energy the most?', placeholder: 'Type your answer....', - field: 'stressManagement', + field: 'energyDrain', required: true, rows: 6 }, { id: 58, - section: 7, + section: 8, sectionName: "Personal Leadership & Risk", sectionPosition: 5, - totalInSection: 10, - type: 'question', - title: 'What decisions do you most regret or would do differently?', - placeholder: 'Type your answer....', - field: 'regretfulDecisions', - required: true, - rows: 6 - }, - { - id: 59, - section: 7, - sectionName: "Personal Leadership & Risk", - sectionPosition: 6, - totalInSection: 10, - type: 'question', - title: 'How do you continue learning and growing as a leader?', - placeholder: 'Type your answer....', - field: 'leadershipGrowth', - required: true, - rows: 6 - }, - { - id: 60, - section: 7, - sectionName: "Personal Leadership & Risk", - sectionPosition: 7, - totalInSection: 10, + totalInSection: 8, type: 'question', title: 'Where are you most stretched as a leader?', placeholder: 'Type your answer....', @@ -815,11 +815,11 @@ export const onboardingSteps: OnboardingStep[] = [ rows: 6 }, { - id: 61, - section: 7, + id: 59, + section: 8, sectionName: "Personal Leadership & Risk", - sectionPosition: 8, - totalInSection: 10, + sectionPosition: 6, + totalInSection: 8, type: 'question', title: 'If you had to take a 90-day sabbatical, what would collapse?', placeholder: 'Type your answer....', @@ -828,11 +828,11 @@ export const onboardingSteps: OnboardingStep[] = [ rows: 6 }, { - id: 62, - section: 7, + id: 60, + section: 8, sectionName: "Personal Leadership & Risk", - sectionPosition: 9, - totalInSection: 10, + sectionPosition: 7, + totalInSection: 8, type: 'question', title: 'What legacy are you trying to build through this company?', placeholder: 'Type your answer....', @@ -841,11 +841,11 @@ export const onboardingSteps: OnboardingStep[] = [ rows: 6 }, { - id: 63, - section: 7, + id: 61, + section: 8, sectionName: "Personal Leadership & Risk", - sectionPosition: 10, - totalInSection: 10, + sectionPosition: 8, + totalInSection: 8, type: 'question', title: 'What would need to happen in the next 12 months for this year to be a success?', placeholder: 'Type your answer....', diff --git a/src/pages/Chat.tsx b/src/pages/Chat.tsx index 156c44b..12ad0b5 100644 --- a/src/pages/Chat.tsx +++ b/src/pages/Chat.tsx @@ -432,7 +432,7 @@ const Chat: React.FC = () => {
setSelectedCategory(category)} - className={`px-3 py-1.5 rounded-lg shadow-[0px_1px_2px_0px_rgba(16,24,40,0.05)] shadow-[inset_0px_-2px_0px_0px_rgba(10,13,18,0.05)] shadow-[inset_0px_0px_0px_1px_rgba(10,13,18,0.18)] flex justify-center items-center gap-1 overflow-hidden cursor-pointer ${selectedCategory === category ? 'bg-white' : '' + className={`px-3 py-1.5 rounded-lg shadow-[0px_1px_2px_0px_rgba(16,24,40,0.05)] shadow-[inset_0px_-2px_0px_0px_rgba(10,13,18,0.05)] shadow-[inset_0px_0px_0px_1px_rgba(10,13,18,0.18)] flex justify-center items-center gap-1 overflow-hidden cursor-pointer ${selectedCategory === category ? 'bg-[--Neutrals-NeutralSlate50]' : '' }`} >
diff --git a/src/pages/CompanyWiki.tsx b/src/pages/CompanyWiki.tsx index 31c4ab5..4463f1f 100644 --- a/src/pages/CompanyWiki.tsx +++ b/src/pages/CompanyWiki.tsx @@ -1,94 +1,304 @@ -import React, { useEffect, useState } from 'react'; -import { useOrg } from '../contexts/OrgContext'; -import { CompanyReport } from '../types'; -import { CompanyWikiManager } from '../components/CompanyWiki'; - -const CompanyWiki: React.FC = () => { - const { org, employees, getFullCompanyReportHistory, generateCompanyWiki } = useOrg(); - const [isGenerating, setIsGenerating] = useState(false); - const [companyReport, setCompanyReport] = useState(null); - const [error, setError] = useState(null); - const [onboardingProgress, setOnboardingProgress] = useState(60); - - useEffect(() => { - (async () => { - try { - const history = await getFullCompanyReportHistory(); - if (history.length) { - setCompanyReport(history[0]); - } - } catch (e) { - console.error('Failed loading company report history', e); - } - })(); - }, [getFullCompanyReportHistory]); - - // Determine wiki state based on company data - const wikiState = companyReport ? 'completed' : 'empty'; - - // Create Q&A items from company report or org data - const qaItems = companyReport ? [ - { - question: "What is the mission of your company?", - answer: org?.mission || "To empower small businesses with AI-driven automation tools that increase efficiency and reduce operational overhead." - }, - { - question: "How has your mission evolved in the last 1–3 years?", - answer: org?.evolution || "We shifted from general SaaS tools to vertical-specific solutions, with deeper integrations and onboarding support." - }, - { - question: "What is your 5-year vision for the company?", - answer: org?.vision || "To become the leading AI operations platform for SMBs in North America, serving over 100,000 customers." - }, - { - question: "What are your company's top 3 strategic advantages?", - answer: org?.advantages || "Fast product iteration enabled by in-house AI capabilities\nDeep customer understanding from vertical specialization\nHigh customer retention due to integrated onboarding" - }, - { - question: "What are your biggest vulnerabilities or threats?", - answer: org?.vulnerabilities || "Dependence on a single marketing channel, weak middle management, and rising customer acquisition costs." - } - ] : undefined; - - // Convert employees to suggested format for invitations - const suggestedEmployees = employees?.map(emp => ({ - id: emp.id, - name: emp.name || emp.email, - email: emp.email - })) || []; - - const handleCompleteOnboarding = async () => { - setIsGenerating(true); - setError(null); - try { - const report = await generateCompanyWiki(); - setCompanyReport(report); - setOnboardingProgress(100); - } catch (e: any) { - console.error(e); - setError('Failed to generate company wiki'); - } finally { - setIsGenerating(false); - } - }; - - return ( -
- {error && ( -
- {error} -
- )} - - -
- ); -}; - +import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { secureApi } from '../services/secureApi'; +import { OnboardingData } from '../types'; + + +const CompanyWiki: React.FC = () => { + const navigate = useNavigate(); + const [onboardingData, setOnboardingData] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const [activeSection, setActiveSection] = useState(1); + const [onboardingCompleted, setOnboardingCompleted] = useState(false); + const [lastStep, setLastStep] = useState(); + + useEffect(() => { + loadOnboardingData(); + }, []); + + const loadOnboardingData = async () => { + try { + setIsLoading(true); + const response = await secureApi.getOrgData(); + + if (!response.onboardingCompleted) { + navigate(`/onboarding`); + return; + } + + if (response.onboardingData) { + setOnboardingData(response?.onboardingData); + setOnboardingCompleted(response.onboardingCompleted); + // setLastStep(response.lastStep); + } + } catch (err: any) { + console.error('Failed to load onboarding data:', err); + setError(err.message || 'Failed to load company wiki data'); + } finally { + setIsLoading(false); + } + }; + + const getSectionTitle = (section: number): string => { + const titles = { + 1: 'Company Overview & Vision', + 2: 'Leadership & Organizational Structure', + 3: 'Operations & Execution', + 4: 'Culture & Team Health', + 5: 'Sales, Marketing & Growth', + 6: 'Innovation & Product/Service Strategy', + 7: 'Personal Leadership & Risk' + }; + return titles[section as keyof typeof titles] || ''; + }; + + const getSectionQuestions = (section: number) => { + if (!onboardingData) return []; + + const sectionFields = { + 1: [ + 'companySize', + 'mission', + 'missionEvolution', + 'vision', + 'strategicAdvantages', + 'vulnerabilities', + 'scalabilityChallenges', + 'growthLimitations' + ], + 2: [ + 'leadershipStructure', + 'criticalPeople', + 'leadershipGaps', + 'delegationOpportunities', + 'leadershipDevelopment', + 'heldOntoTooLong', + 'successionConfidence' + ], + 3: [ + 'businessSystems', + 'personalDependencies', + 'operationalFriction', + 'workflowEfficiency', + 'fragileProcesses', + 'recurringProblems' + ], + 4: [ + 'cultureDescription', + 'livedValues', + 'internalFriction', + 'speakUpCulture', + 'clearExpectations', + 'staffFeedback', + 'highPerformerLove' + ], + 5: [ + 'revenuePipeline', + 'customerAcquisition', + 'customerAcquisitionCost', + 'customerLifetimeValue', + 'underutilizedChannels', + 'overspendingROI', + 'currentBottleneck' + ], + 6: [ + 'monthlyBurnOverhead', + 'currentRevenue', + 'netProfitMargin', + 'financialsUpToDate', + 'financialGrowthPlanning', + 'cashRunway', + 'underpricing' + ], + 7: [ + 'uniqueOffering', + 'productStagnation', + 'industryTrends', + 'innovationAhead', + 'industryDirection' + ], + 8: [ + 'avoidedDecisions', + 'hardestCall', + 'energyDrain', + 'leadershipStretched', + 'sabbaticalRisks', + 'companyLegacy', + 'yearSuccess' + ] + }; + + const fields = sectionFields[section as keyof typeof sectionFields] || []; + return fields.map(field => ({ + field, + question: getQuestionText(field), + answer: onboardingData[field] || 'No answer provided' + })); + }; + + const getQuestionText = (field: string): string => { + const questions = { + companySize: 'What is the size of your company?', + mission: 'What is the mission of your company?', + missionEvolution: 'How has your mission evolved in the last 1–3 years?', + vision: 'What is your company\'s vision for the future?', + strategicAdvantages: 'What does success look like for your company?', + vulnerabilities: 'What are your core company values?', + scalabilityChallenges: 'Describe your current leadership structure.', + growthLimitations: 'Who are the most critical people in the business today?', + + leadershipStructure: 'Where are leadership gaps or weak links?', + criticalPeople: 'What decisions are you still involved in that someone else should own?', + leadershipGaps: 'What systems or tools do you rely on to run the business?', + delegationOpportunities: 'Where does the business rely too much on you personally?', + leadershipDevelopment: 'Where is the most operational friction inside the company?', + heldOntoTooLong: 'How efficient is your workflow from sales to delivery?', + successionConfidence: 'How confident are you in your succession plan?', + + businessSystems: 'What systems or tools do you rely on to run the business?', + personalDependencies: 'Where does the business rely too much on you personally?', + operationalFriction: 'Where is the most operational friction inside the company?', + workflowEfficiency: 'How efficient is your workflow from sales to delivery?', + fragileProcesses: 'What processes feel fragile or inconsistent?', + recurringProblems: 'What recurring problems never seem to get solved?', + + cultureDescription: 'How would you describe your company culture in a few words?', + livedValues: 'What values are truly lived out daily by your team?', + internalFriction: 'Where is there internal friction or misalignment?', + speakUpCulture: 'Do people speak up when things are broken or wrong?', + clearExpectations: 'How do customers typically find you?', + staffFeedback: 'What is your competitive advantage?', + highPerformerLove: 'Where do you lose potential customers?', + + revenuePipeline: 'How consistent is your revenue pipeline?', + customerAcquisition: 'Where do most of your customers come from?', + customerAcquisitionCost: 'What is your customer acquisition cost (CAC)?', + customerLifetimeValue: 'What\'s your average customer lifetime value (LTV)?', + underutilizedChannels: 'What channels or strategies are underutilized?', + overspendingROI: 'Where are you overspending with low ROI?', + currentBottleneck: 'What is your current bottleneck in scaling revenue?', + + monthlyBurnOverhead: 'What is your monthly burn or overhead?', + currentRevenue: 'What is your current monthly/annual revenue?', + netProfitMargin: 'What is your current net profit margin?', + financialsUpToDate: 'Are your financials up to date and properly reported?', + financialGrowthPlanning: 'What would your team do differently if they had full financial transparency?', + cashRunway: 'What does your cash runway look like?', + underpricing: 'What are you underpricing or undervaluing?', + + uniqueOffering: 'What is your most unique offering?', + productStagnation: 'What part of the product/service is outdated or stagnant?', + industryTrends: 'What trends are you tracking in your industry?', + innovationAhead: 'How does your company stay ahead of innovation?', + industryDirection: 'What new product/service do you believe could change the game for you?', + + + avoidedDecisions: 'What decisions are you avoiding right now?', + hardestCall: 'What\'s been the hardest call you\'ve had to make in the last year?', + energyDrain: 'What part of the business drains your energy the most?', + leadershipStretched: 'Where are you most stretched as a leader?', + sabbaticalRisks: 'If you had to take a 90-day sabbatical, what would collapse?', + companyLegacy: 'What legacy are you trying to build through this company?', + yearSuccess: 'What would need to happen in the next 12 months for this year to be a success?' + }; + return questions[field as keyof typeof questions] || field; + }; + + if (isLoading) { + return ( +
+
+
+

Loading company wiki...

+
+
+ ); + } + + if (error) { + return ( +
+
+

Error: {error}

+ +
+
+ ); + } + + if (!onboardingCompleted || !onboardingData) { + return null; + } + + return ( +
+ {/* Left Sidebar - Company Navigation */} + {/* Main Content Area */} +
+
+ {/* Table of Contents Sidebar */} +
+
+
Table of contents
+
+
+ {[1, 2, 3, 4, 5, 6, 7].map((section, index) => ( +
setActiveSection(section)} + > +
+
{section}
+
+
+ {getSectionTitle(section)} +
+
+ ))} +
+
+ + {/* Questions Content */} +
+
+
+ {getSectionTitle(activeSection)} +
+
+
+ {getSectionQuestions(activeSection).map((qa, index) => ( +
+
+
+
Q
+
+ {qa.question} +
+
+
+
+
+
A
+
+ {qa.answer} +
+
+
+
+ ))} +
+
+
+
+
+ ); +}; + export default CompanyWiki; \ No newline at end of file diff --git a/src/pages/CompanyWikiNew.tsx b/src/pages/CompanyWikiNew.tsx new file mode 100644 index 0000000..44e7aa1 --- /dev/null +++ b/src/pages/CompanyWikiNew.tsx @@ -0,0 +1,263 @@ +import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { secureApi } from '../services/secureApi'; + +interface OnboardingData { + [key: string]: string; +} + +const CompanyWiki: React.FC = () => { + const navigate = useNavigate(); + const [onboardingData, setOnboardingData] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const [activeSection, setActiveSection] = useState(1); + const [onboardingCompleted, setOnboardingCompleted] = useState(false); + const [lastStep, setLastStep] = useState(); + + useEffect(() => { + loadOnboardingData(); + }, []); + + const loadOnboardingData = async () => { + try { + setIsLoading(true); + const response = await secureApi.getOnboardingQuestions(); + + if (!response.completed && response.lastStep) { + navigate(`/onboarding?step=${response.lastStep}`); + return; + } + + if (!response.completed) { + navigate('/onboarding'); + return; + } + + setOnboardingData(response.questions); + setOnboardingCompleted(response.completed); + setLastStep(response.lastStep); + } catch (err: any) { + console.error('Failed to load onboarding data:', err); + setError(err.message || 'Failed to load company wiki data'); + } finally { + setIsLoading(false); + } + }; + + const getSectionTitle = (section: number): string => { + const titles = { + 1: 'Company Overview & Vision', + 2: 'Leadership & Organizational Structure', + 3: 'Operations & Execution', + 4: 'Culture & Team Health', + 5: 'Sales, Marketing & Growth', + 6: 'Innovation & Product/Service Strategy', + 7: 'Personal Leadership & Risk' + }; + return titles[section as keyof typeof titles] || ''; + }; + + const getSectionQuestions = (section: number) => { + if (!onboardingData) return []; + + const sectionFields = { + 1: ['mission', 'missionEvolution', 'vision', 'successDefinition', 'coreValues'], + 2: ['leadershipStructure', 'criticalPeople', 'leadershipGaps', 'delegationOpportunities'], + 3: ['businessSystems', 'personalDependencies', 'operationalFriction', 'workflowEfficiency'], + 4: ['cultureDescription', 'livedValues', 'internalFriction', 'speakUpCulture'], + 5: ['customerAcquisition', 'competitiveAdvantage', 'customerLoss', 'customerLoyalty'], + 6: ['newProducts', 'innovationProcess', 'uniquePosition', 'industryDirection'], + 7: ['businessWorries', 'leadershipBlindSpots', 'stressManagement', 'regretfulDecisions'] + }; + + const fields = sectionFields[section as keyof typeof sectionFields] || []; + return fields.map(field => ({ + field, + question: getQuestionText(field), + answer: onboardingData[field] || 'No answer provided' + })); + }; + + const getQuestionText = (field: string): string => { + const questions = { + mission: 'What is the mission of your company?', + missionEvolution: 'How has your mission evolved in the last 1–3 years?', + vision: 'What is your company\'s vision for the future?', + successDefinition: 'What does success look like for your company?', + coreValues: 'What are your core company values?', + leadershipStructure: 'Describe your current leadership structure.', + criticalPeople: 'Who are the most critical people in the business today?', + leadershipGaps: 'Where are leadership gaps or weak links?', + delegationOpportunities: 'What decisions are you still involved in that someone else should own?', + businessSystems: 'What systems or tools do you rely on to run the business?', + personalDependencies: 'Where does the business rely too much on you personally?', + operationalFriction: 'Where is the most operational friction inside the company?', + workflowEfficiency: 'How efficient is your workflow from sales to delivery?', + cultureDescription: 'How would you describe your company culture in a few words?', + livedValues: 'What values are truly lived out daily by your team?', + internalFriction: 'Where is there internal friction or misalignment?', + speakUpCulture: 'Do people speak up when things are broken or wrong?', + customerAcquisition: 'How do customers typically find you?', + competitiveAdvantage: 'What is your competitive advantage?', + customerLoss: 'Where do you lose potential customers?', + customerLoyalty: 'What drives customer loyalty and retention?', + newProducts: 'What new products or services are you considering?', + innovationProcess: 'How do you stay innovative and ahead of trends?', + uniquePosition: 'What customer problems are you uniquely positioned to solve?', + industryDirection: 'Where do you see your industry heading?', + businessWorries: 'What keeps you up at night about the business?', + leadershipBlindSpots: 'What are your biggest blind spots as a leader?', + stressManagement: 'How do you handle stress and pressure?', + regretfulDecisions: 'What decisions do you most regret or would do differently?' + }; + return questions[field as keyof typeof questions] || field; + }; + + if (isLoading) { + return ( +
+
+
+

Loading company wiki...

+
+
+ ); + } + + if (error) { + return ( +
+
+

Error: {error}

+ +
+
+ ); + } + + if (!onboardingCompleted || !onboardingData) { + return null; + } + + return ( +
+
+ {/* Left Sidebar - Company Navigation */} +
+ {/* Company Header */} +
+
+
+
+
+
+
+
+
+
+ {onboardingData?.companyName || 'Company Name'} +
+
+
+
+ + {/* Navigation Items */} +
+
+
+
Company Wiki
+
+
+
Submissions
+
+
+
Reports
+
+
+
Chat
+
+
+
Help
+
+
+
+
+ + {/* Bottom Section */} +
+
+
Settings
+
+
+
+ + {/* Main Content Area */} +
+
+ {/* Table of Contents Sidebar */} +
+
+
Table of contents
+
+
+ {[1, 2, 3, 4, 5, 6, 7].map((section, index) => ( +
setActiveSection(section)} + > +
+
{section}
+
+
+ {getSectionTitle(section)} +
+
+ ))} +
+
+ + {/* Questions Content */} +
+
+
+ {getSectionTitle(activeSection)} +
+
+
+ {getSectionQuestions(activeSection).map((qa, index) => ( +
+
+
+
Q
+
+ {qa.question} +
+
+
+
+
+
A
+
+ {qa.answer} +
+
+
+
+ ))} +
+
+
+
+
+
+ ); +}; + +export default CompanyWiki; \ No newline at end of file diff --git a/src/pages/HelpNew.tsx b/src/pages/HelpNew.tsx index 6bf0768..de63e38 100644 --- a/src/pages/HelpNew.tsx +++ b/src/pages/HelpNew.tsx @@ -73,7 +73,7 @@ const HelpNew: React.FC = () => { {faqItems.map((item, index) => (
toggleFAQ(index)} @@ -105,7 +105,7 @@ const HelpNew: React.FC = () => {
))}
-
+
Still have questions?
We are available for 24/7
diff --git a/src/pages/Onboarding.tsx b/src/pages/Onboarding.tsx index 4db639b..90f3d54 100644 --- a/src/pages/Onboarding.tsx +++ b/src/pages/Onboarding.tsx @@ -13,7 +13,6 @@ import { const Onboarding: React.FC = () => { const { org, upsertOrg, generateCompanyWiki } = useOrg(); - const { user } = useAuth(); const navigate = useNavigate(); useEffect(() => { diff --git a/src/pages/Reports.tsx b/src/pages/Reports.tsx index 1464ea4..23d3b06 100644 --- a/src/pages/Reports.tsx +++ b/src/pages/Reports.tsx @@ -1,10 +1,13 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; +import { useLocation } from 'react-router-dom'; import { useOrg } from '../contexts/OrgContext'; +import { secureApiPOST, secureApi } from '../services/secureApi'; import { CompanyReport, Employee, EmployeeReport } from '../types'; import { SAMPLE_COMPANY_REPORT } from '../constants'; import RadarPerformanceChart from '../components/charts/RadarPerformanceChart'; const Reports: React.FC = () => { + const location = useLocation(); const { employees, reports, user, isOwner, getFullCompanyReportHistory, generateEmployeeReport, generateCompanyReport, orgId } = useOrg(); const [companyReport, setCompanyReport] = useState(null); const [selectedReport, setSelectedReport] = useState<{ report: CompanyReport | EmployeeReport; type: 'company' | 'employee'; employeeName?: string } | null>(null); @@ -14,6 +17,9 @@ const Reports: React.FC = () => { const currentUserIsOwner = isOwner(user?.uid || ''); + // Get selected employee ID from navigation state (from Submissions page) + const selectedEmployeeId = location.state?.selectedEmployeeId; + // Load company report on component mount useEffect(() => { const loadCompanyReport = async () => { @@ -38,6 +44,16 @@ const Reports: React.FC = () => { loadCompanyReport(); }, [currentUserIsOwner, getFullCompanyReportHistory]); + // Handle navigation from Submissions page + useEffect(() => { + if (selectedEmployeeId) { + const employee = employees.find(emp => emp.id === selectedEmployeeId); + if (employee) { + handleEmployeeSelect(employee); + } + } + }, [selectedEmployeeId, employees, handleEmployeeSelect]); + // Filter and sort employees const visibleEmployees = currentUserIsOwner ? employees.filter(emp => @@ -45,7 +61,7 @@ const Reports: React.FC = () => { ).sort((a, b) => a.name.localeCompare(b.name)) : employees.filter(emp => emp.id === user?.uid); - const handleEmployeeSelect = (employee: Employee) => { + const handleEmployeeSelect = useCallback((employee: Employee) => { const employeeReport = reports[employee.id]; if (employeeReport) { setSelectedReport({ @@ -54,7 +70,7 @@ const Reports: React.FC = () => { employeeName: employee.name }); } - }; + }, [reports]); const handleCompanyReportSelect = () => { if (companyReport) { @@ -76,237 +92,101 @@ const Reports: React.FC = () => { }; return ( -
-
- - {/* Left Sidebar - Navigation */} -
-
- {/* Company Logo */} -
-
-
-
-
-
-
-
-
Auditly Company
-
-
-
- - - -
-
- - {/* Navigation Items */} -
-
-
-
- - - -
-
Company Wiki
-
-
-
- - - -
-
Submissions
-
-
-
- - - - - - - - - - -
-
Reports
-
-
-
- - - -
-
Chat
-
-
-
- - - - - - - - - - -
-
Help
-
-
-
+
+ {/* Middle Section - Employee List */} +
+
+
+
Employees
- - {/* Bottom Section - Settings and CTA */} -
-
-
- - - - - -
-
Settings
-
- - {/* CTA Card */} -
-
-
-
-
-
Build [Company]'s Report
-
Share this form with your team members to capture valuable info about your company to train Auditly.
-
-
-
-
-
-
Invite
-
-
- - - -
-
-
-
- - - -
-
-
Copy
-
+
+ {/* Search */} +
+
+
+
+ + +
+ setSearchQuery(e.target.value)} + className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate500] text-sm font-normal font-['Inter'] leading-tight outline-none" + />
+ + {/* Employee List */} +
+ {/* Company Report Item */} + {currentUserIsOwner && ( +
+
+
+ C +
+
+
Company Report
+
+ )} + + {/* Employee Items */} + {visibleEmployees.map((employee) => ( +
handleEmployeeSelect(employee)} + > +
+
+ {employee.initials} +
+
+
+ {employee.name} +
+
+ ))} +
- {/* Middle Section - Employee List */} -
-
-
-
Employees
-
-
- {/* Search */} -
-
-
-
- - - -
- setSearchQuery(e.target.value)} - className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate500] text-sm font-normal font-['Inter'] leading-tight outline-none" - /> -
-
-
- - {/* Employee List */} -
- {/* Company Report Item */} - {currentUserIsOwner && ( -
-
-
- C -
-
-
Company Report
-
- )} - - {/* Employee Items */} - {visibleEmployees.map((employee) => ( -
handleEmployeeSelect(employee)} - > -
-
- {employee.initials} -
-
-
- {employee.name} -
-
- ))} -
-
-
- - {/* Main Content Area */} -
- {selectedReport ? ( - selectedReport.type === 'company' ? ( - - ) : ( - - ) + {/* Main Content Area */} +
+ {selectedReport ? ( + selectedReport.type === 'company' ? ( + ) : ( -
-
-

- Select a Report -

-

- Choose a company or employee report from the list to view details. -

-
+ + ) + ) : ( +
+
+

+ Select a Report +

+

+ Choose a company or employee report from the list to view details. +

- )} -
+
+ )}
@@ -319,7 +199,10 @@ const CompanyReportContent: React.FC<{ onRegenerate: () => void; isGenerating: boolean; }> = ({ report, onRegenerate, isGenerating }) => { - const [activeDepartmentTab, setActiveDepartmentTab] = useState('Campaigns'); + // Default to the first department in the array + const [activeDepartmentTab, setActiveDepartmentTab] = useState(() => + report?.gradingBreakdown?.[0]?.departmentNameShort || 'Campaigns' + ); return ( <> @@ -331,11 +214,11 @@ const CompanyReportContent: React.FC<{
- +
-
Download as PDF
+
Download as PDF
@@ -343,29 +226,29 @@ const CompanyReportContent: React.FC<{ {/* Content */}
{/* Company Weaknesses */} -
+
-
Company Weaknesses
+
Company Weaknesses
-
+
{report?.weaknesses?.map((weakness, index) => (
-
{weakness.title}:
-
{weakness.description}
+
{weakness.title}:
+
{weakness.description}
{index < (report?.weaknesses?.length || 0) - 1 && ( -
- - +
+ +
)}
)) || (
-
Lack of Structure:
-
People are confused about their roles. No one knows who's responsible.
+
Lack of Structure:
+
People are confused about their roles. No one knows who's responsible.
)}
@@ -373,16 +256,15 @@ const CompanyReportContent: React.FC<{ {/* Personnel Changes */} {report?.personnelChanges && ( -
+
-
Personnel Changes
+
Personnel Changes
-
- +
{/* New Hires */} {report.personnelChanges.newHires && report.personnelChanges.newHires.length > 0 && (
-
New Hires
+
New Hires
{report.personnelChanges.newHires.map((hire, index) => (
{hire.name} - {hire.role}
@@ -396,7 +278,7 @@ const CompanyReportContent: React.FC<{ {/* Promotions */} {report.personnelChanges.promotions && report.personnelChanges.promotions.length > 0 && (
-
Promotions
+
Promotions
{report.personnelChanges.promotions.map((promotion, index) => (
{promotion.name}
@@ -410,7 +292,7 @@ const CompanyReportContent: React.FC<{ {/* Departures */} {report.personnelChanges.departures && report.personnelChanges.departures.length > 0 && (
-
Departures
+
Departures
{report.personnelChanges.departures.map((departure, index) => (
{departure.name}
@@ -426,7 +308,7 @@ const CompanyReportContent: React.FC<{ {(!report.personnelChanges.newHires || report.personnelChanges.newHires.length === 0) && (!report.personnelChanges.promotions || report.personnelChanges.promotions.length === 0) && (!report.personnelChanges.departures || report.personnelChanges.departures.length === 0) && ( -
+
No personnel changes to report.
)} @@ -436,30 +318,43 @@ const CompanyReportContent: React.FC<{ {/* Hiring Needs */} {report?.immediateHiringNeeds && report.immediateHiringNeeds.length > 0 && ( -
+
-
Immediate Hiring Needs
+
Immediate Hiring Needs
-
+ {/*
{report.immediateHiringNeeds.map((need, index) => ( -
-
-
-
- {need.role} - {need.department} -
-
- {need.priority} Priority -
+
+
{need.role} - {need.department}
+
+
+ {need.priority} Priority
-
- {need.reasoning} -
+
+
+
+ ))} +
*/} +
+ {report.immediateHiringNeeds.map((need, index) => ( + +
+
{need.role} - {need.department}
+
{need.reasoning}
+
+ {index !== report.immediateHiringNeeds.length - 1 && ( +
+ + + +
+ )} +
))}
@@ -467,23 +362,28 @@ const CompanyReportContent: React.FC<{ {/* Forward Plan */} {report?.forwardOperatingPlan && ( -
+
-
Forward Plan
+
Forward Plan
-
+
{ report.forwardOperatingPlan.map((plan, index) => (
-
{plan.title}
-
- {plan.details.map((detail, idx) => ( -

{detail}

- ))} +
{plan.title}
+
+
    + {plan.details.map((detail, idx) => ( +
  • + + {detail} +
  • + ))} +
-
+ {index !== report.forwardOperatingPlan.length - 1 &&
}
)) } @@ -495,22 +395,22 @@ const CompanyReportContent: React.FC<{ Strengths goes here */} {report?.strengths && ( -
+
-
Strengths
+
Strengths
-
+
{report.strengths.map((strength, idx) => (
-
+
- +
-
{strength}
+
{strength}
))}
@@ -521,23 +421,22 @@ const CompanyReportContent: React.FC<{ Organizational Impact Summary */} {report?.organizationalImpactSummary && ( -
+
-
Organizational Impact Summary
+
Organizational Impact Summary
-
- +
{/* Mission Critical */}
-
Mission Critical
+
Mission Critical
{report.organizationalImpactSummary.missionCritical.map((employee, index) => (
-
{employee.employeeName}
-
{employee.description}
+
{employee.employeeName}
+
{employee.description}
))}
@@ -547,13 +446,13 @@ const CompanyReportContent: React.FC<{
-
Highly Valuable
+
Highly Valuable
{report.organizationalImpactSummary.highlyValuable.map((employee, index) => (
-
{employee.employeeName}
-
{employee.description}
+
{employee.employeeName}
+
{employee.description}
))}
@@ -563,13 +462,13 @@ const CompanyReportContent: React.FC<{
-
Core Support
+
Core Support
{report.organizationalImpactSummary.coreSupport.map((employee, index) => (
-
{employee.employeeName}
-
{employee.description}
+
{employee.employeeName}
+
{employee.description}
))}
@@ -579,13 +478,13 @@ const CompanyReportContent: React.FC<{
-
Low Criticality
+
Low Criticality
{report.organizationalImpactSummary.lowCriticality.map((employee, index) => (
-
{employee.employeeName}
-
{employee.description}
+
{employee.employeeName}
+
{employee.description}
))}
@@ -595,110 +494,110 @@ const CompanyReportContent: React.FC<{ )} {/* Grading Overview */} -
+
-
Grading Overview
+
Grading Overview
-
+
{/* Department Tabs */} - {['Campaigns', 'Social Media', 'Creative', 'Tech', 'Admin/OPS'].map((dept) => ( + {report?.gradingBreakdown?.map(dept => (
setActiveDepartmentTab(dept)} + onClick={() => setActiveDepartmentTab(dept.departmentNameShort)} >
-
- {dept} + {dept.departmentNameShort}
))}
-
- {/* Department Overview Section */} -
-
-
Department Overview
-
-
Overall Grade
-
-
A
+ {/* Content for the currently selected department */} + {(() => { + const currentDepartment = report?.gradingBreakdown?.find(dept => dept.departmentNameShort === activeDepartmentTab); + if (!currentDepartment) return null; + + return ( +
+ {/* Department Overview Section */} +
+
+
Department Overview
+
+
Overall Grade
+
+
A
+
+
+
+
+ + + +
+
+ Overall company performance shows strong collaboration and delivery with opportunities for process improvement.
-
-
- - - -
-
- Overall company performance shows strong collaboration and delivery with opportunities for process improvement. -
-
- {/* Employee Radar Charts Section */} -
-
Team Performance Analysis
-
- {report?.gradingBreakdown?.teamScores - ?.filter(teamScore => { - // Filter employees based on active department tab - // For now, showing all employees as we don't have department info per employee - // In a real implementation, you'd filter by employee department - return true; - }) - ?.map((teamScore, index) => { - const radarData = [ - { label: 'Reliability', value: teamScore.reliability * 10 }, - { label: 'Role Fit', value: teamScore.roleFit * 10 }, - { label: 'Scalability', value: teamScore.scalability * 10 }, - { label: 'Output', value: teamScore.output * 10 }, - { label: 'Initiative', value: teamScore.initiative * 10 } - ]; + {/* Employee Radar Charts Section */} +
+
Team Performance Analysis
+
+ {currentDepartment.teamScores?.map((teamScore, index) => { + const radarData = [ + { label: 'Reliability', value: teamScore.reliability * 10 }, + { label: 'Role Fit', value: teamScore.roleFit * 10 }, + { label: 'Scalability', value: teamScore.scalability * 10 }, + { label: 'Output', value: teamScore.output * 10 }, + { label: 'Initiative', value: teamScore.initiative * 10 } + ]; - return ( -
-
-

{teamScore.employeeName}

-
+
+

{teamScore.employeeName}

+
- Grade: {teamScore.grade} + }`}> + Grade: {teamScore.grade} +
+
+
+
-
- -
-
- ); - }) - } + ); + })} +
+
-
-
+ ); + })()}
{/* Company Strengths */} {/* {report?.organizationalStrengths && ( -
+
Company Strengths
@@ -721,7 +620,7 @@ const CompanyReportContent: React.FC<{
)} */} -
+
); }; @@ -753,7 +652,7 @@ const EmployeeReportContent: React.FC<{ {/* Content */}
{/* Role & Responsibilities */} -
+
Role & Responsibilities
@@ -766,7 +665,7 @@ const EmployeeReportContent: React.FC<{ {/* Self-Rated Output */} {report.roleAndOutput?.selfRatedOutput && ( -
+
Self-Rated Output
@@ -780,7 +679,7 @@ const EmployeeReportContent: React.FC<{ {/* Insights */} {report.insights && ( -
+
Insights & Traits
@@ -815,7 +714,7 @@ const EmployeeReportContent: React.FC<{ {/* Strengths */} {report.strengths && report.strengths.length > 0 && ( -
+
Strengths
@@ -839,7 +738,7 @@ const EmployeeReportContent: React.FC<{ {/* Recommendations */} {report.recommendations && report.recommendations.length > 0 && ( -
+
Recommendations
diff --git a/src/pages/SettingsNew.tsx b/src/pages/SettingsNew.tsx index 4259806..3d9fda3 100644 --- a/src/pages/SettingsNew.tsx +++ b/src/pages/SettingsNew.tsx @@ -72,7 +72,7 @@ const SettingsNew: React.FC = () => { General Settings
{activeTab === 'general' && ( -
+
)}
{ Plan & Billings
{activeTab === 'billing' && ( -
+
)}
-
+
{/* General Settings Content */} diff --git a/src/pages/Submissions.tsx b/src/pages/Submissions.tsx new file mode 100644 index 0000000..3ce5cb5 --- /dev/null +++ b/src/pages/Submissions.tsx @@ -0,0 +1,326 @@ +import React, { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useOrg } from '../contexts/OrgContext'; +import { useAuth } from '../contexts/AuthContext'; +import { secureApiPOST, secureApi } from '../services/secureApi'; +import { Employee } from '../types'; +import { EMPLOYEE_QUESTIONS } from '../employeeQuestions'; + +interface EmployeeSubmission { + employeeId: string; + answers: Record; + submittedAt: number; + employee?: Employee; +} + +const Submissions: React.FC = () => { + const navigate = useNavigate(); + const { employees, user, isOwner, orgId } = useOrg(); + const [submissions, setSubmissions] = useState>({}); + const [selectedEmployee, setSelectedEmployee] = useState(null); + const [searchQuery, setSearchQuery] = useState(''); + const [loading, setLoading] = useState(true); + + const currentUserIsOwner = isOwner(user?.uid || ''); + + // Load submissions on component mount + useEffect(() => { + const loadSubmissions = async () => { + try { + setLoading(true); + // Use the secure API service to get submissions + // const data = await secureApi.getSubmissions(); + const data = { submissions: [] }; // temp fix + + if (data) { + setSubmissions(data.submissions); + + // Auto-select first employee with submission + const employeesWithSubmissions = employees.filter(emp => data.submissions?.[emp.id]); + if (employeesWithSubmissions.length > 0) { + setSelectedEmployee(employeesWithSubmissions[0]); + } + } else { + console.error('Failed to load submissions:', response.statusText); + } + } catch (error) { + console.error('Error loading submissions:', error); + // Load demo data for development + loadDemoSubmissions(); + } finally { + setLoading(false); + } + }; + + loadSubmissions(); + }, [employees]); + + const loadDemoSubmissions = () => { + // Demo submission data for testing + const demoSubmissions: Record = {}; + + employees.forEach((employee, index) => { + if (index < 3) { // Only add submissions for first 3 employees + demoSubmissions[employee.id] = { + employeeId: employee.id, + employee, + submittedAt: Date.now() - (index * 86400000), // Stagger dates + answers: { + full_name: employee.name, + email: employee.email, + title_department: employee.role || 'Team Member', + mission: 'To empower small businesses with AI-driven automation tools that increase efficiency and reduce operational overhead.', + mission_evolution: 'We shifted from general SaaS tools to vertical-specific solutions, with deeper integrations and onboarding support.', + vision: 'To become the leading AI operations platform for SMBs in North America, serving over 100,000 customers.', + advantages: 'Fast product iteration enabled by in-house AI capabilities\nDeep customer understanding from vertical specialization\nHigh customer retention due to integrated onboarding', + vulnerabilities: 'Dependence on a single marketing channel, weak middle management, and rising customer acquisition costs.', + role_clarity: 'I understand my role clearly and feel aligned with company objectives.', + performance_output: 'I consistently deliver high-quality work and meet deadlines.', + collaboration: 'I work well with my team and communicate effectively.', + additional_feedback: 'I would appreciate more structured processes and clearer communication channels.' + } + }; + } + }); + + setSubmissions(demoSubmissions); + const employeesWithSubmissions = employees.filter(emp => demoSubmissions[emp.id]); + if (employeesWithSubmissions.length > 0) { + setSelectedEmployee(employeesWithSubmissions[0]); + } + }; + + // Filter employees: show only those with submissions, and apply search + const visibleEmployees = employees + .filter(emp => submissions[emp.id]) // Only employees with submissions + .filter(emp => emp.name.toLowerCase().includes(searchQuery.toLowerCase())) + .sort((a, b) => a.name.localeCompare(b.name)); + + const handleEmployeeSelect = (employee: Employee) => { + setSelectedEmployee(employee); + }; + + const handleViewReport = () => { + if (selectedEmployee) { + // Navigate to reports page with the selected employee + navigate('/reports', { state: { selectedEmployeeId: selectedEmployee.id } }); + } + }; + + const handleChatWithAI = () => { + if (selectedEmployee) { + // Navigate to chat page with employee context + navigate('/chat', { state: { employeeContext: selectedEmployee } }); + } + }; + + // Get questions and answers for selected employee + const getEmployeeQuestionsAndAnswers = () => { + if (!selectedEmployee || !submissions[selectedEmployee.id]) { + return []; + } + + const submission = submissions[selectedEmployee.id]; + const questionsAndAnswers: Array<{ question: string; answer: string; isLong?: boolean }> = []; + + // Map EMPLOYEE_QUESTIONS to actual answers + EMPLOYEE_QUESTIONS.forEach(q => { + const answer = submission.answers[q.id]; + if (answer && answer.trim()) { + questionsAndAnswers.push({ + question: q.prompt, + answer: answer, + isLong: answer.length > 150 // Mark long answers for different styling + }); + } + }); + + return questionsAndAnswers; + }; + + if (loading) { + return ( +
+
+

+ Loading Submissions... +

+
+
+ ); + } + + return ( +
+ {/* Middle Section - Employee List */} +
+
+
+
Employees
+
+
+ {/* Search */} +
+
+
+
+ + + +
+ setSearchQuery(e.target.value)} + className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate500] text-sm font-normal font-['Inter'] leading-tight outline-none" + /> +
+
+
+ + {/* Employee List */} +
+ {visibleEmployees.length === 0 ? ( +
+ {searchQuery ? 'No employees found matching your search.' : 'No employee submissions found.'} +
+ ) : ( + visibleEmployees.map((employee) => ( +
handleEmployeeSelect(employee)} + > +
+
+ {employee.initials} +
+
+
+ {employee.name} +
+
+ )) + )} +
+
+
+ + {/* Main Content Area */} +
+ {selectedEmployee ? ( + + ) : ( +
+
+

+ Select an Employee +

+

+ Choose an employee from the list to view their submission answers. +

+
+
+ )} +
+
+
+ ); +}; + +// Component for displaying submission content +const SubmissionContent: React.FC<{ + employee: Employee; + submission: EmployeeSubmission; + onViewReport: () => void; + onChatWithAI: () => void; + questionsAndAnswers: Array<{ question: string; answer: string; isLong?: boolean }>; +}> = ({ employee, submission, onViewReport, onChatWithAI, questionsAndAnswers }) => { + return ( + <> + {/* Header */} +
+
+ {employee.name}'s Answers +
+
+ + +
+
+ + {/* Content */} +
+ {questionsAndAnswers.length === 0 ? ( +
+

No submission data available for this employee.

+
+ ) : ( + questionsAndAnswers.map((qa, index) => ( +
+
+
+
Q
+
{qa.question}
+
+
+
+
+
A
+
+ {qa.answer} +
+
+
+
+ )) + )} +
+ + ); +}; + +export default Submissions; \ No newline at end of file diff --git a/src/pages/figma/ChatAIResponse.tsx b/src/pages/figma/ChatAIResponse.tsx index 5b3b73d..7ef45ae 100644 --- a/src/pages/figma/ChatAIResponse.tsx +++ b/src/pages/figma/ChatAIResponse.tsx @@ -153,9 +153,9 @@ const ChatAIResponse: React.FC = () => {
{/* User Question */} -
+
What are the main characteristics?
-
+
@@ -182,7 +182,7 @@ const ChatAIResponse: React.FC = () => {
{/* Chat Input */} -
+
Ask anything, use @ to tag staff and ask questions.
@@ -204,7 +204,7 @@ const ChatAIResponse: React.FC = () => {
-
+
diff --git a/src/pages/figma/ChatLight.tsx b/src/pages/figma/ChatLight.tsx index f1f370a..43cae93 100644 --- a/src/pages/figma/ChatLight.tsx +++ b/src/pages/figma/ChatLight.tsx @@ -172,7 +172,7 @@ const ChatLight: React.FC = () => {
-
+
@@ -182,7 +182,7 @@ const ChatLight: React.FC = () => {
How can the company serve them better?
-
+
@@ -192,7 +192,7 @@ const ChatLight: React.FC = () => {
How can the company serve them better?
-
+
@@ -202,7 +202,7 @@ const ChatLight: React.FC = () => {
How can the company serve them better?
-
+
@@ -215,7 +215,7 @@ const ChatLight: React.FC = () => {
-
+
Ask anything, use @ to tag staff and ask questions.
@@ -237,7 +237,7 @@ const ChatLight: React.FC = () => {
-
+
diff --git a/src/services/secureApi.ts b/src/services/secureApi.ts index fe266ed..f20bfba 100644 --- a/src/services/secureApi.ts +++ b/src/services/secureApi.ts @@ -13,6 +13,11 @@ interface ApiResponse { message?: string; } +interface GetOrgData { + org: Organization; + success: boolean; +} + interface OrgData { id: string; name: string; @@ -134,8 +139,8 @@ class SecureApiService { } // Organization Data Methods - async getOrgData(): Promise { - const response = await this.makeRequest<{ org: OrgData }>( + async getOrgData(): Promise { + const response = await this.makeRequest<{ org: Organization }>( 'getOrgData', 'GET', null, true ); return response.org; @@ -333,6 +338,10 @@ class SecureApiService { async completeOnboarding(onboardingData: any): Promise<{ success: boolean; error?: string }> { return this.makeRequest('onboarding/complete', 'POST', onboardingData); } + + async getOnboardingQuestions(): Promise<{ questions: any; completed: boolean; lastStep?: number }> { + return this.makeRequest('getOrgData', 'GET'); + } } // Export a singleton instance diff --git a/src/types.ts b/src/types.ts index c4a7791..b6ea623 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,14 +29,16 @@ export interface OnboardingData { yourName: string; companyLogo: string; companyName: string; - companySize: string; + + companySize: number; mission: string; missionEvolution: string; vision: string; - successDefinition: string; - coreValues: string; - industryReputation: string; + strategicAdvantages: string; + vulnerabilities: string; + scalabilityChallenges: string; growthLimitations: string; + leadershipStructure: string; criticalPeople: string; leadershipGaps: string; @@ -44,12 +46,14 @@ export interface OnboardingData { leadershipDevelopment: string; heldOntoTooLong: string; successionConfidence: string; + businessSystems: string; personalDependencies: string; operationalFriction: string; workflowEfficiency: string; + fragileProcesses: string; recurringProblems: string; - wouldFixFirst: string; + cultureDescription: string; livedValues: string; internalFriction: string; @@ -57,33 +61,36 @@ export interface OnboardingData { clearExpectations: string; staffFeedback: string; highPerformerLove: string; + + revenuePipeline: string; customerAcquisition: string; - competitiveAdvantage: string; - customerLoss: string; - customerLoyalty: string; - marketingROI: string; - overspending: string; - growthAccelerator: string; - untappedOpportunities: string; - newProducts: string; - innovationProcess: string; - uniquePosition: string; + customerAcquisitionCost: string; + customerLifetimeValue: string; + underutilizedChannels: string; + overspendingROI: string; + currentBottleneck: string; + + monthlyBurnOverhead: string; + currentRevenue: string; + netProfitMargin: string; + financialsUpToDate: string; + financialGrowthPlanning: string; + cashRunway: string; + underpricing: string; + + uniqueOffering: string; + productStagnation: string; + industryTrends: string; + innovationAhead: string; industryDirection: string; - disruptionThreats: string; - ideaValidation: string; - idealPortfolio: string; - innovationBalance: string; - innovationPartnerships: string; - innovationMetrics: string; - businessWorries: string; - leadershipBlindSpots: string; - stressManagement: string; - regretfulDecisions: string; - leadershipGrowth: string; + + avoidedDecisions: string; + hardestCall: string; + energyDrain: string; leadershipStretched: string; sabbaticalRisks: string; companyLegacy: string; - yearSuccess: string; + yearSuccess: number; } export interface Organization { @@ -276,7 +283,7 @@ export interface CompanyReport { output: number; initiative: number; }[]; - } + }[]; // gradingBreakdown: { // departmentName: string; // lead: string;