Frontend Fixes & Enhancements — 8 April 2026
This document covers all bug fixes, UI improvements, and new features implemented on 8 April 2026 across 32 files.
1. Kanban Card Blur on Drag
Problem: Clicking/dragging a job card in the Jobs Kanban board caused the card to appear visually blurred.
Root cause: backdrop-blur-sm on the SelectBox component created a GPU compositing layer that produced rendering artifacts when combined with the drag state's opacity-50 + rotate + scale transitions.
Fix:
- Removed
backdrop-blur-smfromSelectBox(opaquebg-gray-50background made it invisible anyway) - Narrowed
transition-alltotransition-[opacity,transform,border]onKanbanJobCardAdapterto prevent unintended property transitions
Files: components/ux/TWResponsiveCard/blocks/header/SelectBox.tsx, components/ux/KanbanJobCardAdapter.tsx
2. Due Date Past Date Validation
Problem: The system accepted past dates when editing a job's due date (e.g., setting due date to yesterday).
Fix: Added minDate prop to the TWDatepicker component:
- Calendar days before
minDateare greyed out and unclickable - Validation on confirm button prevents setting dates before minimum
- Manual text input is also validated
- Applied
minDate={today}to the job form's Due Date field
Files: components/ux/TWDatepicker.tsx, components/jobs/JobRequirementsForm.tsx
3. Candidate "Applied" Date Showing N/A
Problem: The candidate card in the job pipeline Kanban showed "N/A" for the Applied date.
Root cause: The card config used source: "applied" but useJobCandidates provides the field as matchDate.
Fix: Changed source: "applied" to source: "matchDate" in the candidate card config.
File: components/ux/TWResponsiveCard/cardBuilder/configs/candidateConfig.ts
4. Company Logo Showing "?" Instead of Initials
Problem: When a company had no logo image, a purple circle with "?" appeared instead of the company name initials.
Root cause: resolveAvatarUrl() was called without the name parameter. When no image URL exists and no name is provided, the function falls back to ? in the generated avatar URL.
Fix: Added the company/user name as the second argument to resolveAvatarUrl() across all affected pages:
- Job detail page (company logo, contact avatar, talent picker modal)
- Visitor job page
- Jobseeker application page
- Jobseeker job detail page
Files: app/company/jobs/[jobId]/page.tsx, app/(visitor)/jobs/[jobId]/page.tsx, app/jobseeker/application/page.tsx, app/jobseeker/jobs/[jobId]/page.tsx
5. Recommended Talents Score Display (100x Too Large)
Problem: Match scores on the Recommended tab showed values like 5113, 4961, 5000 instead of 51, 50, 50.
Root cause: The backend returns scores as 0–100, but the hook multiplied by 100 again (score * 100).
Fix: Removed the erroneous * 100 multiplication in useRecommendedTalents.
File: lib/hooks/jobs/useRecommendedTalents.ts
6. Score Widget on Candidates List Page
Problem: The /company/resume/candidates page had no match score displayed on candidate cards.
Fix:
- Added async score fetching using
GET_USER_JOB_MATCH_SCOREper candidate (same pattern as the pipeline view) - Added
scoreandjobIdfields toCandidateRowtype and builders - Added score widget to the resume candidate card profile block config
- Scores load from Apollo cache first (cache-first policy) and don't block page rendering
Files: app/company/resume/candidates/page.tsx, components/ux/TWResponsiveCard/cardBuilder/configs/resumeCandidateConfig.ts, lib/utils/candidates/candidateRowBuilder.ts
7. "Due in -8 days" Overdue Display
Problem: The job detail page header showed "Due in -8 days" for overdue jobs.
Fix: Contextual display:
- Negative days: "Overdue by X days" (red text)
- Zero days: "Due today"
- 1-7 days: amber warning color
- 8+ days: default color
File: app/company/jobs/[jobId]/page.tsx
8. Recommended Talents Card Overhaul
Problem: Recommended talent cards showed irrelevant information (status selector, "Handled by" name on every card, "Talent Pool Match" tag, edit/delete menu) and looked flat.
Changes:
- Removed: Empty header block (eliminated blank space at top), status selector (NEW badge was wrong), edit/delete/download menu, "Handled by" info, "Applied" date, "Talent Pool Match" tag
- Added: "Add as Candidate" footer button wired to
addTalentAsCandidatemutation, email (clickable mailto), phone (clickable tel), top 5 skills from CV - Added
addCandidateaction to the action configs registry
Files: components/ux/TWResponsiveCard/cardBuilder/configs/recommendedTalentsConfig.ts, lib/hooks/jobs/useRecommendedTalents.ts, components/ux/TWResponsiveCard/cardBuilder/actions/actionConfigs.tsx, app/company/jobs/[jobId]/page.tsx
9. Dropzone MIME Type Warnings
Problem: Browser console showed warnings: Skipped ".csv" because it is not a valid MIME type for every file extension in the accept prop.
Root cause: The Dropzone component passed file extensions (.pdf, .csv) directly as keys to react-dropzone's accept prop, which expects MIME types.
Fix: Added an EXT_TO_MIME mapping and parseAccept() function that converts extensions to proper MIME types (e.g., .pdf → application/pdf, .csv → text/csv).
File: components/reusable/Dropzone.tsx
10. Agent Document Upload — 0 Bytes Size
Problem: Uploaded agent documents showed "0 B" file size.
Root cause: file.size was logged but never included in the uploadAgentDocument mutation input.
Fix: Added sizeBytes: file.size to the mutation input object.
File: lib/hooks/useAgentDocuments.ts
11. Document Card — Upload Date Display
Problem: No way to see when a document was uploaded.
Fix: Added formatted upload date with calendar icon next to the file size on each document card.
Note: "Uploaded by" is not available — the backend's AgentDocument type doesn't expose an uploadedBy field. The uploadedById is sent during upload but not returned on queries. This requires a backend change.
File: components/company/ai-agent/DocumentCard.tsx
12. Book Interview Modal — End Time Fix
Problem: The end time field was a static read-only display (<div>) that didn't align with the "From" dropdown and couldn't be changed by the user. Duration was fixed and didn't update.
Fix:
- Replaced static
<div>with an editableTWSelectdropdown (proper alignment) - End time options filtered to only show times after the selected start time
- Bidirectional sync: changing duration updates end time, changing end time updates duration
File: app/company/resume/candidates/_components/modals/BookInterviewModal.tsx
13. Save as Draft Job Posting
Problem: "Save as Draft" button created jobs with status "NEW" instead of "DRAFT".
Root cause: handleSaveAsDraft called buildJobInput with { publishedOnline: false } but didn't override the status, which defaulted to "NEW".
Fix: Added status: "DRAFT" to the overrides: buildJobInput(resolvedSkills, { publishedOnline: false, status: "DRAFT" }).
File: components/reusable/jobs/CreateJob.tsx
14. Draft Status in Kanban Board
Problem: Draft jobs had no dedicated column in the Kanban board — they were mapped to "New".
Fix:
- Added
DRAFTtoPipelineItemStatusunion type - Added
DRAFTtoDEFAULT_PIPELINE_STATUSES(first position, before NEW) - Fixed status mapping:
DRAFT → DRAFT(wasDRAFT → NEW) - Added Draft column to KanbanBoard default columns
- Added Draft option to card status selector dropdowns
- Added
EditIconfor Draft column visibility filter on jobs page
Files: lib/types/kanban.ts, lib/types/pipeline.ts, lib/utils/pipeline.ts, components/ux/KanbanBoard.tsx, components/ux/KanbanJobCardAdapter.tsx, app/company/jobs/page.tsx
15. Inline Edit Duplication Bug (Critical Fix)
Problem: Inline editing any field (title, location, year, etc.) on certifications, experiences, or education cards on the talent view page (/company/resume/talents/[id]) caused the edited item to be duplicated — both the old and new version appeared.
Root cause: The useInlineResumeEdit hook's edit handlers (handleCertificateEdit, handleExperienceEdit, handleEducationEdit) replaced the array item with the updated object from the card's onEdit callback. But the card component types (Certificate, Experience, Education from lib/types/qualifications.ts) don't include _structuredId. So the replacement item lost its _structuredId.
When saveStructuredCv ran its diff to determine which mutations to call, items without _structuredId were treated as new items → ADD mutation was called instead of UPDATE → backend created a new record while keeping the old one → duplication.
Fix: All three edit handlers in useInlineResumeEdit.ts now preserve _structuredId from the original array item before replacing with the updated data:
const original = certificates[index] as Record<string, unknown> | undefined
const structuredId = original?._structuredId
certificates[index] = structuredId
? { ...updated, _structuredId: structuredId } as Certificate
: updated
File: app/company/resume/candidates/_components/utils/useInlineResumeEdit.ts
16. Certification Location Not Preserved in CV Builder
Problem: Editing a certification's location through the CV builder / ProfileForm path dropped the location field.
Root cause: The converter functions cvBuilderCertToOnboarding and onboardingCertToCVBuilder in ProfileForm.tsx didn't include the location field — only title, year, and institute were mapped.
Fix: Added location to both converter functions.
File: components/cv/ProfileForm.tsx
17. Inline Edit Double-Fire Guard
Problem: Clicking the "Done" button while a text input was focused caused handleDone to fire twice — once from the input's onBlur and once from the button's onClick. This could cause state inconsistencies.
Fix: Added guard if (editingField === null) return at the top of handleDone and handleFieldDone in all three qualification card components. The second call is a no-op since the first already set editingField to null.
Files: components/reusable/qualifications/CertificateCard.tsx, EducationCard.tsx, ExperienceCard.tsx
18. TWSelect defaultOpen Prop
Problem: Location fields in qualification cards required two clicks — one to enter edit mode (swap text for dropdown), another to open the dropdown.
Fix: Added defaultOpen prop to TWSelect and TWLocationAutocomplete. When defaultOpen is true, the dropdown opens automatically after mount via requestAnimationFrame (delayed to avoid the original mousedown triggering click-outside). Location fields in qualification cards changed from fixed w-64 to flex-1 min-w-0 for proper width.
Note: defaultOpen is currently not applied to the qualification cards (reverted to avoid interaction issues). The prop is available for future use.
Files: components/ux/TWSelect.tsx, components/ux/TWLocationAutocomplete.tsx, components/reusable/qualifications/CertificateCard.tsx, EducationCard.tsx, ExperienceCard.tsx
Files Changed Summary
| # | File | Changes |
|---|---|---|
| 1 | components/ux/TWResponsiveCard/blocks/header/SelectBox.tsx | Remove backdrop-blur-sm |
| 2 | components/ux/KanbanJobCardAdapter.tsx | Narrow transitions, add DRAFT status |
| 3 | components/ux/TWDatepicker.tsx | Add minDate prop with calendar/input validation |
| 4 | components/jobs/JobRequirementsForm.tsx | Apply minDate to due date field |
| 5 | components/ux/TWResponsiveCard/cardBuilder/configs/candidateConfig.ts | Fix applied date field mapping |
| 6 | components/ux/TWResponsiveCard/cardBuilder/configs/resumeCandidateConfig.ts | Add score widget |
| 7 | components/ux/TWResponsiveCard/cardBuilder/configs/recommendedTalentsConfig.ts | Full card overhaul |
| 8 | components/ux/TWResponsiveCard/cardBuilder/actions/actionConfigs.tsx | Add addCandidate action |
| 9 | components/reusable/Dropzone.tsx | Fix MIME type mapping |
| 10 | components/reusable/jobs/CreateJob.tsx | Fix draft status |
| 11 | components/company/ai-agent/DocumentCard.tsx | Add upload date |
| 12 | components/ux/KanbanBoard.tsx | Add Draft column |
| 13 | app/company/jobs/page.tsx | Add Draft icon/label |
| 14 | app/company/jobs/[jobId]/page.tsx | Fix avatars, overdue display, recommended grid |
| 15 | app/company/resume/candidates/page.tsx | Add score fetching |
| 16 | app/company/resume/candidates/_components/modals/BookInterviewModal.tsx | Fix end time |
| 17 | app/(visitor)/jobs/[jobId]/page.tsx | Fix company logo avatar |
| 18 | app/jobseeker/application/page.tsx | Fix company logo avatar |
| 19 | app/jobseeker/jobs/[jobId]/page.tsx | Fix company logo avatar |
| 20 | lib/hooks/jobs/useRecommendedTalents.ts | Fix score, add email/phone/skills |
| 21 | lib/hooks/useAgentDocuments.ts | Add sizeBytes to mutation |
| 22 | lib/utils/candidates/candidateRowBuilder.ts | Add score/jobId fields |
| 23 | lib/utils/pipeline.ts | Fix DRAFT mapping |
| 24 | lib/types/kanban.ts | Add DRAFT to type |
| 25 | lib/types/pipeline.ts | Add DRAFT to defaults |
| 26 | app/company/resume/candidates/_components/utils/useInlineResumeEdit.ts | Preserve _structuredId on inline edit |
| 27 | components/cv/ProfileForm.tsx | Add location to cert converters |
| 28 | components/reusable/qualifications/CertificateCard.tsx | Guard double-fire, flex location |
| 29 | components/reusable/qualifications/EducationCard.tsx | Guard double-fire, flex location |
| 30 | components/reusable/qualifications/ExperienceCard.tsx | Guard double-fire, flex location |
| 31 | components/ux/TWSelect.tsx | Add defaultOpen prop |
| 32 | components/ux/TWLocationAutocomplete.tsx | Pass defaultOpen to TWSelect |