diff --git a/src/components/CodingChallengeWrapper.tsx b/src/components/CodingChallengeWrapper.tsx index 88d047a..43691b3 100644 --- a/src/components/CodingChallengeWrapper.tsx +++ b/src/components/CodingChallengeWrapper.tsx @@ -28,6 +28,7 @@ const CodingChallengeWrapper: React.FC = ({ pattern ) : (
diff --git a/src/components/Instructions.css b/src/components/Instructions.css index bbfe1a4..c83f135 100644 --- a/src/components/Instructions.css +++ b/src/components/Instructions.css @@ -268,6 +268,17 @@ /* color: #a0aec0; */ } +.markdown-content a { + color: var(--primary); + text-decoration: underline; + text-underline-offset: 2px; + transition: opacity 0.2s ease; +} + +.markdown-content a:hover { + opacity: 0.8; +} + .instructions-footer { border-top: 1px solid #404040; padding: 16px 24px; diff --git a/src/components/Instructions.tsx b/src/components/Instructions.tsx index d63c151..0b56ec5 100644 --- a/src/components/Instructions.tsx +++ b/src/components/Instructions.tsx @@ -21,19 +21,41 @@ import { ScrollArea } from "@/components/ui/scroll-area"; interface InstructionsProps { readmes: ReadmeFile[]; onClose: () => void; + interviewId?: string; } -const Instructions: React.FC = ({ readmes, onClose }) => { - const [currentIndex, setCurrentIndex] = useState(0); +const STORAGE_KEY_PREFIX = "instructions-page-"; + +const Instructions: React.FC = ({ readmes, onClose, interviewId }) => { + // Initialize from localStorage if we have an interviewId + const [currentIndex, setCurrentIndex] = useState(() => { + if (interviewId) { + const saved = localStorage.getItem(`${STORAGE_KEY_PREFIX}${interviewId}`); + if (saved !== null) { + const parsed = parseInt(saved, 10); + // Validate the saved index is within bounds + if (!isNaN(parsed) && parsed >= 0 && parsed < readmes.length) { + return parsed; + } + } + } + return 0; + }); const [visibleTabs, setVisibleTabs] = useState([]); const [overflowTabs, setOverflowTabs] = useState([]); const [showTopShadow, setShowTopShadow] = useState(false); const [showBottomShadow, setShowBottomShadow] = useState(false); const tabsListRef = useRef(null); - const scrollAreaRef = useRef(null); const currentReadme = readmes[currentIndex]; + // Persist current page to localStorage + useEffect(() => { + if (interviewId) { + localStorage.setItem(`${STORAGE_KEY_PREFIX}${interviewId}`, currentIndex.toString()); + } + }, [currentIndex, interviewId]); + // Focus management for modal useEffect(() => { const firstTab = document.getElementById('tab-0'); @@ -274,6 +296,7 @@ const Instructions: React.FC = ({ readmes, onClose }) => { .replace(/^### (.*$)/gim, "

$1

") .replace(/\*\*(.*?)\*\*/g, "$1") .replace(/\*(.*?)\*/g, "$1") + .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1') .replace(/\n\n/g, "

"); // Restore inline code @@ -352,7 +375,6 @@ const Instructions: React.FC = ({ readmes, onClose }) => {

diff --git a/src/components/InterviewShell.tsx b/src/components/InterviewShell.tsx index 1b4f6e3..b142746 100644 --- a/src/components/InterviewShell.tsx +++ b/src/components/InterviewShell.tsx @@ -61,7 +61,7 @@ const ResizableSidebarContent: React.FC<{ {pattern.readmes ? ( - {}} /> + {}} interviewId={pattern.id} /> ) : null} @@ -85,6 +85,7 @@ const ResizableSidebarContent: React.FC<{ key={`instructions-${sidebarWidth}`} readmes={pattern.readmes} onClose={() => {}} + interviewId={pattern.id} /> ) : null} @@ -102,6 +103,8 @@ const ResizableSidebarContent: React.FC<{ ); }; +const SIDEBAR_OPEN_KEY_PREFIX = "sidebar-open-"; + const InterviewShell: React.FC = ({ pattern, onBack }) => { const [showInstructions, setShowInstructions] = useState(false); const [hasViewedInstructions, setHasViewedInstructions] = useState(false); @@ -110,6 +113,18 @@ const InterviewShell: React.FC = ({ pattern, onBack }) => { const sidebarRef = useRef(null); const isResizing = useRef(false); + // Sidebar open state persisted to localStorage + const [sidebarOpen, setSidebarOpen] = useState(() => { + const saved = localStorage.getItem(`${SIDEBAR_OPEN_KEY_PREFIX}${pattern.id}`); + // Default to open (true) if no saved state + return saved === null ? true : saved === "true"; + }); + + const handleSidebarOpenChange = (open: boolean) => { + setSidebarOpen(open); + localStorage.setItem(`${SIDEBAR_OPEN_KEY_PREFIX}${pattern.id}`, String(open)); + }; + // Resize functionality useEffect(() => { const handleMouseMove = (e: MouseEvent) => { @@ -194,7 +209,7 @@ const InterviewShell: React.FC = ({ pattern, onBack }) => {
- + = ({ pattern, onBack }) => { setShowInstructions(false)} + interviewId={pattern.id} /> ) : isCodingChallenge ? (