587 lines
48 KiB
TypeScript
587 lines
48 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { useOrg } from '../contexts/OrgContext';
|
|
import { CompanyReport, Employee, Report } from '../types';
|
|
import { SAMPLE_COMPANY_REPORT } from '../constants';
|
|
|
|
const Reports: React.FC = () => {
|
|
const { employees, reports, user, isOwner, getFullCompanyReportHistory, generateEmployeeReport, generateCompanyReport, orgId } = useOrg();
|
|
const [companyReport, setCompanyReport] = useState<CompanyReport | null>(null);
|
|
const [selectedReport, setSelectedReport] = useState<{ report: CompanyReport | Report; type: 'company' | 'employee'; employeeName?: string } | null>(null);
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const [generatingReports, setGeneratingReports] = useState<Set<string>>(new Set());
|
|
const [generatingCompanyReport, setGeneratingCompanyReport] = useState(false);
|
|
|
|
const currentUserIsOwner = isOwner(user?.uid || '');
|
|
|
|
// Load company report on component mount
|
|
useEffect(() => {
|
|
const loadCompanyReport = async () => {
|
|
if (currentUserIsOwner) {
|
|
try {
|
|
const history = await getFullCompanyReportHistory();
|
|
if (history.length > 0) {
|
|
setCompanyReport(history[0]);
|
|
// Auto-select company report by default
|
|
setSelectedReport({ report: history[0], type: 'company' });
|
|
} else {
|
|
setCompanyReport(SAMPLE_COMPANY_REPORT);
|
|
setSelectedReport({ report: SAMPLE_COMPANY_REPORT, type: 'company' });
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load company report:', error);
|
|
setCompanyReport(SAMPLE_COMPANY_REPORT);
|
|
setSelectedReport({ report: SAMPLE_COMPANY_REPORT, type: 'company' });
|
|
}
|
|
}
|
|
};
|
|
loadCompanyReport();
|
|
}, [currentUserIsOwner, getFullCompanyReportHistory]);
|
|
|
|
// Filter and sort employees
|
|
const visibleEmployees = currentUserIsOwner
|
|
? employees.filter(emp =>
|
|
emp.name.toLowerCase().includes(searchQuery.toLowerCase())
|
|
).sort((a, b) => a.name.localeCompare(b.name))
|
|
: employees.filter(emp => emp.id === user?.uid);
|
|
|
|
const handleEmployeeSelect = (employee: Employee) => {
|
|
const employeeReport = reports[employee.id];
|
|
if (employeeReport) {
|
|
setSelectedReport({
|
|
report: employeeReport,
|
|
type: 'employee',
|
|
employeeName: employee.name
|
|
});
|
|
}
|
|
};
|
|
|
|
const handleCompanyReportSelect = () => {
|
|
if (companyReport) {
|
|
setSelectedReport({ report: companyReport, type: 'company' });
|
|
}
|
|
};
|
|
|
|
const handleGenerateCompanyReport = async () => {
|
|
setGeneratingCompanyReport(true);
|
|
try {
|
|
const newReport = await generateCompanyReport();
|
|
setCompanyReport(newReport);
|
|
setSelectedReport({ report: newReport, type: 'company' });
|
|
} catch (error) {
|
|
console.error('Error generating company report:', error);
|
|
} finally {
|
|
setGeneratingCompanyReport(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="w-[1440px] h-[4558px] p-4 bg-Neutrals-NeutralSlate200 inline-flex justify-start items-start overflow-hidden">
|
|
<div className="flex-1 self-stretch rounded-3xl shadow-[0px_0px_15px_0px_rgba(0,0,0,0.08)] flex justify-between items-start overflow-hidden">
|
|
|
|
{/* Left Sidebar - Navigation */}
|
|
<div className="w-64 self-stretch max-w-64 min-w-64 px-3 pt-4 pb-3 bg-Neutrals-NeutralSlate0 border-r border-Neutrals-NeutralSlate200 inline-flex flex-col justify-between items-center overflow-hidden">
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-5">
|
|
{/* Company Logo */}
|
|
<div className="w-60 pl-2 pr-4 py-2 bg-Neutrals-NeutralSlate0 rounded-3xl outline outline-1 outline-offset-[-1px] outline-Neutrals-NeutralSlate200 inline-flex justify-between items-center overflow-hidden">
|
|
<div className="flex-1 flex justify-start items-center gap-2">
|
|
<div className="w-8 h-8 rounded-full flex justify-start items-center gap-2.5">
|
|
<div className="w-8 h-8 relative bg-Brand-Orange rounded-full outline outline-[1.60px] outline-offset-[-1.60px] outline-white/10 overflow-hidden">
|
|
<div className="w-8 h-8 left-0 top-0 absolute bg-gradient-to-b from-white/0 to-white/10" />
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 inline-flex flex-col justify-start items-start gap-0.5">
|
|
<div className="self-stretch justify-start text-Neutrals-NeutralSlate950 text-base font-medium font-['Inter'] leading-normal">Auditly Company</div>
|
|
</div>
|
|
</div>
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M5.83333 12.5007L9.99999 16.6673L14.1667 12.5007M5.83333 7.50065L9.99999 3.33398L14.1667 7.50065" stroke="var(--Neutrals-NeutralSlate400, #A4A7AE)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Navigation Items */}
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-5">
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-1.5">
|
|
<div className="w-60 px-4 py-2.5 rounded-[34px] inline-flex justify-start items-center gap-2">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M7.5 17.4996V11.333C7.5 10.8662 7.5 10.6329 7.59083 10.4546C7.67072 10.2978 7.79821 10.1703 7.95501 10.0904C8.13327 9.99962 8.36662 9.99962 8.83333 9.99962H11.1667C11.6334 9.99962 11.8667 9.99962 12.045 10.0904C12.2018 10.1703 12.3293 10.2978 12.4092 10.4546C12.5 10.6329 12.5 10.8662 12.5 11.333V17.4996M9.18141 2.30297L3.52949 6.6989C3.15168 6.99275 2.96278 7.13968 2.82669 7.32368C2.70614 7.48667 2.61633 7.67029 2.56169 7.86551C2.5 8.0859 2.5 8.32521 2.5 8.80384V14.833C2.5 15.7664 2.5 16.2331 2.68166 16.5896C2.84144 16.9032 3.09641 17.1582 3.41002 17.318C3.76654 17.4996 4.23325 17.4996 5.16667 17.4996H14.8333C15.7668 17.4996 16.2335 17.4996 16.59 17.318C16.9036 17.1582 17.1586 16.9032 17.3183 16.5896C17.5 16.2331 17.5 15.7664 17.5 14.833V8.80384C17.5 8.32521 17.5 8.0859 17.4383 7.86551C17.3837 7.67029 17.2939 7.48667 17.1733 7.32368C17.0372 7.13968 16.8483 6.99275 16.4705 6.69891L10.8186 2.30297C10.5258 2.07526 10.3794 1.9614 10.2178 1.91763C10.0752 1.87902 9.92484 1.87902 9.78221 1.91763C9.62057 1.9614 9.47418 2.07526 9.18141 2.30297Z" stroke="var(--Neutrals-NeutralSlate400, #A4A7AE)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<div className="justify-start text-Neutrals-NeutralSlate500 text-sm font-medium font-['Inter'] leading-tight">Company Wiki</div>
|
|
</div>
|
|
<div className="w-60 px-4 py-2.5 rounded-[34px] inline-flex justify-start items-center gap-2">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M11.6667 9.16602H6.66667M8.33333 12.4993H6.66667M13.3333 5.83268H6.66667M16.6667 5.66602V14.3327C16.6667 15.7328 16.6667 16.4329 16.3942 16.9677C16.1545 17.4381 15.772 17.8205 15.3016 18.0602C14.7669 18.3327 14.0668 18.3327 12.6667 18.3327H7.33333C5.9332 18.3327 5.23314 18.3327 4.69836 18.0602C4.22795 17.8205 3.8455 17.4381 3.60582 16.9677C3.33333 16.4329 3.33333 15.7328 3.33333 14.3327V5.66602C3.33333 4.26588 3.33333 3.56582 3.60582 3.03104C3.8455 2.56063 4.22795 2.17818 4.69836 1.9385C5.23314 1.66602 5.9332 1.66602 7.33333 1.66602H12.6667C14.0668 1.66602 14.7669 1.66602 15.3016 1.9385C15.772 2.17818 16.1545 2.56063 16.3942 3.03104C16.6667 3.56582 16.6667 4.26588 16.6667 5.66602Z" stroke="var(--Neutrals-NeutralSlate400, #A4A7AE)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<div className="justify-start text-Neutrals-NeutralSlate500 text-sm font-medium font-['Inter'] leading-tight">Submissions</div>
|
|
</div>
|
|
<div className="w-60 px-4 py-2.5 bg-Neutrals-NeutralSlate100 rounded-[34px] inline-flex justify-start items-center gap-2">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<g clipPath="url(#clip0_1042_5096)">
|
|
<path d="M10 1.66602C11.0943 1.66602 12.178 1.88156 13.189 2.30035C14.2001 2.71914 15.1187 3.33297 15.8926 4.10679C16.6664 4.88062 17.2802 5.79928 17.699 6.81032C18.1178 7.82137 18.3333 8.90501 18.3333 9.99935M10 1.66602V9.99935M10 1.66602C5.39763 1.66602 1.66667 5.39698 1.66667 9.99935C1.66667 14.6017 5.39763 18.3327 10 18.3327C14.6024 18.3327 18.3333 14.6017 18.3333 9.99935M10 1.66602C14.6024 1.66602 18.3333 5.39698 18.3333 9.99935M18.3333 9.99935L10 9.99935M18.3333 9.99935C18.3333 11.3144 18.0221 12.6109 17.4251 13.7826C16.828 14.9544 15.9621 15.9682 14.8982 16.7412L10 9.99935" stroke="var(--Brand-Orange, #3399FF)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</g>
|
|
<defs>
|
|
<clipPath id="clip0_1042_5096">
|
|
<rect width="20" height="20" fill="white" />
|
|
</clipPath>
|
|
</defs>
|
|
</svg>
|
|
</div>
|
|
<div className="justify-start text-Neutrals-NeutralSlate950 text-sm font-medium font-['Inter'] leading-tight">Reports</div>
|
|
</div>
|
|
<div className="w-60 px-4 py-2.5 rounded-[34px] inline-flex justify-start items-center gap-2">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M17.4997 9.58333C17.4997 13.4953 14.3284 16.6667 10.4164 16.6667C9.51904 16.6667 8.66069 16.4998 7.87065 16.1954C7.7262 16.1398 7.65398 16.112 7.59655 16.0987C7.54006 16.0857 7.49917 16.0803 7.44124 16.0781C7.38234 16.0758 7.31772 16.0825 7.18849 16.0958L2.92097 16.537C2.5141 16.579 2.31067 16.6001 2.19067 16.5269C2.08614 16.4631 2.01495 16.3566 1.996 16.2356C1.97425 16.0968 2.07146 15.9168 2.26588 15.557L3.62893 13.034C3.74118 12.8262 3.79731 12.7223 3.82273 12.6225C3.84784 12.5238 3.85391 12.4527 3.84588 12.3512C3.83775 12.2484 3.79266 12.1147 3.7025 11.8472C3.46289 11.1363 3.33302 10.375 3.33302 9.58333C3.33302 5.67132 6.50434 2.5 10.4164 2.5C14.3284 2.5 17.4997 5.67132 17.4997 9.58333Z" stroke="var(--Neutrals-NeutralSlate400, #A4A7AE)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<div className="justify-start text-Neutrals-NeutralSlate500 text-sm font-medium font-['Inter'] leading-tight">Chat</div>
|
|
</div>
|
|
<div className="w-60 px-4 py-2.5 rounded-[34px] inline-flex justify-start items-center gap-2">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<g clipPath="url(#clip0_1042_5104)">
|
|
<path d="M7.575 7.49935C7.77092 6.94241 8.15763 6.47277 8.66663 6.17363C9.17563 5.87448 9.77408 5.76513 10.356 5.86494C10.9379 5.96475 11.4657 6.26729 11.8459 6.71896C12.2261 7.17063 12.4342 7.74228 12.4333 8.33268C12.4333 9.99935 9.93333 10.8327 9.93333 10.8327M10 14.166H10.0083M18.3333 9.99935C18.3333 14.6017 14.6024 18.3327 10 18.3327C5.39763 18.3327 1.66667 14.6017 1.66667 9.99935C1.66667 5.39698 5.39763 1.66602 10 1.66602C14.6024 1.66602 18.3333 5.39698 18.3333 9.99935Z" stroke="var(--Neutrals-NeutralSlate400, #A4A7AE)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</g>
|
|
<defs>
|
|
<clipPath id="clip0_1042_5104">
|
|
<rect width="20" height="20" fill="white" />
|
|
</clipPath>
|
|
</defs>
|
|
</svg>
|
|
</div>
|
|
<div className="justify-start text-Neutrals-NeutralSlate500 text-sm font-medium font-['Inter'] leading-tight">Help</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Bottom Section - Settings and CTA */}
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-3">
|
|
<div className="w-60 px-4 py-2.5 rounded-[34px] inline-flex justify-start items-center gap-2">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<g clipPath="url(#clip0_1042_5109)">
|
|
<path d="M10 12.5013C11.3807 12.5013 12.5 11.382 12.5 10.0013C12.5 8.62059 11.3807 7.5013 10 7.5013C8.61929 7.5013 7.5 8.62059 7.5 10.0013C7.5 11.382 8.61929 12.5013 10 12.5013Z" stroke="var(--Neutrals-NeutralSlate400, #A4A7AE)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
<div className="flex-1 justify-start text-Neutrals-NeutralSlate500 text-sm font-medium font-['Inter'] leading-tight">Settings</div>
|
|
</div>
|
|
|
|
{/* CTA Card */}
|
|
<div className="self-stretch bg-Neutrals-NeutralSlate0 rounded-[20px] shadow-[0px_1px_4px_0px_rgba(14,18,27,0.04)] outline outline-1 outline-offset-[-1px] outline-Neutrals-NeutralSlate200 flex flex-col justify-start items-start overflow-hidden">
|
|
<div className="self-stretch h-24 relative">
|
|
<div className="w-60 h-32 left-0 top-[-0.50px] absolute bg-gradient-to-b from-black to-black/0" />
|
|
</div>
|
|
<div className="self-stretch p-3 flex flex-col justify-start items-start gap-1">
|
|
<div className="self-stretch justify-start text-Neutrals-NeutralSlate800 text-sm font-semibold font-['Inter'] leading-tight">Build [Company]'s Report</div>
|
|
<div className="self-stretch justify-start text-Neutrals-NeutralSlate500 text-xs font-normal font-['Inter'] leading-none">Share this form with your team members to capture valuable info about your company to train Auditly.</div>
|
|
</div>
|
|
<div className="self-stretch px-3 pb-3 flex flex-col justify-start items-start gap-8">
|
|
<div className="self-stretch inline-flex justify-start items-start gap-2">
|
|
<div className="flex-1 px-3 py-1.5 bg-Button-Secondary rounded-[999px] flex justify-center items-center gap-0.5 overflow-hidden">
|
|
<div className="px-1 flex justify-center items-center">
|
|
<div className="justify-center text-Neutrals-NeutralSlate950 text-sm font-medium font-['Inter'] leading-tight">Invite</div>
|
|
</div>
|
|
<div className="relative">
|
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M8 3.33203V12.6654M3.33334 7.9987H12.6667" stroke="var(--Neutrals-NeutralSlate950, #0A0D12)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 px-3 py-1.5 bg-Brand-Orange rounded-[999px] outline outline-1 outline-offset-[-1px] outline-blue-400 flex justify-center items-center gap-0.5 overflow-hidden">
|
|
<div className="relative">
|
|
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M8.97171 12.2442L8.0289 13.1871C6.72716 14.4888 4.61661 14.4888 3.31486 13.1871C2.01311 11.8853 2.01311 9.77476 3.31486 8.47301L4.25767 7.5302M12.7429 8.47301L13.6858 7.5302C14.9875 6.22845 14.9875 4.1179 13.6858 2.81615C12.384 1.51441 10.2735 1.51441 8.97171 2.81615L8.0289 3.75896M6.16697 10.3349L10.8336 5.66826" stroke="var(--Other-White, white)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<div className="px-1 flex justify-center items-center">
|
|
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Copy</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Middle Section - Employee List */}
|
|
<div className="flex-1 self-stretch bg-Neutrals-NeutralSlate0 flex justify-start items-center">
|
|
<div className="flex-1 self-stretch max-w-64 min-w-64 border-r border-Outline-Outline-Gray-200 inline-flex flex-col justify-start items-start">
|
|
<div className="self-stretch p-5 inline-flex justify-start items-center gap-2.5">
|
|
<div className="flex-1 justify-start text-Neutrals-NeutralSlate950 text-base font-medium font-['Inter'] leading-normal">Employees</div>
|
|
</div>
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-2">
|
|
{/* Search */}
|
|
<div className="self-stretch px-2.5 flex flex-col justify-start items-start gap-2">
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-1">
|
|
<div className="self-stretch px-4 py-3 bg-Neutrals-NeutralSlate100 rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
|
|
<div className="relative">
|
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M17.5 17.5L14.5834 14.5833M16.6667 9.58333C16.6667 13.4954 13.4954 16.6667 9.58333 16.6667C5.67132 16.6667 2.5 13.4954 2.5 9.58333C2.5 5.67132 5.67132 2.5 9.58333 2.5C13.4954 2.5 16.6667 5.67132 16.6667 9.58333Z" stroke="var(--Neutrals-NeutralSlate500, #717680)" strokeWidth="1.5" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<input
|
|
type="text"
|
|
placeholder="Search"
|
|
value={searchQuery}
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
className="flex-1 bg-transparent text-Neutrals-NeutralSlate500 text-sm font-normal font-['Inter'] leading-tight outline-none"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Employee List */}
|
|
<div className="self-stretch px-3 flex flex-col justify-start items-start">
|
|
{/* Company Report Item */}
|
|
{currentUserIsOwner && (
|
|
<div
|
|
className={`self-stretch p-2 rounded-full shadow-[0px_1px_2px_0px_rgba(10,13,20,0.03)] inline-flex justify-start items-center gap-2 overflow-hidden cursor-pointer ${selectedReport?.type === 'company' ? 'bg-Main-BG-Gray-100' : ''
|
|
}`}
|
|
onClick={handleCompanyReportSelect}
|
|
>
|
|
<div className="w-7 h-7 p-1 bg-Brand-Orange rounded-[666.67px] flex justify-center items-center">
|
|
<div className="text-center justify-start text-white text-xs font-medium font-['Inter'] leading-none">
|
|
C
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 justify-start text-Neutrals-NeutralSlate950 text-sm font-normal font-['Inter'] leading-tight">Company Report</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Employee Items */}
|
|
{visibleEmployees.map((employee) => (
|
|
<div
|
|
key={employee.id}
|
|
className={`self-stretch p-2 rounded-full shadow-[0px_1px_2px_0px_rgba(10,13,20,0.03)] inline-flex justify-start items-center gap-2 overflow-hidden cursor-pointer ${selectedReport?.type === 'employee' && selectedReport?.employeeName === employee.name ? 'bg-Main-BG-Gray-100' : ''
|
|
}`}
|
|
onClick={() => handleEmployeeSelect(employee)}
|
|
>
|
|
<div className="w-7 h-7 p-1 bg-Main-BG-Gray-100 rounded-[666.67px] flex justify-center items-center">
|
|
<div className="text-center justify-start text-Neutrals-NeutralSlate500 text-xs font-medium font-['Inter'] leading-none">
|
|
{employee.initials}
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 justify-start text-Neutrals-NeutralSlate800 text-sm font-normal font-['Inter'] leading-tight">
|
|
{employee.name}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Main Content Area */}
|
|
<div className="flex-1 self-stretch inline-flex flex-col justify-start items-start">
|
|
{selectedReport ? (
|
|
selectedReport.type === 'company' ? (
|
|
<CompanyReportContent
|
|
report={selectedReport.report as CompanyReport}
|
|
onRegenerate={handleGenerateCompanyReport}
|
|
isGenerating={generatingCompanyReport}
|
|
/>
|
|
) : (
|
|
<EmployeeReportContent
|
|
report={selectedReport.report as Report}
|
|
employeeName={selectedReport.employeeName!}
|
|
/>
|
|
)
|
|
) : (
|
|
<div className="flex-1 flex items-center justify-center">
|
|
<div className="text-center">
|
|
<h3 className="text-lg font-semibold text-Neutrals-NeutralSlate950 mb-2">
|
|
Select a Report
|
|
</h3>
|
|
<p className="text-Neutrals-NeutralSlate500">
|
|
Choose a company or employee report from the list to view details.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// Component for displaying company report content
|
|
const CompanyReportContent: React.FC<{
|
|
report: CompanyReport;
|
|
onRegenerate: () => void;
|
|
isGenerating: boolean;
|
|
}> = ({ report, onRegenerate, isGenerating }) => {
|
|
return (
|
|
<>
|
|
{/* Header */}
|
|
<div className="self-stretch px-5 py-3 inline-flex justify-start items-center gap-2.5">
|
|
<div className="flex-1 justify-start text-Neutrals-NeutralSlate800 text-base font-medium font-['Inter'] leading-normal">
|
|
Company Report
|
|
</div>
|
|
<div className="px-3 py-2.5 bg-Brand-Orange rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 flex justify-center items-center gap-1 overflow-hidden">
|
|
<div className="relative">
|
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M14 14H2M12 7.33333L8 11.3333M8 11.3333L4 7.33333M8 11.3333V2" stroke="var(--Other-White, white)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<div className="px-1 flex justify-center items-center">
|
|
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Download as PDF</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-4 px-5 pb-6 overflow-y-auto">
|
|
{/* Company Weaknesses */}
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Company Weaknesses</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
{report?.weaknesses?.map((weakness, index) => (
|
|
<div key={index}>
|
|
<div className="self-stretch inline-flex justify-between items-start">
|
|
<div className="w-48 justify-start text-Text-Gray-800 text-base font-semibold font-['Inter'] leading-normal">{weakness.title}:</div>
|
|
<div className="flex-1 justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">{weakness.description}</div>
|
|
</div>
|
|
{index < (report?.weaknesses?.length || 0) - 1 && (
|
|
<div className="my-4">
|
|
<svg width="784" height="2" viewBox="0 0 784 2" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M0 1H784" stroke="var(--Text-Gray-200, #E9EAEB)" />
|
|
</svg>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)) || (
|
|
<div className="self-stretch inline-flex justify-between items-start">
|
|
<div className="w-48 justify-start text-Text-Gray-800 text-base font-semibold font-['Inter'] leading-normal">Lack of Structure:</div>
|
|
<div className="flex-1 justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">People are confused about their roles. No one knows who's responsible.</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Personnel Changes */}
|
|
{report?.personnelChanges && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Personnel Changes</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<div className="self-stretch justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.personnelChanges}
|
|
{/* Copilot, we need to implement this so that it works with the defined type, it's not currently implemented correctly. */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Grading Overview */}
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Grading Overview</div>
|
|
</div>
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-3">
|
|
<div className="p-1 bg-Text-Gray-200 rounded-full outline outline-1 outline-offset-[-1px] outline-Outline-Outline-Gray-200 inline-flex justify-start items-center gap-1">
|
|
<div className="px-3 py-1.5 bg-Main-BG-White-0 rounded-full flex justify-center items-center gap-1 overflow-hidden">
|
|
<div className="px-0.5 flex justify-center items-center">
|
|
<div className="justify-start text-Text-Dark-950 text-xs font-medium font-['Inter'] leading-none">Campaigns</div>
|
|
</div>
|
|
</div>
|
|
<div className="px-3 py-1.5 rounded-full 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">
|
|
<div className="px-0.5 flex justify-center items-center">
|
|
<div className="justify-start text-zinc-600 text-xs font-medium font-['Inter'] leading-none">Social Media</div>
|
|
</div>
|
|
</div>
|
|
<div className="px-3 py-1.5 rounded-full 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">
|
|
<div className="px-0.5 flex justify-center items-center">
|
|
<div className="justify-start text-zinc-600 text-xs font-medium font-['Inter'] leading-none">Creative</div>
|
|
</div>
|
|
</div>
|
|
<div className="px-3 py-1.5 rounded-full 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">
|
|
<div className="px-0.5 flex justify-center items-center">
|
|
<div className="justify-start text-zinc-600 text-xs font-medium font-['Inter'] leading-none">Tech</div>
|
|
</div>
|
|
</div>
|
|
<div className="px-3 py-1.5 rounded-full 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">
|
|
<div className="px-0.5 flex justify-center items-center">
|
|
<div className="justify-start text-zinc-600 text-xs font-medium font-['Inter'] leading-none">Admin/OPS</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<div className="self-stretch p-5 bg-Text-Gray-100 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-3 overflow-hidden">
|
|
<div className="self-stretch inline-flex justify-between items-center">
|
|
<div className="w-48 justify-start text-Text-Gray-800 text-base font-semibold font-['Inter'] leading-normal">Department Overview</div>
|
|
<div className="pl-3 pr-1 py-1 bg-green-500/10 rounded-2xl flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Gray-800 text-sm font-medium font-['Inter'] leading-tight">Overall Grade</div>
|
|
<div className="px-2 bg-green-500 rounded-2xl flex justify-start items-center">
|
|
<div className="text-center justify-start text-Text-White-00 text-sm font-medium font-['Inter'] leading-tight">A</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<svg width="752" height="2" viewBox="0 0 752 2" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M0 1H752" stroke="var(--Text-Gray-300, #D5D7DA)" />
|
|
</svg>
|
|
</div>
|
|
<div className="self-stretch justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
Overall company performance shows strong collaboration and delivery with opportunities for process improvement.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Hiring Needs */}
|
|
{report?.immediateHiringNeeds && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Hiring Needs</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<div className="self-stretch justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.immediateHiringNeeds}
|
|
{/* Copilot, we need to implement this so that it works with the defined type, it's not currently implemented correctly. */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Forward Plan */}
|
|
{report?.forwardOperatingPlan && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Forward Plan</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<div className="self-stretch justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.forwardOperatingPlan}
|
|
{/* Copilot, we need to implement this so that it works with the defined type, it's not currently implemented correctly. */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Company Strengths */}
|
|
{report?.organizationalStrengths && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Company Strengths</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
{report.organizationalStrengths.map((strength, index) => (
|
|
<div key={index}>
|
|
<div className="self-stretch inline-flex justify-between items-start">
|
|
<div className="w-48 justify-start text-Text-Gray-800 text-base font-semibold font-['Inter'] leading-normal">{strength.title}:</div>
|
|
<div className="flex-1 justify-start text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">{strength.description}</div>
|
|
</div>
|
|
{index < report.organizationalStrengths.length - 1 && (
|
|
<div className="my-4">
|
|
<svg width="784" height="2" viewBox="0 0 784 2" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M0 1H784" stroke="var(--Text-Gray-200, #E9EAEB)" />
|
|
</svg>
|
|
</div>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
// Component for displaying employee report content
|
|
const EmployeeReportContent: React.FC<{
|
|
report: Report;
|
|
employeeName: string;
|
|
}> = ({ report, employeeName }) => {
|
|
return (
|
|
<>
|
|
{/* Header */}
|
|
<div className="self-stretch px-5 py-3 inline-flex justify-start items-center gap-2.5">
|
|
<div className="flex-1 justify-start text-Neutrals-NeutralSlate800 text-base font-medium font-['Inter'] leading-normal">
|
|
{employeeName}'s Answers
|
|
</div>
|
|
<div className="px-3 py-2.5 bg-Brand-Orange rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 flex justify-center items-center gap-1 overflow-hidden">
|
|
<div className="relative">
|
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M14 14H2M12 7.33333L8 11.3333M8 11.3333L4 7.33333M8 11.3333V2" stroke="var(--Other-White, white)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
</svg>
|
|
</div>
|
|
<div className="px-1 flex justify-center items-center">
|
|
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Download as PDF</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="self-stretch flex flex-col justify-start items-start gap-4 px-5 pb-6 overflow-y-auto">
|
|
{/* Performance Overview */}
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Role & Responsibilities</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<p className="text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.roleAndOutput?.responsibilities || 'No role information available.'}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Work Output */}
|
|
{report.roleAndOutput?.output && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Work Output</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<p className="text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.roleAndOutput.output}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Skills & Experience */}
|
|
{report.skillsAndExperience && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Skills & Experience</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<p className="text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.skillsAndExperience}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Communication Style */}
|
|
{report.communicationStyle && (
|
|
<div className="w-full p-3 bg-Text-Gray-100 rounded-[20px] shadow-[0px_1px_2px_0px_rgba(0,0,0,0.02)] flex flex-col justify-center items-start gap-1 overflow-hidden">
|
|
<div className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2">
|
|
<div className="justify-start text-Text-Dark-950 text-xl font-medium font-['Neue_Montreal'] leading-normal">Communication Style</div>
|
|
</div>
|
|
<div className="self-stretch p-6 bg-Light-Grays-l-gray08 rounded-2xl outline outline-1 outline-offset-[-1px] outline-Text-Gray-200 flex flex-col justify-start items-start gap-4">
|
|
<p className="text-Text-Gray-800 text-base font-normal font-['Inter'] leading-normal">
|
|
{report.communicationStyle}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Reports; |