position ui and owliver update

This commit is contained in:
2026-08-14 01:18:59 +05:30
parent 1c653264b5
commit cccada9bd2
29 changed files with 3718 additions and 1313 deletions

View File

@@ -1,7 +1,12 @@
import React, { useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useJobPosting, useApplications, useScreenAllCandidates, useUpdateJobPosting, useHireCandidate, useUpdateApplication, useCreateApplication, useWorkerProfiles, useCourses, useAssignments, useStaff } from '@/lib/krowHooks';
import { demandLabel } from '@/lib/positionModel';
import {
customRequirementsText, demandLabel, hasRequirements, payLabel,
} from '@/lib/positionModel';
import {
PositionCustomRequirements, PositionOverview, PositionRequirements,
} from '@/components/krow/PositionDetails';
import { workforceStatusFor } from '@/lib/workforce';
import { MatchedCandidates } from '@/components/krow/MatchedCandidates';
import { base44 } from '@/api/base44Client';
@@ -283,12 +288,15 @@ export default function PositionDetail() {
<div className="bg-white border border-[#E5E7EB] rounded-2xl p-6">
<div className="flex items-start justify-between gap-4 flex-wrap">
<div className="flex-1 min-w-0">
{/* Company leads: on a workforce page the client asking for the
people is as much the identity of the role as its title — above
it rather than fused into it, so the stored job title is always
read as the title. */}
{job.company && (
<p className="text-[11px] font-semibold uppercase tracking-wide text-[#0838E0]">{job.company}</p>
)}
<div className="flex items-center gap-2 mb-1">
{/* Company leads: on a workforce page the client asking for the
people is as much the identity of the role as its title. */}
<h1 className="text-[22px] font-bold text-[#111827]">
{job.company ? `${job.company} — ${job.title}` : job.title}
</h1>
<h1 className="text-[22px] font-bold text-[#111827]">{job.title}</h1>
{job.priority && job.priority !== 'normal' && (
<span className={cn(
'px-2 py-0.5 rounded-full text-[11px] font-bold capitalize',
@@ -308,7 +316,7 @@ export default function PositionDetail() {
<div className="flex items-center gap-4 text-[13px] text-[#6B7280] flex-wrap">
<span className="capitalize">{job.role_category}</span>
{job.location && <span>{job.location}</span>}
{job.pay_range_min != null && <span className="font-medium text-[#111827]">${job.pay_range_min}–{job.pay_range_max}/hr</span>}
{payLabel(job) && <span className="font-medium text-[#111827]">{payLabel(job)}</span>}
</div>
</div>
@@ -378,6 +386,30 @@ export default function PositionDetail() {
)}
</div>
{/* Everything Create Position collected about the role itself. The same
two components the Positions drawer renders, so the page and the panel
state the record identically. */}
<div className="bg-white border border-[#E5E7EB] rounded-2xl p-6 space-y-5">
<div>
<h2 className="text-[15px] font-bold text-[#111827]">Position details</h2>
<p className="text-[12px] text-[#6B7280] mt-0.5">The role as it was defined when this position was created.</p>
</div>
<PositionOverview position={job} />
{/* Role-specific, so present only when this role states them. */}
{hasRequirements(job) && (
<div>
<h3 className="text-[11px] font-bold uppercase tracking-wide text-[#9CA3AF] mb-2">Requirements</h3>
<PositionRequirements position={job} />
</div>
)}
{customRequirementsText(job) && (
<div>
<h3 className="text-[11px] font-bold uppercase tracking-wide text-[#9CA3AF] mb-2">Custom requirements</h3>
<PositionCustomRequirements position={job} />
</div>
)}
</div>
<WorkforceStatus workforce={workforce} job={job} />
{/* Which people can actually do this work, scored against the position's