From 0fba24b17378e106eb6c54d1a8ae604fd5f1cf2a Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Fri, 20 Jun 2025 11:49:22 -0700 Subject: [PATCH] Prettier and eslint fixes in progress --- frontend/src/components/ResumeGenerator.tsx | 2 +- frontend/src/components/layout/Header.tsx | 24 +++---- frontend/src/components/ui/CandidateInfo.tsx | 7 +- .../src/components/ui/CandidatePicker.tsx | 6 +- frontend/src/components/ui/ComingSoon.tsx | 6 +- frontend/src/components/ui/JobInfo.tsx | 12 +--- frontend/src/components/ui/JobPicker.tsx | 6 +- frontend/src/components/ui/JobViewer.tsx | 8 +-- frontend/src/components/ui/JobsTable.tsx | 10 +-- .../src/components/ui/LoginRestricted.tsx | 1 + frontend/src/components/ui/ResumeInfo.tsx | 36 ++-------- frontend/src/components/ui/ResumeViewer.tsx | 9 +-- frontend/src/config/navigationConfig.tsx | 65 ------------------ frontend/src/hooks/AuthContext.tsx | 7 +- frontend/src/hooks/GlobalContext.tsx | 2 +- frontend/src/hooks/useAutoScrollToBottom.tsx | 4 +- frontend/src/pages/CandidateChatPage.tsx | 12 ++-- frontend/src/pages/GenerateCandidate.tsx | 2 +- frontend/src/pages/HowItWorks.tsx | 17 +---- frontend/src/pages/JobAnalysisPage.tsx | 12 +--- frontend/src/pages/LoginPage.tsx | 5 +- frontend/src/pages/candidate/Dashboard.tsx | 2 +- frontend/src/pages/candidate/Profile.tsx | 67 +++++-------------- .../src/pages/candidate/RegistrationForms.tsx | 6 +- frontend/src/pages/candidate/Settings.tsx | 2 +- frontend/src/services/api-client.ts | 14 ++-- 26 files changed, 77 insertions(+), 267 deletions(-) diff --git a/frontend/src/components/ResumeGenerator.tsx b/frontend/src/components/ResumeGenerator.tsx index 336d68a..62bfd96 100644 --- a/frontend/src/components/ResumeGenerator.tsx +++ b/frontend/src/components/ResumeGenerator.tsx @@ -12,7 +12,7 @@ import { StatusBox, StatusIcon } from './ui/StatusIcon'; import { CopyBubble } from './CopyBubble'; import { useAppState } from 'hooks/GlobalContext'; import { StreamingOptions } from 'services/api-client'; -import { Navigate, useNavigate } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; interface ResumeGeneratorProps { job: Job; diff --git a/frontend/src/components/layout/Header.tsx b/frontend/src/components/layout/Header.tsx index 4ae0114..83f5504 100644 --- a/frontend/src/components/layout/Header.tsx +++ b/frontend/src/components/layout/Header.tsx @@ -1,19 +1,16 @@ // components/layout/Header.tsx -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { NavigateFunction, useLocation } from 'react-router-dom'; import { AppBar, Toolbar, Tooltip, - Typography, Button, IconButton, Box, Drawer, Divider, Avatar, - Tabs, - Tab, Container, Fade, Popover, @@ -26,25 +23,18 @@ import { List, ListItem, ListItemButton, - SxProps, } from '@mui/material'; import { styled, useTheme } from '@mui/material/styles'; import { Menu as MenuIcon, - Dashboard, - Person, Logout, - Settings, ExpandMore, ExpandLess, KeyboardArrowDown, } from '@mui/icons-material'; -import FaceRetouchingNaturalIcon from '@mui/icons-material/FaceRetouchingNatural'; import { getUserMenuItemsByGroup } from 'config/navigationConfig'; import { NavigationItem } from 'types/navigation'; import { Beta } from 'components/ui/Beta'; -import { Candidate, Employer } from 'types/types'; -import { SetSnackType } from 'components/Snack'; import { CopyBubble } from 'components/CopyBubble'; import 'components/layout/Header.css'; @@ -193,7 +183,9 @@ const Header: React.FC = (props: HeaderProps) => { id: item.id, label: item.label as string, icon: item.icon || null, - action: () => item.path && navigate(item.path.replace(/:.*$/, '')), + action: () => { + item.path && navigate(item.path.replace(/:.*$/, '')); + }, group: 'account', }); } @@ -217,7 +209,9 @@ const Header: React.FC = (props: HeaderProps) => { id: item.id, label: item.label as string, icon: item.icon || null, - action: () => item.path && navigate(item.path.replace(/:.*$/, '')), + action: () => { + item.path && navigate(item.path.replace(/:.*$/, '')); + }, group: 'admin', }); } @@ -252,7 +246,9 @@ const Header: React.FC = (props: HeaderProps) => { id: item.id, label: item.label as string, icon: item.icon || null, - action: () => item.path && navigate(item.path.replace(/:.*$/, '')), + action: () => { + item.path && navigate(item.path.replace(/:.*$/, '')); + }, group: 'system', }); } diff --git a/frontend/src/components/ui/CandidateInfo.tsx b/frontend/src/components/ui/CandidateInfo.tsx index b33c45b..8d9dc88 100644 --- a/frontend/src/components/ui/CandidateInfo.tsx +++ b/frontend/src/components/ui/CandidateInfo.tsx @@ -1,6 +1,6 @@ import React, { useState, useRef, useEffect } from 'react'; -import { Box, Link, Typography, Avatar, Grid, SxProps, Tooltip, IconButton } from '@mui/material'; -import { Card, CardContent, Divider, useTheme } from '@mui/material'; +import { Box, Link, Typography, Avatar, SxProps, Tooltip, IconButton } from '@mui/material'; +import { Divider, useTheme } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import { useMediaQuery } from '@mui/material'; import { Candidate, CandidateAI } from 'types/types'; @@ -8,7 +8,6 @@ import { CopyBubble } from 'components/CopyBubble'; import { rest } from 'lodash'; import { AIBanner } from 'components/ui/AIBanner'; import { useAuth } from 'hooks/AuthContext'; -import { DeleteConfirmation } from '../DeleteConfirmation'; interface CandidateInfoProps { candidate: Candidate; @@ -21,7 +20,7 @@ interface CandidateInfoProps { const CandidateInfo: React.FC = (props: CandidateInfoProps) => { const { candidate } = props; const { user, apiClient } = useAuth(); - const { sx, action = '', elevation = 1, variant = 'normal' } = props; + const { sx, action = '', variant = 'normal' } = props; const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')) || variant === 'minimal'; const ai: CandidateAI | null = 'isAI' in candidate ? (candidate as CandidateAI) : null; diff --git a/frontend/src/components/ui/CandidatePicker.tsx b/frontend/src/components/ui/CandidatePicker.tsx index cd0e955..762c507 100644 --- a/frontend/src/components/ui/CandidatePicker.tsx +++ b/frontend/src/components/ui/CandidatePicker.tsx @@ -1,11 +1,10 @@ import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import { BackstoryElementProps } from 'components/BackstoryTab'; import { CandidateInfo } from 'components/ui/CandidateInfo'; -import { Candidate, CandidateAI } from 'types/types'; +import { Candidate } from 'types/types'; import { useAuth } from 'hooks/AuthContext'; import { useAppState, useSelectedCandidate } from 'hooks/GlobalContext'; import { Paper } from '@mui/material'; @@ -18,7 +17,6 @@ const CandidatePicker = (props: CandidatePickerProps) => { const { onSelect, sx } = props; const { apiClient, user } = useAuth(); const { selectedCandidate, setSelectedCandidate } = useSelectedCandidate(); - const navigate = useNavigate(); const { setSnack } = useAppState(); const [candidates, setCandidates] = useState(null); @@ -64,7 +62,7 @@ const CandidatePicker = (props: CandidatePickerProps) => { justifyContent: 'center', }} > - {candidates?.map((u, i) => ( + {candidates?.map(u => ( { diff --git a/frontend/src/components/ui/ComingSoon.tsx b/frontend/src/components/ui/ComingSoon.tsx index e1d4b26..e3484b0 100644 --- a/frontend/src/components/ui/ComingSoon.tsx +++ b/frontend/src/components/ui/ComingSoon.tsx @@ -1,7 +1,6 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React from 'react'; import Box from '@mui/material/Box'; -import useMediaQuery from '@mui/material/useMediaQuery'; -import { SxProps, useTheme } from '@mui/material/styles'; +import { useTheme } from '@mui/material/styles'; import './ComingSoon.css'; @@ -11,7 +10,6 @@ type ComingSoonProps = { const ComingSoon: React.FC = (props: ComingSoonProps) => { const { children } = props; - const theme = useTheme(); return ( Coming Soon diff --git a/frontend/src/components/ui/JobInfo.tsx b/frontend/src/components/ui/JobInfo.tsx index c0d110b..fae3878 100644 --- a/frontend/src/components/ui/JobInfo.tsx +++ b/frontend/src/components/ui/JobInfo.tsx @@ -1,17 +1,12 @@ -import React, { JSX, useActionState, useEffect, useRef, useState } from 'react'; +import React, { JSX, useEffect, useRef, useState } from 'react'; import { Box, Link, Typography, - Avatar, - Grid, SxProps, - CardActions, Chip, Stack, CardHeader, - Button, - styled, LinearProgress, IconButton, Tooltip, @@ -20,11 +15,8 @@ import { Card, CardContent, Divider, useTheme } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import { useMediaQuery } from '@mui/material'; import { Job } from 'types/types'; -import { CopyBubble } from 'components/CopyBubble'; import { rest } from 'lodash'; -import { AIBanner } from 'components/ui/AIBanner'; import { useAuth } from 'hooks/AuthContext'; -import { DeleteConfirmation } from '../DeleteConfirmation'; import { Build, CheckCircle, Description, Psychology, Star, Work } from '@mui/icons-material'; import ModelTrainingIcon from '@mui/icons-material/ModelTraining'; import { StatusIcon, StatusBox } from 'components/ui/StatusIcon'; @@ -45,7 +37,7 @@ interface JobInfoProps { const JobInfo: React.FC = (props: JobInfoProps) => { const { setSnack } = useAppState(); const { user, apiClient } = useAuth(); - const { sx, action = '', elevation = 1, variant = 'normal', job } = props; + const { sx, variant = 'normal', job } = props; const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')) || variant === 'minimal'; const isAdmin = user?.isAdmin; diff --git a/frontend/src/components/ui/JobPicker.tsx b/frontend/src/components/ui/JobPicker.tsx index 690082f..fa6a339 100644 --- a/frontend/src/components/ui/JobPicker.tsx +++ b/frontend/src/components/ui/JobPicker.tsx @@ -1,6 +1,4 @@ import React, { useEffect, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import { BackstoryElementProps } from 'components/BackstoryTab'; @@ -17,7 +15,7 @@ interface JobPickerProps extends BackstoryElementProps { const JobPicker = (props: JobPickerProps) => { const { onSelect } = props; const { apiClient } = useAuth(); - const { selectedJob, setSelectedJob } = useSelectedJob(); + const { selectedJob } = useSelectedJob(); const { setSnack } = useAppState(); const [jobs, setJobs] = useState(null); @@ -55,7 +53,7 @@ const JobPicker = (props: JobPickerProps) => { justifyContent: 'center', }} > - {jobs?.map((j, i) => ( + {jobs?.map(j => ( { diff --git a/frontend/src/components/ui/JobViewer.tsx b/frontend/src/components/ui/JobViewer.tsx index 77a9b7d..2d57fea 100644 --- a/frontend/src/components/ui/JobViewer.tsx +++ b/frontend/src/components/ui/JobViewer.tsx @@ -28,7 +28,6 @@ import { Business as BusinessIcon, Work as WorkIcon, Schedule as ScheduleIcon, - Close as CloseIcon, ArrowBack as ArrowBackIcon, } from '@mui/icons-material'; import { TransitionProps } from '@mui/material/transitions'; @@ -36,7 +35,7 @@ import { JobInfo } from 'components/ui/JobInfo'; import { Job } from 'types/types'; import { useAuth } from 'hooks/AuthContext'; import { useAppState, useSelectedJob } from 'hooks/GlobalContext'; -import { Navigate, useNavigate, useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; type SortField = 'updatedAt' | 'createdAt' | 'company' | 'title'; type SortOrder = 'asc' | 'desc'; @@ -71,8 +70,8 @@ const JobViewer: React.FC = ({ onSelect }) => { const { jobId } = useParams<{ jobId?: string }>(); useEffect(() => { + if (loading) return; // Prevent multiple calls const getJobs = async () => { - setLoading(true); try { const results = await apiClient.getJobs(); const jobsData: Job[] = results.data || []; @@ -101,8 +100,9 @@ const JobViewer: React.FC = ({ onSelect }) => { } }; + setLoading(true); getJobs(); - }, [apiClient, setSnack]); + }, [apiClient, setSnack, loading]); const sortJobs = (jobsList: Job[], field: SortField, order: SortOrder): Job[] => { return [...jobsList].sort((a, b) => { diff --git a/frontend/src/components/ui/JobsTable.tsx b/frontend/src/components/ui/JobsTable.tsx index 654d77b..c3f8348 100644 --- a/frontend/src/components/ui/JobsTable.tsx +++ b/frontend/src/components/ui/JobsTable.tsx @@ -59,7 +59,7 @@ const JobsTable: React.FC = ({ // Fetch jobs from API const fetchJobs = React.useCallback( - async (pageNum: number = 0, searchTerm: string = '') => { + async (pageNum = 0, searchTerm = '') => { try { setLoading(true); setError(null); @@ -71,7 +71,6 @@ const JobsTable: React.FC = ({ }; let paginationResponse: Types.PaginatedResponse; - let url = `/api/1.0/jobs`; if (searchTerm.trim()) { paginationResponse = await apiClient.searchJobs(searchTerm); } else { @@ -152,17 +151,12 @@ const JobsTable: React.FC = ({ onJobSelect?.(selectedJobsList); }; - // Utility functions - const formatDate = (dateString: string) => { - return new Date(dateString).toLocaleDateString(); - }; - const getOwnerName = (owner?: Types.Job['owner']) => { if (!owner) return 'Unknown'; return `${owner.firstName || ''} ${owner.lastName || ''}`.trim() || owner.email || 'Unknown'; }; - const truncateDescription = (description: string, maxLength: number = 100) => { + const truncateDescription = (description: string, maxLength = 100) => { if (description.length <= maxLength) return description; return description.substring(0, maxLength) + '...'; }; diff --git a/frontend/src/components/ui/LoginRestricted.tsx b/frontend/src/components/ui/LoginRestricted.tsx index 90eb5c6..caaa997 100644 --- a/frontend/src/components/ui/LoginRestricted.tsx +++ b/frontend/src/components/ui/LoginRestricted.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import Box from '@mui/material/Box'; import './LoginRestricted.css'; diff --git a/frontend/src/components/ui/ResumeInfo.tsx b/frontend/src/components/ui/ResumeInfo.tsx index 49e8a20..ecd545e 100644 --- a/frontend/src/components/ui/ResumeInfo.tsx +++ b/frontend/src/components/ui/ResumeInfo.tsx @@ -1,13 +1,9 @@ import React, { useEffect, useRef, useState } from 'react'; import { Box, - Link, Typography, - Avatar, Grid, SxProps, - CardActions, - Chip, Stack, CardHeader, Button, @@ -19,7 +15,6 @@ import { Divider, useTheme, useMediaQuery, - TextField, Dialog, DialogTitle, DialogContent, @@ -38,8 +33,6 @@ import { Work as WorkIcon, Person as PersonIcon, Schedule as ScheduleIcon, - Visibility as VisibilityIcon, - VisibilityOff as VisibilityOffIcon, ModelTraining, } from '@mui/icons-material'; import InputIcon from '@mui/icons-material/Input'; @@ -73,14 +66,13 @@ const ResumeInfo: React.FC = (props: ResumeInfoProps) => { const { setSnack } = useAppState(); const { resume } = props; const { user, apiClient } = useAuth(); - const { sx, action = '', elevation = 1, variant = 'normal' } = props; + const { sx, variant = 'normal' } = props; const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')) || variant === 'minimal'; const isAdmin = user?.isAdmin; const [activeResume, setActiveResume] = useState({ ...resume }); const [deleted, setDeleted] = useState(false); const [editDialogOpen, setEditDialogOpen] = useState(false); - const [printDialogOpen, setPrintDialogOpen] = useState(false); const [editContent, setEditContent] = useState(''); const [editSystemPrompt, setEditSystemPrompt] = useState(''); const [editPrompt, setEditPrompt] = useState(''); @@ -437,32 +429,12 @@ const ResumeInfo: React.FC = (props: ResumeInfoProps) => { )} - {/* Print Dialog */} - {}} //setPrintDialogOpen(false)} - maxWidth="lg" - fullWidth - fullScreen={true} - > - - - {/* Edit Dialog */} setEditDialogOpen(false)} + onClose={() => { + setEditDialogOpen(false); + }} maxWidth="lg" fullWidth disableEscapeKeyDown={true} diff --git a/frontend/src/components/ui/ResumeViewer.tsx b/frontend/src/components/ui/ResumeViewer.tsx index 53fc656..374afb9 100644 --- a/frontend/src/components/ui/ResumeViewer.tsx +++ b/frontend/src/components/ui/ResumeViewer.tsx @@ -13,7 +13,6 @@ import { Select, MenuItem, InputLabel, - Chip, IconButton, Dialog, AppBar, @@ -27,11 +26,9 @@ import { import { KeyboardArrowUp as ArrowUpIcon, KeyboardArrowDown as ArrowDownIcon, - Description as DescriptionIcon, Work as WorkIcon, Person as PersonIcon, Schedule as ScheduleIcon, - Close as CloseIcon, ArrowBack as ArrowBackIcon, Search as SearchIcon, Clear as ClearIcon, @@ -40,7 +37,7 @@ import { TransitionProps } from '@mui/material/transitions'; import { ResumeInfo } from 'components/ui/ResumeInfo'; import { useAuth } from 'hooks/AuthContext'; import { useAppState, useSelectedResume } from 'hooks/GlobalContext'; // Assuming similar context exists -import { Navigate, useNavigate, useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { Resume } from 'types/types'; type SortField = 'updatedAt' | 'createdAt' | 'candidateId' | 'jobId'; @@ -71,7 +68,6 @@ const ResumeViewer: React.FC = ({ onSelect, candidateId, jobI const { selectedResume, setSelectedResume } = useSelectedResume(); // Assuming similar context const { setSnack } = useAppState(); const [resumes, setResumes] = useState([]); - const [loading, setLoading] = useState(false); const [sortField, setSortField] = useState('updatedAt'); const [sortOrder, setSortOrder] = useState('desc'); const [mobileDialogOpen, setMobileDialogOpen] = useState(false); @@ -81,7 +77,6 @@ const ResumeViewer: React.FC = ({ onSelect, candidateId, jobI useEffect(() => { const getResumes = async () => { - setLoading(true); try { let results; @@ -115,8 +110,6 @@ const ResumeViewer: React.FC = ({ onSelect, candidateId, jobI } catch (err) { console.error('Failed to load resumes:', err); setSnack('Failed to load resumes: ' + err, 'error'); - } finally { - setLoading(false); } }; diff --git a/frontend/src/config/navigationConfig.tsx b/frontend/src/config/navigationConfig.tsx index 7325561..09eb2d2 100644 --- a/frontend/src/config/navigationConfig.tsx +++ b/frontend/src/config/navigationConfig.tsx @@ -2,33 +2,17 @@ import React from 'react'; import { Chat as ChatIcon, Dashboard as DashboardIcon, - Description as DescriptionIcon, - BarChart as BarChartIcon, Settings as SettingsIcon, Work as WorkIcon, - Info as InfoIcon, Person as PersonIcon, - Business as BusinessIcon, - Search as SearchIcon, - Bookmark as BookmarkIcon, - History as HistoryIcon, - QuestionAnswer as QuestionAnswerIcon, - AttachMoney as AttachMoneyIcon, - Quiz as QuizIcon, - Analytics as AnalyticsIcon, BubbleChart, AutoFixHigh, } from '@mui/icons-material'; import EditDocumentIcon from '@mui/icons-material/EditDocument'; import { BackstoryLogo } from 'components/ui/BackstoryLogo'; -import { HomePage } from 'pages/HomePage'; import { CandidateChatPage } from 'pages/CandidateChatPage'; -import { DocsPage } from 'pages/DocsPage'; -import { CreateProfilePage } from 'pages/candidate/ProfileWizard'; -import { VectorVisualizerPage } from 'pages/VectorVisualizerPage'; import { BetaPage } from 'pages/BetaPage'; -import { CandidateListingPage } from 'pages/FindCandidatePage'; import { JobAnalysisPage } from 'pages/JobAnalysisPage'; import { GenerateCandidate } from 'pages/GenerateCandidate'; import { LoginPage } from 'pages/LoginPage'; @@ -37,7 +21,6 @@ import { Box, Typography } from '@mui/material'; import { CandidateDashboard } from 'pages/candidate/Dashboard'; import { NavigationConfig, NavigationItem } from 'types/navigation'; import { HowItWorks } from 'pages/HowItWorks'; -import SchoolIcon from '@mui/icons-material/School'; import { CandidateProfile } from 'pages/candidate/Profile'; import { Settings } from 'pages/candidate/Settings'; import { VectorVisualizer } from 'components/VectorVisualizer'; @@ -45,49 +28,11 @@ import { DocumentManager } from 'components/DocumentManager'; import { useAuth } from 'hooks/AuthContext'; import { useNavigate } from 'react-router-dom'; import { JobViewer } from 'components/ui/JobViewer'; -import { CandidatePicker } from 'components/ui/CandidatePicker'; import { ResumeViewer } from 'components/ui/ResumeViewer'; import { JobsTable } from 'components/ui/JobsTable'; import * as Types from 'types/types'; -// Beta page components for placeholder routes -const BackstoryPage = () => ( - - Backstory - -); -const ResumesPage = () => ( - - Resumes - -); -const QASetupPage = () => ( - - Q&A Setup - -); -const SearchPage = () => ( - - Search - -); -const SavedPage = () => ( - - Saved - -); -const JobsPage = () => ( - - Jobs - -); -const CompanyPage = () => ( - - Company - -); - const LogoutPage = () => { const { logout } = useAuth(); const navigate = useNavigate(); @@ -96,16 +41,6 @@ const LogoutPage = () => { }); return Logging out...; }; -const AnalyticsPage = () => ( - - Analytics - -); -const SettingsPage = () => ( - - Settings - -); export const navigationConfig: NavigationConfig = { items: [ diff --git a/frontend/src/hooks/AuthContext.tsx b/frontend/src/hooks/AuthContext.tsx index 5baaa41..5126065 100644 --- a/frontend/src/hooks/AuthContext.tsx +++ b/frontend/src/hooks/AuthContext.tsx @@ -2,12 +2,7 @@ import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react'; import * as Types from '../types/types'; -import { - ApiClient, - CreateCandidateRequest, - CreateEmployerRequest, - GuestConversionRequest, -} from 'services/api-client'; +import { ApiClient, CreateEmployerRequest, GuestConversionRequest } from 'services/api-client'; import { formatApiRequest, toCamelCase } from 'types/conversion'; // ============================ diff --git a/frontend/src/hooks/GlobalContext.tsx b/frontend/src/hooks/GlobalContext.tsx index 946b66d..bd150fa 100644 --- a/frontend/src/hooks/GlobalContext.tsx +++ b/frontend/src/hooks/GlobalContext.tsx @@ -365,7 +365,7 @@ export function useAppStateLogic(): AppStateContextType { console.log('Cleared all route state'); }, []); - const emptySetSnack: SetSnackType = (message: string, severity?: SeverityType) => { + const emptySetSnack: SetSnackType = (_message: string, _severity?: SeverityType) => { return; }; diff --git a/frontend/src/hooks/useAutoScrollToBottom.tsx b/frontend/src/hooks/useAutoScrollToBottom.tsx index cf8c688..a495b9f 100644 --- a/frontend/src/hooks/useAutoScrollToBottom.tsx +++ b/frontend/src/hooks/useAutoScrollToBottom.tsx @@ -68,10 +68,10 @@ const useResizeObserverAndMutationObserver = ( requestAnimationFrame(() => callbackRef.current()); }, 500); - const resizeObserver = new ResizeObserver((e: any) => { + const resizeObserver = new ResizeObserver((_e: any) => { debouncedCallback('resize'); }); - const mutationObserver = new MutationObserver((e: any) => { + const mutationObserver = new MutationObserver((_e: any) => { debouncedCallback('mutation'); }); diff --git a/frontend/src/pages/CandidateChatPage.tsx b/frontend/src/pages/CandidateChatPage.tsx index 423709e..5cdd2bc 100644 --- a/frontend/src/pages/CandidateChatPage.tsx +++ b/frontend/src/pages/CandidateChatPage.tsx @@ -1,5 +1,5 @@ import React, { forwardRef, useState, useEffect, useRef } from 'react'; -import { Box, Paper, Button, Divider, useTheme, useMediaQuery, Tooltip } from '@mui/material'; +import { Box, Paper, Button, useTheme, Tooltip } from '@mui/material'; import { Send as SendIcon } from '@mui/icons-material'; import { useAuth } from 'hooks/AuthContext'; import { @@ -34,11 +34,9 @@ const defaultMessage: ChatMessage = { }; const CandidateChatPage = forwardRef( - (props: BackstoryPageProps, ref) => { + (_props: BackstoryPageProps, ref) => { const { apiClient } = useAuth(); - const navigate = useNavigate(); const { selectedCandidate, setSelectedCandidate } = useSelectedCandidate(); - const theme = useTheme(); const [processingMessage, setProcessingMessage] = useState< ChatMessageStatus | ChatMessageError | null >(null); @@ -124,11 +122,9 @@ const CandidateChatPage = forwardRef( }, onError: (error: string | ChatMessageError) => { console.log('onError:', error); - let message: string; // Type-guard to determine if this is a ChatMessageBase or a string if (typeof error === 'object' && error !== null && 'content' in error) { setProcessingMessage(error); - message = error.content as string; } else { setProcessingMessage({ ...defaultMessage, @@ -300,7 +296,7 @@ const CandidateChatPage = forwardRef( )} {selectedCandidate.questions?.length !== 0 && - selectedCandidate.questions?.map(q => )} + selectedCandidate.questions?.map((q, i) => )} {/* Fixed Message Input */} ( ); } ); - +CandidateChatPage.displayName = 'CandidateChatPage'; export { CandidateChatPage }; diff --git a/frontend/src/pages/GenerateCandidate.tsx b/frontend/src/pages/GenerateCandidate.tsx index 5e4d019..94e8f62 100644 --- a/frontend/src/pages/GenerateCandidate.tsx +++ b/frontend/src/pages/GenerateCandidate.tsx @@ -39,7 +39,7 @@ const defaultMessage: ChatMessage = { metadata: null as any, }; -const GenerateCandidate = (props: BackstoryElementProps) => { +const GenerateCandidate = (_props: BackstoryElementProps) => { const { apiClient, user } = useAuth(); const { setSnack } = useAppState(); const [processingMessage, setProcessingMessage] = useState(null); diff --git a/frontend/src/pages/HowItWorks.tsx b/frontend/src/pages/HowItWorks.tsx index 96dc3e8..c769db8 100644 --- a/frontend/src/pages/HowItWorks.tsx +++ b/frontend/src/pages/HowItWorks.tsx @@ -7,15 +7,11 @@ import { Paper, Typography, Grid, - Card, - CardContent, - Chip, Step, StepLabel, Stepper, Stack, ButtonProps, - useMediaQuery, useTheme, } from '@mui/material'; import { styled } from '@mui/material/styles'; @@ -80,16 +76,6 @@ const ImageContainer = styled(Box)(({ theme }) => ({ }, })); -const StepCard = styled(Card)(({ theme }) => ({ - height: '100%', - display: 'flex', - flexDirection: 'column', - border: `1px solid ${theme.palette.action.active}`, - '&:hover': { - boxShadow: theme.shadows[4], - }, -})); - const steps = [ 'Select Job Analysis', 'Choose a Job', @@ -242,7 +228,6 @@ const HeroButton = (props: HeroButtonProps) => { const HowItWorks: React.FC = () => { const navigate = useNavigate(); const theme = useTheme(); - const isMobile = useMediaQuery(theme.breakpoints.down('md')); const handleGetStarted = () => { navigate('/job-analysis'); @@ -270,7 +255,7 @@ const HowItWorks: React.FC = () => { component="h1" sx={{ fontWeight: 700, - fontSize: { xs: '2rem', md: '3rem' }, + fontSize: { xs: '1.5rem', md: '2rem' }, mb: 2, color: 'white', }} diff --git a/frontend/src/pages/JobAnalysisPage.tsx b/frontend/src/pages/JobAnalysisPage.tsx index bdbce8e..1ab27b4 100644 --- a/frontend/src/pages/JobAnalysisPage.tsx +++ b/frontend/src/pages/JobAnalysisPage.tsx @@ -5,7 +5,6 @@ import { Step, StepLabel, Button, - Typography, Paper, useTheme, Snackbar, @@ -14,7 +13,6 @@ import { Tab, Avatar, useMediaQuery, - Divider, } from '@mui/material'; import { Add, WorkOutline } from '@mui/icons-material'; import PersonIcon from '@mui/icons-material/Person'; @@ -22,19 +20,15 @@ import WorkIcon from '@mui/icons-material/Work'; import AssessmentIcon from '@mui/icons-material/Assessment'; import { JobMatchAnalysis } from 'components/JobMatchAnalysis'; import { Candidate, Job, SkillAssessment } from 'types/types'; -import { useNavigate } from 'react-router-dom'; import { BackstoryPageProps } from 'components/BackstoryTab'; import { useAuth } from 'hooks/AuthContext'; -import { useAppState, useSelectedCandidate, useSelectedJob } from 'hooks/GlobalContext'; +import { useSelectedCandidate, useSelectedJob } from 'hooks/GlobalContext'; import { CandidateInfo } from 'components/ui/CandidateInfo'; -import { ComingSoon } from 'components/ui/ComingSoon'; -import { LoginRequired } from 'components/ui/LoginRequired'; import { Scrollable } from 'components/Scrollable'; import { CandidatePicker } from 'components/ui/CandidatePicker'; import { JobPicker } from 'components/ui/JobPicker'; import { JobCreator } from 'components/JobCreator'; import { LoginRestricted } from 'components/ui/LoginRestricted'; -import JsonView from '@uiw/react-json-view'; import { ResumeGenerator } from 'components/ResumeGenerator'; import { JobInfo } from 'components/ui/JobInfo'; @@ -110,7 +104,7 @@ const capitalize = (str: string) => { }; // Main component -const JobAnalysisPage: React.FC = (props: BackstoryPageProps) => { +const JobAnalysisPage: React.FC = (_props: BackstoryPageProps) => { const theme = useTheme(); const { user, guest } = useAuth(); const { selectedCandidate, setSelectedCandidate } = useSelectedCandidate(); @@ -329,7 +323,7 @@ const JobAnalysisPage: React.FC = (props: BackstoryPageProps {steps.map((step, index) => ( - + { diff --git a/frontend/src/pages/LoginPage.tsx b/frontend/src/pages/LoginPage.tsx index d2a7955..2eb4823 100644 --- a/frontend/src/pages/LoginPage.tsx +++ b/frontend/src/pages/LoginPage.tsx @@ -1,7 +1,6 @@ import React, { useState, useEffect } from 'react'; import { Box, - Container, Paper, Typography, Alert, @@ -33,9 +32,7 @@ const LoginPage: React.FC = (props: BackstoryPageProps) => { const [tabValue, setTabValue] = useState('login'); const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(null); - const { guest, user, login, isLoading, error } = useAuth(); - const name = - user?.userType === 'candidate' ? (user as Types.Candidate).username : user?.email || ''; + const { guest, user, error } = useAuth(); const [errorMessage, setErrorMessage] = useState(null); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); diff --git a/frontend/src/pages/candidate/Dashboard.tsx b/frontend/src/pages/candidate/Dashboard.tsx index bc0c1a1..ff117e9 100644 --- a/frontend/src/pages/candidate/Dashboard.tsx +++ b/frontend/src/pages/candidate/Dashboard.tsx @@ -17,7 +17,7 @@ import { useAppState } from 'hooks/GlobalContext'; type CandidateDashboardProps = BackstoryElementProps; -const CandidateDashboard = (props: CandidateDashboardProps) => { +const CandidateDashboard = (_props: CandidateDashboardProps) => { const { setSnack } = useAppState(); const navigate = useNavigate(); const { user } = useAuth(); diff --git a/frontend/src/pages/candidate/Profile.tsx b/frontend/src/pages/candidate/Profile.tsx index e06c2e2..1002053 100644 --- a/frontend/src/pages/candidate/Profile.tsx +++ b/frontend/src/pages/candidate/Profile.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect } from 'react'; -import CheckIcon from '@mui/icons-material/Check'; import { Box, Button, @@ -29,8 +28,6 @@ import { InputLabel, Switch, FormControlLabel, - ToggleButton, - Checkbox, } from '@mui/material'; import { styled } from '@mui/material/styles'; import { @@ -100,12 +97,11 @@ function TabPanel(props: TabPanelProps) { ); } -const CandidateProfile: React.FC = (props: BackstoryPageProps) => { +const CandidateProfile: React.FC = (_props: BackstoryPageProps) => { const { setSnack } = useAppState(); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const { user, updateUserData, apiClient } = useAuth(); - const [isPublic, setIsPublic] = React.useState(true); // Check if user is a candidate const candidate = user?.userType === 'candidate' ? (user as Types.Candidate) : null; @@ -427,24 +423,11 @@ const CandidateProfile: React.FC = (props: BackstoryPageProp - {false && editMode.basic ? ( - handleInputChange('email', e.target.value)} - variant="outlined" - /> - ) : ( - <> - - - Email - - {candidate.email} - - )} + + + Email + + {candidate.email} @@ -487,31 +470,13 @@ const CandidateProfile: React.FC = (props: BackstoryPageProp - {false && editMode.basic ? ( - - handleInputChange('location', { - ...formData.location, - city: e.target.value, - }) - } - variant="outlined" - placeholder="City, State, Country" - /> - ) : ( - <> - - - Location - - - {candidate.location?.city || 'Not specified'} {candidate.location?.country || ''} - - - )} + + + Location + + + {candidate.location?.city || 'Not specified'} {candidate.location?.country || ''} + @@ -655,7 +620,7 @@ const CandidateProfile: React.FC = (props: BackstoryPageProp {(!formData.skills || formData.skills.length === 0) && ( - No skills added yet. Click "Add Skill" to get started. + No skills added yet. Click "Add Skill" to get started. )} @@ -781,7 +746,7 @@ const CandidateProfile: React.FC = (props: BackstoryPageProp fontSize: { xs: '0.8rem', sm: '0.875rem' }, }} > - No work experience added yet. Click "Add Experience" to get started. + No work experience added yet. Click "Add Experience" to get started. )} @@ -820,7 +785,7 @@ const CandidateProfile: React.FC = (props: BackstoryPageProp fontSize: { xs: '0.8rem', sm: '0.875rem' }, }} > - No work experience added yet. Click "Add Experience" to get started. + No work experience added yet. Click "Add Experience" to get started. )} diff --git a/frontend/src/pages/candidate/RegistrationForms.tsx b/frontend/src/pages/candidate/RegistrationForms.tsx index 67f99b1..faa03b9 100644 --- a/frontend/src/pages/candidate/RegistrationForms.tsx +++ b/frontend/src/pages/candidate/RegistrationForms.tsx @@ -811,7 +811,7 @@ export function RegistrationTypeSelector() { Join Backstory - Choose how you'd like to get started + Choose how you'd like to get started @@ -836,7 +836,7 @@ export function RegistrationTypeSelector() { 👤 - I'm looking for work + I'm looking for work Create a candidate profile to find your next opportunity @@ -869,7 +869,7 @@ export function RegistrationTypeSelector() { 🏢 - I'm hiring + I'm hiring Create a company account to find and hire talent diff --git a/frontend/src/pages/candidate/Settings.tsx b/frontend/src/pages/candidate/Settings.tsx index e10e9c9..7970c79 100644 --- a/frontend/src/pages/candidate/Settings.tsx +++ b/frontend/src/pages/candidate/Settings.tsx @@ -83,7 +83,7 @@ const SystemInfoComponent: React.FC<{ return
{systemElements}
; }; -const Settings = (props: BackstoryPageProps) => { +const Settings = (_props: BackstoryPageProps) => { const { apiClient } = useAuth(); const { setSnack } = useAppState(); // const [editSystemPrompt, setEditSystemPrompt] = useState(""); diff --git a/frontend/src/services/api-client.ts b/frontend/src/services/api-client.ts index 1936595..fdbd7bb 100644 --- a/frontend/src/services/api-client.ts +++ b/frontend/src/services/api-client.ts @@ -1442,7 +1442,8 @@ class ApiClient { const messageId = ''; let finalMessage: T | null = null; - const promise = new Promise(async (resolve, reject) => { + + const processStream = async (): Promise => { try { const response = await fetch(`${this.baseUrl}${api}`, { method, @@ -1467,6 +1468,7 @@ class ApiClient { const decoder = new TextDecoder(); let buffer = ''; let streamingMessage: Types.ChatMessageStreaming | null = null; + try { while (true) { const { done, value } = await reader.read(); @@ -1545,11 +1547,11 @@ class ApiClient { } options.onComplete?.(); - resolve(finalMessage as T); + return finalMessage as T; } catch (error) { if (signal.aborted) { options.onComplete?.(); - reject(new Error('Request was aborted')); + throw new Error('Request was aborted'); } else { console.error(error); options.onError?.({ @@ -1559,15 +1561,15 @@ class ApiClient { content: (error as Error).message, }); options.onComplete?.(); - reject(error); + throw error; } } - }); + }; return { messageId, cancel: () => abortController.abort(), - promise, + promise: processStream(), }; }