diff --git a/packages/shared/src/components/Logo.tsx b/packages/shared/src/components/Logo.tsx
index 9300a03418..b41f43097d 100644
--- a/packages/shared/src/components/Logo.tsx
+++ b/packages/shared/src/components/Logo.tsx
@@ -19,12 +19,6 @@ const DevPlusIcon = dynamic(() =>
),
);
-const LogoRecruiterSvg = dynamic(() =>
- import(
- /* webpackChunkName: "logoRecruiterSvg" */ '../svg/LogoRecruiterSvg'
- ).then((mod) => mod.LogoRecruiterSvg),
-);
-
export enum LogoPosition {
Absolute = 'absolute',
Relative = 'relative',
@@ -152,7 +146,11 @@ export default function Logo({
fallback={LogoText}
/>
)}
- {isRecruiter && !compact && }
+ {isRecruiter && !compact && (
+
+ Recruiter
+
+ )}
);
diff --git a/packages/shared/src/components/recruiter/AnalyzeStatusBar.tsx b/packages/shared/src/components/recruiter/AnalyzeStatusBar.tsx
index 79457b7c85..77f256e157 100644
--- a/packages/shared/src/components/recruiter/AnalyzeStatusBar.tsx
+++ b/packages/shared/src/components/recruiter/AnalyzeStatusBar.tsx
@@ -12,11 +12,11 @@ import { IconSize } from '../Icon';
const LOADING_STEPS = [
'Analyzing your job description (this may take a minute)',
- 'Mapping skills, requirements, and intent',
- 'Scanning the daily.dev network...',
+ 'Extracting skills and requirements',
+ 'Finding matches in our community...',
];
-const COMPLETE_MESSAGE = 'Your hiring edge is ready';
+const COMPLETE_MESSAGE = 'Your analysis is ready';
type AnalyzeStatusBarProps = {
loadingStep: number;
diff --git a/packages/shared/src/components/recruiter/Header.tsx b/packages/shared/src/components/recruiter/Header.tsx
index a7a82458b9..c42eedd8c3 100644
--- a/packages/shared/src/components/recruiter/Header.tsx
+++ b/packages/shared/src/components/recruiter/Header.tsx
@@ -24,8 +24,8 @@ export interface RecruiterHeaderProps {
}
export const RecruiterHeader = ({
- title = 'Your potential reach',
- subtitle = "See how many developers match your role and what they're interested in.",
+ title = 'Reach analysis',
+ subtitle = 'See who in our community fits your role',
headerButton,
}: RecruiterHeaderProps) => {
return (
diff --git a/packages/shared/src/features/opportunity/components/analyze/AnalyzeContent.tsx b/packages/shared/src/features/opportunity/components/analyze/AnalyzeContent.tsx
index 4e5431f175..02741a3b4a 100644
--- a/packages/shared/src/features/opportunity/components/analyze/AnalyzeContent.tsx
+++ b/packages/shared/src/features/opportunity/components/analyze/AnalyzeContent.tsx
@@ -7,10 +7,7 @@ import {
import { useOpportunityPreviewContext } from '../../context/OpportunityPreviewContext';
import { OpportunityPreviewStatus } from '../../types';
import { JobInfo } from './JobInfo';
-import { apiUrl } from '../../../../lib/config';
import { ReachHeroSection } from './ReachHeroSection';
-import { InsightCard } from './InsightCard';
-import { Chip } from '../../../../components/cards/common/PostTags';
import { PlusUserIcon } from '../../../../components/icons/PlusUser';
import { IconSize } from '../../../../components/Icon';
@@ -18,21 +15,12 @@ type AnalyzeContentProps = {
loadingStep: number;
};
-const iconSize = 24;
-
export const AnalyzeContent = ({ loadingStep }: AnalyzeContentProps) => {
const data = useOpportunityPreviewContext();
const isReady = data?.result?.status === OpportunityPreviewStatus.READY;
const totalCount = data?.result?.totalCount ?? 0;
- const tags = data?.result?.tags ?? [];
- const companies = data?.result?.companies ?? [];
-
- // Mock engagement stat - in production this would come from the API
- const avgTimePerWeek = '4.2 hrs';
const isError = data?.result?.status === OpportunityPreviewStatus.ERROR;
- const showAggregation =
- !isError && loadingStep >= 2 && (isReady || tags.length > 0);
const showReachHero = !isError && loadingStep >= 2;
return (
@@ -60,71 +48,6 @@ export const AnalyzeContent = ({ loadingStep }: AnalyzeContentProps) => {
)}
- {/* Candidate Insights */}
- {showAggregation && (
-
- {/* Tags */}
-
-
- {tags.map((tag) => (
-
- #{tag}
-
- ))}
-
-
-
- {/* Companies */}
-
-
- {companies.slice(0, 4).map((company) => (
-
-
- {company.name}
-
- ))}
-
-
-
- {/* Platform Engagement */}
-
-
-
- {avgTimePerWeek}
-
-
- avg. per candidate
-
-
-
-
- )}
-
{/* Job Summary */}
= {
+ [LocationType.UNSPECIFIED]: null,
+ [LocationType.REMOTE]: 'Remote',
+ [LocationType.OFFICE]: 'On-site',
+ [LocationType.HYBRID]: 'Hybrid',
+};
+
+const salaryPeriodMap: Record = {
+ [SalaryPeriod.UNSPECIFIED]: 'year',
+ [SalaryPeriod.ANNUAL]: 'year',
+ [SalaryPeriod.MONTHLY]: 'month',
+ [SalaryPeriod.WEEKLY]: 'week',
+ [SalaryPeriod.DAILY]: 'day',
+ [SalaryPeriod.HOURLY]: 'hour',
+};
+
+const formatSalary = (salary?: Salary): string | null => {
+ if (!salary?.min || !salary?.max) {
+ return null;
+ }
+ const min = salary.min / 1000;
+ const max = salary.max / 1000;
+ const period = salaryPeriodMap[salary.period ?? SalaryPeriod.UNSPECIFIED];
+ return `$${min}k - $${max}k/${period}`;
+};
type JobInfoProps = {
loadingStep: number;
@@ -33,8 +61,10 @@ export const JobInfo = ({ loadingStep }: JobInfoProps) => {
);
}
+ const { locations, meta, title, tldr, keywords } = opportunity;
+
const locationString =
- opportunity.locations
+ locations
?.map((item) =>
[
item.location?.city,
@@ -44,51 +74,68 @@ export const JobInfo = ({ loadingStep }: JobInfoProps) => {
.filter(Boolean)
.join(', '),
)
- .join(' · ') || 'Location not specified';
+ .join(' · ') || null;
const seniorityLabel =
- seniorityLevelMap[
- opportunity.meta?.seniorityLevel ?? SeniorityLevel.UNSPECIFIED
- ];
+ seniorityLevelMap[meta?.seniorityLevel ?? SeniorityLevel.UNSPECIFIED];
+
+ const workArrangement =
+ locationTypeMap[locations?.[0]?.type ?? LocationType.UNSPECIFIED];
+
+ const salaryRange = formatSalary(meta?.salary);
+
+ // Build meta items array for clean rendering
+ const metaItems = [
+ locationString,
+ seniorityLabel !== 'N/A' ? seniorityLabel : null,
+ workArrangement,
+ salaryRange,
+ ].filter(Boolean);
return (
{/* Title and meta */}
- {opportunity.title}
+ {title}
-
-
- {locationString}
-
- {seniorityLabel && (
- <>
- ·
-
- {seniorityLabel}
-
- >
- )}
-
+ {metaItems.length > 0 && (
+
+ {metaItems.map((item, index) => (
+
+ {index > 0 && ·}
+
+ {item}
+
+
+ ))}
+
+ )}
+ {/* TLDR */}
+ {tldr && (
+
+ TLDR {tldr}
+
+ )}
+
{/* Tech stack */}
- {opportunity.keywords && opportunity.keywords.length > 0 && (
+ {keywords && keywords.length > 0 && (
- {opportunity.keywords.slice(0, 10).map((tag) => (
+ {keywords.slice(0, 10).map((tag) => (
#{tag.keyword}
))}
- {opportunity.keywords.length > 10 && (
- +{opportunity.keywords.length - 10}
+ {keywords.length > 10 && (
+ +{keywords.length - 10}
)}
)}
diff --git a/packages/shared/src/features/opportunity/components/analyze/ReachHeroSection.tsx b/packages/shared/src/features/opportunity/components/analyze/ReachHeroSection.tsx
index 532357ed27..58bd2d199c 100644
--- a/packages/shared/src/features/opportunity/components/analyze/ReachHeroSection.tsx
+++ b/packages/shared/src/features/opportunity/components/analyze/ReachHeroSection.tsx
@@ -11,8 +11,6 @@ type ReachHeroSectionProps = {
isLoading: boolean;
};
-const PASSIVE_PERCENTAGE = 30;
-
export const ReachHeroSection = ({
totalCount,
isLoading,
@@ -58,6 +56,13 @@ export const ReachHeroSection = ({
return (
+ {/* Label */}
+
+ Potential reach
+
{/* Hero number */}
{animatedCount.toLocaleString()}
@@ -65,22 +70,18 @@ export const ReachHeroSection = ({
developers matched
- {/* Exclusive stat */}
+ {/* Community differentiator */}
-
- {PASSIVE_PERCENTAGE}%
- {' '}
- are passively open to new opportunities
+ Active in our community
diff --git a/packages/shared/src/svg/LogoRecruiterSvg.tsx b/packages/shared/src/svg/LogoRecruiterSvg.tsx
deleted file mode 100644
index 0493e59b39..0000000000
--- a/packages/shared/src/svg/LogoRecruiterSvg.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import type { ReactElement } from 'react';
-import React from 'react';
-
-export type LogoRecruiterProps = {
- className?: {
- container?: string;
- };
-};
-
-export const LogoRecruiterSvg = ({
- className,
-}: LogoRecruiterProps): ReactElement => {
- return (
-
- );
-};