Add Work Environment & Location designation (Remote, Hybrid, Onsite) across Profile, Autonomous Engine, and Job Feeds
This commit is contained in:
@@ -248,6 +248,38 @@ export const AutonomousEngine: React.FC<AutonomousEngineProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Preferred Locations & Work Type (Remote / Hybrid / Onsite) */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-slate-300 mb-1.5">Preferred Work Locations & Remote Status</label>
|
||||
<div className="flex items-center gap-3 text-xs mb-2">
|
||||
{['Remote', 'Hybrid', 'Onsite'].map((type) => {
|
||||
const workTypes = criteria.preferredWorkTypes || ['Remote', 'Hybrid'];
|
||||
const isSelected = workTypes.includes(type as any);
|
||||
return (
|
||||
<button
|
||||
key={type}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const updated = isSelected
|
||||
? workTypes.filter(t => t !== type)
|
||||
: [...workTypes, type as any];
|
||||
handleUpdateCriteria('preferredWorkTypes', updated);
|
||||
}}
|
||||
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-xl border text-xs font-medium transition ${
|
||||
isSelected
|
||||
? 'bg-indigo-950 border-indigo-500/50 text-indigo-300 font-bold'
|
||||
: 'bg-slate-950 border-slate-800 text-slate-400 hover:text-slate-200'
|
||||
}`}
|
||||
>
|
||||
<span className={`w-2 h-2 rounded-full ${isSelected ? 'bg-indigo-400' : 'bg-slate-600'}`}></span>
|
||||
<span>{type}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-[10px] text-slate-500">Designates work environment preferences for autonomous matching.</p>
|
||||
</div>
|
||||
|
||||
{/* Excluded Companies */}
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-slate-300 mb-1.5">Excluded / Blacklisted Companies</label>
|
||||
|
||||
@@ -27,6 +27,7 @@ export const JobFeeds: React.FC<JobFeedsProps> = ({
|
||||
}) => {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [selectedPlatform, setSelectedPlatform] = useState<string>('ALL');
|
||||
const [selectedWorkType, setSelectedWorkType] = useState<string>('ALL');
|
||||
const [minMatch, setMinMatch] = useState<number>(0);
|
||||
const [appliedFeedIds, setAppliedFeedIds] = useState<string[]>([]);
|
||||
const [isFetchingFeeds, setIsFetchingFeeds] = useState(false);
|
||||
@@ -43,7 +44,6 @@ export const JobFeeds: React.FC<JobFeedsProps> = ({
|
||||
|
||||
const filteredFeeds = displayFeeds.filter(feed => {
|
||||
const term = searchTerm.toLowerCase().trim();
|
||||
if (!term && selectedPlatform === 'ALL' && minMatch === 0) return true;
|
||||
|
||||
const titleMatch = (feed.title || '').toLowerCase().includes(term);
|
||||
const companyMatch = (feed.company || '').toLowerCase().includes(term);
|
||||
@@ -54,9 +54,22 @@ export const JobFeeds: React.FC<JobFeedsProps> = ({
|
||||
|
||||
const matchesSearch = !term || titleMatch || companyMatch || locationMatch || platformMatchStr || descMatch || skillsMatch;
|
||||
const matchesPlatform = selectedPlatform === 'ALL' || feed.platform === selectedPlatform;
|
||||
|
||||
// Work Type / Remote Status Filter
|
||||
const feedLoc = (feed.location || '').toLowerCase();
|
||||
const feedDesc = (feed.description || '').toLowerCase();
|
||||
let matchesWorkType = true;
|
||||
if (selectedWorkType === 'Remote') {
|
||||
matchesWorkType = feedLoc.includes('remote') || feedDesc.includes('remote');
|
||||
} else if (selectedWorkType === 'Hybrid') {
|
||||
matchesWorkType = feedLoc.includes('hybrid') || feedDesc.includes('hybrid');
|
||||
} else if (selectedWorkType === 'Onsite') {
|
||||
matchesWorkType = !feedLoc.includes('remote') && !feedDesc.includes('remote');
|
||||
}
|
||||
|
||||
const matchesMatch = (feed.estimatedMatch ?? 80) >= minMatch;
|
||||
|
||||
return matchesSearch && matchesPlatform && matchesMatch;
|
||||
return matchesSearch && matchesPlatform && matchesWorkType && matchesMatch;
|
||||
});
|
||||
|
||||
const handleFetchLiveFeeds = async () => {
|
||||
@@ -125,8 +138,22 @@ export const JobFeeds: React.FC<JobFeedsProps> = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Platform & Match Threshold */}
|
||||
<div className="flex items-center gap-3 text-xs">
|
||||
{/* Platform & Work Type & Match Threshold */}
|
||||
<div className="flex items-center flex-wrap gap-2.5 text-xs">
|
||||
|
||||
{/* Work Type Filter Dropdown */}
|
||||
<select
|
||||
value={selectedWorkType}
|
||||
onChange={(e) => setSelectedWorkType(e.target.value)}
|
||||
className="px-3 py-2 rounded-xl bg-slate-950 border border-slate-800 text-indigo-300 font-semibold text-xs focus:outline-none focus:border-indigo-500"
|
||||
>
|
||||
<option value="ALL">All Work Types (Remote/Onsite/Hybrid)</option>
|
||||
<option value="Remote">🌐 Remote Only</option>
|
||||
<option value="Hybrid">🏢 Hybrid Only</option>
|
||||
<option value="Onsite">📍 Onsite Only</option>
|
||||
</select>
|
||||
|
||||
{/* Platform Dropdown */}
|
||||
<select
|
||||
value={selectedPlatform}
|
||||
onChange={(e) => setSelectedPlatform(e.target.value)}
|
||||
@@ -154,14 +181,15 @@ export const JobFeeds: React.FC<JobFeedsProps> = ({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{(searchTerm || selectedPlatform !== 'ALL' || minMatch > 0) && (
|
||||
{(searchTerm || selectedPlatform !== 'ALL' || selectedWorkType !== 'ALL' || minMatch > 0) && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchTerm('');
|
||||
setSelectedPlatform('ALL');
|
||||
setSelectedWorkType('ALL');
|
||||
setMinMatch(0);
|
||||
}}
|
||||
className="px-3 py-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 text-xs font-semibold transition"
|
||||
className="px-3 py-2 rounded-xl bg-indigo-950 border border-indigo-500/40 text-indigo-300 text-xs font-semibold hover:bg-indigo-900 transition"
|
||||
>
|
||||
Reset Filters
|
||||
</button>
|
||||
|
||||
@@ -26,7 +26,8 @@ export const INITIAL_USER_PROFILE: UserProfile = {
|
||||
targetRoles: [],
|
||||
minMatchScore: 80,
|
||||
maxDailyApplications: 10,
|
||||
preferredLocations: [],
|
||||
preferredLocations: ["Remote US", "Connecticut", "New York"],
|
||||
preferredWorkTypes: ["Remote", "Hybrid"],
|
||||
minSalary: 100000,
|
||||
excludedCompanies: [],
|
||||
preferredPlatforms: ["LinkedIn", "Greenhouse", "Lever", "Workday", "Indeed", "Direct"]
|
||||
|
||||
@@ -121,6 +121,7 @@ export interface UserProfile {
|
||||
minMatchScore: number;
|
||||
maxDailyApplications: number;
|
||||
preferredLocations: string[];
|
||||
preferredWorkTypes?: ('Remote' | 'Onsite' | 'Hybrid')[];
|
||||
minSalary: number;
|
||||
excludedCompanies: string[];
|
||||
preferredPlatforms: PlatformType[];
|
||||
|
||||
Reference in New Issue
Block a user