/**
* Interview Mode Selector
*
* FOUR MODES ONLY:
* 1. Friendly - Database questions only
* 2. Balanced - API + video
* 3. Strict - RAG + verdicts
* 4. Final Boss - Full power + personality selection
*
* This component enforces the 4-mode architecture.
* Personality selection only appears for Final Boss mode.
*
* NOTE: All modes currently UNLOCKED. Payment integration pending.
*/
import React, { useState, useEffect } from 'react';
import { ChevronDown, Check, Lock, Zap, Crown, Skull, Video, Scale, Brain, User, Sparkles, Map } from 'lucide-react';
import {
INTERVIEW_MODES,
getInterviewModeList,
FINAL_BOSS_PERSONALITIES,
getFinalBossPersonalityList,
modeAllowsPersonality
} from '../services/scoringService';
// Mode tier badges (visual only - all modes unlocked)
const TIER_BADGES = {
free: { label: 'Free', color: '#10b981', icon: null },
paid_entry: { label: 'Basic', color: '#3b82f6', icon: },
paid_advanced: { label: 'Advanced', color: '#f59e0b', icon: },
premium: { label: 'Premium', color: '#ef4444', icon: },
};
// Feature configs with colors and icons
const FEATURE_CONFIG = {
video: { label: 'Video', icon: Video, color: '#3b82f6' },
verdict: { label: 'Verdict', icon: Scale, color: '#8b5cf6' },
rag: { label: 'RAG', icon: Brain, color: '#f59e0b' },
persona: { label: 'Persona', icon: User, color: '#ef4444' },
llm: { label: 'LLM', icon: Sparkles, color: '#22d3ee' },
roadmap: { label: 'Roadmap', icon: Map, color: '#a855f7' },
};
/**
* Main Mode Card Component
*/
function ModeCard({ mode, isSelected, onSelect, disabled, userTier = 'premium', isDark }) {
const tierInfo = TIER_BADGES[mode.tier] || TIER_BADGES.free;
// Check if user can access this mode
const tierOrder = ['free', 'paid_entry', 'paid_advanced', 'premium'];
const userTierIndex = tierOrder.indexOf(userTier);
const requiredTierIndex = tierOrder.indexOf(mode.tier);
const canAccess = userTierIndex >= requiredTierIndex;
const isLocked = !canAccess;
// Dark mode colors
const cardBg = isDark ? '#1e293b' : '#ffffff';
const cardBorder = isDark ? '#475569' : '#e2e8f0';
const textPrimary = isDark ? '#ffffff' : '#1e293b';
const textSecondary = isDark ? '#cbd5e1' : '#64748b';
return (
!disabled && !isLocked && onSelect(mode.id)}
style={{
'--mode-color': mode.color,
background: isSelected
? (isDark
? `linear-gradient(145deg, rgba(30, 41, 59, 0.95), rgba(15, 23, 42, 0.9))`
: `linear-gradient(145deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.95))`)
: (isDark
? 'linear-gradient(145deg, rgba(30, 41, 59, 0.8), rgba(15, 23, 42, 0.7))'
: 'linear-gradient(145deg, rgba(255, 255, 255, 0.9), rgba(248, 250, 252, 0.85))'),
backdropFilter: 'blur(20px)',
WebkitBackdropFilter: 'blur(20px)',
borderColor: isSelected ? mode.color : (isDark ? 'rgba(148, 163, 184, 0.15)' : 'rgba(203, 213, 225, 0.5)'),
borderWidth: isSelected ? '2px' : '1px',
boxShadow: isSelected
? `0 8px 32px ${mode.color}30, 0 4px 16px rgba(0, 0, 0, 0.15), inset 0 1px 0 ${isDark ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.9)'}`
: `0 4px 20px rgba(0, 0, 0, ${isDark ? '0.25' : '0.08'}), inset 0 1px 0 ${isDark ? 'rgba(255,255,255,0.05)' : 'rgba(255,255,255,0.7)'}`,
transform: isSelected ? 'scale(1.02)' : 'scale(1)',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
}}
>
{mode.icon}
{tierInfo.icon}
{tierInfo.label}
{mode.name}
{mode.description}
{mode.config.usesLLM && (
LLM
)}
{mode.config.hasVideo && (
Video
)}
{mode.config.hasVerdict && (
Verdict
)}
{mode.config.hasRag && (
RAG
)}
{mode.config.hasPersonalitySelection && (
Persona
)}
{mode.config.hasRoadmap && (
Roadmap
)}
{isSelected && !isLocked && (
)}
{isLocked && (
Upgrade to {tierInfo.label}
)}
);
}
/**
* Final Boss Personality Selector
* Only shown when mode = 'final_boss'
*/
function FinalBossPersonalitySelector({ value, onChange, disabled }) {
const [isOpen, setIsOpen] = useState(false);
const personalities = getFinalBossPersonalityList();
const selected = FINAL_BOSS_PERSONALITIES[value] || FINAL_BOSS_PERSONALITIES.faang_engineer;
return (
Choose your interviewer persona for maximum challenge
{isOpen && (
<>
setIsOpen(false)} />
{personalities.map((persona) => (
))}
>
)}
);
}
/**
* Main Interview Mode Selector Component
*/
function InterviewModeSelector({
mode = 'friendly',
onModeChange,
personality = 'faang_engineer',
onPersonalityChange,
disabled = false,
userTier = 'premium' // All modes unlocked - payment integration pending
}) {
const modes = getInterviewModeList();
const showPersonalitySelector = modeAllowsPersonality(mode);
// Detect dark mode
const [isDark, setIsDark] = useState(() => {
// Initialize from current theme
if (typeof document !== 'undefined') {
return document.documentElement.getAttribute('data-theme') === 'dark';
}
return false;
});
useEffect(() => {
if (typeof document === 'undefined') return;
const checkTheme = () => {
try {
const theme = document.documentElement.getAttribute('data-theme');
setIsDark(theme === 'dark');
} catch (e) {
console.warn('Theme check error:', e);
}
};
checkTheme();
// Watch for theme changes
let observer = null;
try {
observer = new MutationObserver(checkTheme);
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
} catch (e) {
console.warn('MutationObserver error:', e);
}
return () => {
if (observer) observer.disconnect();
};
}, []);
// Theme-aware colors
const headerColor = isDark ? '#ffffff' : '#1e293b';
const subheaderColor = isDark ? '#94a3b8' : '#64748b';
return (
Choose Interview Mode
Select the interview difficulty and style that matches your preparation level
{modes.map((m) => (
))}
{/* Final Boss Personality Sub-Selector */}
{showPersonalitySelector && (
)}
);
}
export default InterviewModeSelector;