Changed header menu

Added date fields to Job
This commit is contained in:
James Ketr 2025-06-09 10:59:24 -07:00
parent 781275e9a9
commit 7b457244ae
10 changed files with 57 additions and 21 deletions

View File

@ -328,7 +328,9 @@ const JobCreator = (props: JobCreator) => {
company: company,
summary: summary,
title: jobTitle,
requirements: jobRequirements || undefined
requirements: jobRequirements || undefined,
createdAt: new Date(),
updatedAt: new Date(),
};
setIsProcessing(true);
const job = await apiClient.createJob(newJob);

View File

@ -26,6 +26,7 @@ import {
List,
ListItem,
ListItemButton,
SxProps,
} from '@mui/material';
import { styled, useTheme } from '@mui/material/styles';
import {
@ -256,14 +257,23 @@ const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
// Render desktop navigation with dropdowns
const renderDesktopNavigation = () => {
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
{navigationItems.map((item) => {
<Box sx={{ display: 'flex', width: "100%", alignItems: 'center', justifyContent: "space-between"}}>
{navigationItems.map((item, index) => {
const hasChildren = item.children && item.children.length > 0;
const isActive = isCurrentPath(item) || hasActiveChild(item);
// Default is centered for all menu items
let sx : SxProps = { justifycontent: "center"};
// First item ("Backstory") is left aligned
if (index === 0) {
sx = { marginRight: "auto" };
}
// If there is an Admin menu, it is on the far right
if (item.userTypes?.includes('admin')) {
sx = { marginLeft: "auto"};
}
if (hasChildren) {
return (
<Box key={item.id}>
<Box key={item.id} sx={sx}>
<DropdownButton
onClick={(e) => handleDropdownOpen(e, item.id)}
endIcon={<KeyboardArrowDown />}
@ -306,6 +316,7 @@ const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
sx={{
backgroundColor: isActive ? 'action.selected' : 'transparent',
color: isActive ? 'secondary.main' : 'primary.contrastText',
...sx
}}
>
{item.icon && <Box sx={{ mr: 1, display: 'flex' }}>{item.icon}</Box>}

View File

@ -45,7 +45,7 @@ const JobInfo: React.FC<JobInfoProps> = (props: JobInfoProps) => {
if (!job) {
return <Box>No user loaded.</Box>;
}
console.log(job);
return (
<Card
elevation={elevation}

View File

@ -60,8 +60,8 @@ const SettingsPage = () => (<BetaPage><Typography variant="h4">Settings</Typogra
export const navigationConfig: NavigationConfig = {
items: [
{ id: 'home', label: <BackstoryLogo />, path: '/', component: <HomePage />, userTypes: ['guest', 'candidate', 'employer'], exact: true, },
{ id: 'chat', label: 'Chat about a Candidate', path: '/chat', icon: <ChatIcon />, component: <CandidateChatPage />, userTypes: ['guest', 'candidate', 'employer',], },
{
{ id: 'job-analysis', label: 'Job Analysis', path: '/job-analysis', icon: <WorkIcon />, component: <JobAnalysisPage />, userTypes: ['guest', 'candidate', 'employer',], },
{ id: 'chat', label: 'Candidate Chat', path: '/chat', icon: <ChatIcon />, component: <CandidateChatPage />, userTypes: ['guest', 'candidate', 'employer',], }, {
id: 'candidate-menu', label: 'Tools', icon: <PersonIcon />, userTypes: ['candidate'], children: [
{ id: 'candidate-dashboard', label: 'Dashboard', path: '/candidate/dashboard', icon: <DashboardIcon />, component: <CandidateDashboard />, userTypes: ['candidate'] },
{ id: 'candidate-profile', label: 'Profile', icon: <PersonIcon />, path: '/candidate/profile', component: <CandidateProfile />, userTypes: ['candidate'] },

View File

@ -2,8 +2,8 @@
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 { formatApiRequest, toCamelCase } from '../types/conversion';
import { ApiClient, CreateCandidateRequest, CreateEmployerRequest, GuestConversionRequest } from 'services/api-client';
import { formatApiRequest, toCamelCase } from 'types/conversion';
// ============================
// Enhanced Types and Interfaces

View File

@ -196,7 +196,6 @@ class ApiClient {
const data = await response.json();
const apiResponse = parsePaginatedResponse<T>(data);
const extractedData = extractApiData(apiResponse);
console.log("extracted", extractedData);
// Apply model-specific date conversion to array items if modelType is provided
if (modelType && extractedData.data) {
return {

View File

@ -1,6 +1,6 @@
// Generated TypeScript types from Pydantic models
// Source: src/backend/models.py
// Generated on: 2025-06-09T15:19:57.985888
// Generated on: 2025-06-09T17:45:24.922154
// DO NOT EDIT MANUALLY - This file is auto-generated
// ============================
@ -426,13 +426,6 @@ export interface ChromaDBGetResponse {
umapEmbedding3D?: Array<number>;
}
export interface Citation {
text: string;
source: string;
context: string;
relevance: number;
}
export interface CreateCandidateRequest {
email: string;
username: string;
@ -699,11 +692,14 @@ export interface Job {
id?: string;
ownerId: string;
ownerType: "candidate" | "employer" | "guest";
owner?: BaseUser;
title?: string;
summary?: string;
company?: string;
description: string;
requirements?: JobRequirements;
createdAt: Date;
updatedAt: Date;
}
export interface JobApplication {
@ -726,11 +722,14 @@ export interface JobFull {
id?: string;
ownerId: string;
ownerType: "candidate" | "employer" | "guest";
owner?: BaseUser;
title?: string;
summary?: string;
company?: string;
description: string;
requirements?: JobRequirements;
createdAt: Date;
updatedAt: Date;
location: Location;
salaryRange?: SalaryRange;
employmentType: "full-time" | "part-time" | "contract" | "internship" | "freelance";
@ -1470,6 +1469,21 @@ export function convertInterviewScheduleFromApi(data: any): InterviewSchedule {
endDate: new Date(data.endDate),
};
}
/**
* Convert Job from API response, parsing date fields
* Date fields: createdAt, updatedAt
*/
export function convertJobFromApi(data: any): Job {
if (!data) return data;
return {
...data,
// Convert createdAt from ISO string to Date
createdAt: new Date(data.createdAt),
// Convert updatedAt from ISO string to Date
updatedAt: new Date(data.updatedAt),
};
}
/**
* Convert JobApplication from API response, parsing date fields
* Date fields: appliedDate, updatedDate
@ -1487,13 +1501,17 @@ export function convertJobApplicationFromApi(data: any): JobApplication {
}
/**
* Convert JobFull from API response, parsing date fields
* Date fields: datePosted, applicationDeadline, featuredUntil
* Date fields: createdAt, updatedAt, datePosted, applicationDeadline, featuredUntil
*/
export function convertJobFullFromApi(data: any): JobFull {
if (!data) return data;
return {
...data,
// Convert createdAt from ISO string to Date
createdAt: new Date(data.createdAt),
// Convert updatedAt from ISO string to Date
updatedAt: new Date(data.updatedAt),
// Convert datePosted from ISO string to Date
datePosted: new Date(data.datePosted),
// Convert applicationDeadline from ISO string to Date
@ -1688,6 +1706,8 @@ export function convertFromApi<T>(data: any, modelType: string): T {
return convertInterviewFeedbackFromApi(data) as T;
case 'InterviewSchedule':
return convertInterviewScheduleFromApi(data) as T;
case 'Job':
return convertJobFromApi(data) as T;
case 'JobApplication':
return convertJobApplicationFromApi(data) as T;
case 'JobFull':

View File

@ -28,7 +28,7 @@ class CandidateChat(Agent):
CandidateChat Agent
"""
agent_type: Literal["candidate_chat"] = "candidate_chat"
agent_type: Literal["candidate_chat"] = "candidate_chat" # type: ignore
_agent_type: ClassVar[str] = agent_type # Add this for registration
system_prompt: str = system_message

View File

@ -3236,6 +3236,7 @@ async def create_candidate_job(
# Add required fields
job.id = str(uuid.uuid4())
job.owner_id = current_user.id
job.owner = current_user
await database.set_job(job.id, job.model_dump())

View File

@ -683,11 +683,14 @@ class Job(BaseModel):
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
owner_id: str = Field(..., alias="ownerId")
owner_type: UserType = Field(..., alias="ownerType")
owner: Optional[BaseUser] = None
title: Optional[str]
summary: Optional[str]
company: Optional[str]
description: str
requirements: Optional[JobRequirements]
created_at: datetime = Field(..., alias="createdAt")
updated_at: datetime = Field(..., alias="updatedAt")
model_config = {
"populate_by_name": True # Allow both field names and aliases
}