Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ config.yaml
past/

# Private interview template content
frontend/src/util/reactTemplateContent.ts
frontend/src/util/reactTemplateContent.ts

tmp/
CLAUDE.md
6 changes: 3 additions & 3 deletions frontend/src/components/home/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ function HomePage() {
/>

<div className={`min-h-screen ${isDark ? 'bg-slate-900 text-white' : 'bg-gray-100 text-gray-900'}`}>
<h1 className='text-4xl font-bold text-center pt-20'>welcome to goderpad</h1>
<h3 className='text-xl text-center pt-4'>sce's interview platform</h3>
<div className='flex flex-row gap-30 justify-center mt-20'>
<h1 className='text-4xl font-bold text-center pt-10 sm:pt-20 px-8'>welcome to goderpad</h1>
<h3 className='text-xl text-center pt-4 px-8'>sce's interview platform</h3>
<div className='flex flex-row gap-30 justify-center mt-8 sm:mt-20 px-8 sm:px-6'>
<div className='flex flex-col gap-6 w-full max-w-md mx-auto'>
<h2 className='text-3xl font-semibold mb-2 text-center'>create an interview room</h2>

Expand Down
61 changes: 52 additions & 9 deletions frontend/src/components/room/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ function CodeEditor({ code, setCode, ws, roomId, interviewType, users }: CodeEdi
const [debouncedCode, setDebouncedCode] = useState(code);
const [leftPercent, setLeftPercent] = useState(50);
const [isDragging, setIsDragging] = useState(false);
const [isMobile, setIsMobile] = useState(false);
const [mobilePreviewOpen, setMobilePreviewOpen] = useState(false);
const isDraggingRef = useRef(false);
const containerRef = useRef<HTMLDivElement>(null);
const decorationsRef = useRef<string[]>([]);
Expand Down Expand Up @@ -212,6 +214,14 @@ function CodeEditor({ code, setCode, ws, roomId, interviewType, users }: CodeEdi
setIsDragging(true);
}, []);

useEffect(() => {
const mql = window.matchMedia('(max-width: 767px)');
const update = () => setIsMobile(mql.matches);
update();
mql.addEventListener('change', update);
return () => mql.removeEventListener('change', update);
}, []);

useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!isDraggingRef.current || !containerRef.current) return;
Expand Down Expand Up @@ -438,7 +448,7 @@ function CodeEditor({ code, setCode, ws, roomId, interviewType, users }: CodeEdi
const showPreview = interviewType === 'react';

return (
<div ref={containerRef} className={`relative flex flex-row ${isDark ? 'bg-slate-900' : 'bg-gray-100'} p-6 pt-20`}>
<div ref={containerRef} className={`relative flex ${isMobile ? 'flex-col' : 'flex-row'} ${isDark ? 'bg-slate-900' : 'bg-gray-100'} p-6 pt-20`}>
{/* Language dropdown — only shown for leetcode interviews */}
{interviewType === 'leetcode' && <div className='absolute top-6 left-6 z-20'>
<div className='relative'>
Expand Down Expand Up @@ -502,9 +512,9 @@ function CodeEditor({ code, setCode, ws, roomId, interviewType, users }: CodeEdi
</div>
</div>}
{isDragging && <div className='fixed inset-0 z-50 cursor-col-resize' />}
<div style={{ width: `${leftPercent}%` }} className={`border-2 ${isDark ? 'border-white' : 'border-gray-900'} rounded-lg overflow-hidden`}>
<div style={isMobile ? undefined : { width: `${leftPercent}%` }} className={`${isMobile ? 'w-full' : ''} border-2 ${isDark ? 'border-white' : 'border-gray-900'} rounded-lg overflow-hidden`}>
<Editor
height='85vh'
height={isMobile ? 'calc(100vh - 128px)' : '85vh'}
language={selectedLang.monacoLang}
value={code}
theme={isDark ? 'slate-dark' : 'vs'}
Expand All @@ -513,19 +523,51 @@ function CodeEditor({ code, setCode, ws, roomId, interviewType, users }: CodeEdi
onChange={handleEditorChange}
options={{
minimap: { enabled: false },
fontSize: 14,
fontSize: isMobile ? 12 : 14,
padding: { top: 10 },
scrollBeyondLastLine: false,
}}
/>
</div>
{!isMobile && (
<div
onMouseDown={handleDividerMouseDown}
className={`w-3 flex-shrink-0 flex items-center justify-center cursor-col-resize group`}
>
<div className={`w-0.5 h-full rounded-full transition-colors ${isDark ? 'bg-slate-700 group-hover:bg-slate-400' : 'bg-gray-300 group-hover:bg-gray-500'}`} />
</div>
)}
<div
onMouseDown={handleDividerMouseDown}
className={`w-3 flex-shrink-0 flex items-center justify-center cursor-col-resize group`}
style={isMobile ? undefined : { width: `${100 - leftPercent}%` }}
className={
isMobile
? `fixed left-0 right-0 bottom-0 z-30 h-[70vh] flex flex-col border-t-2 rounded-t-2xl shadow-2xl transition-transform duration-300 ease-out ${isDark ? 'border-white bg-slate-900' : 'border-gray-900 bg-gray-100'} ${mobilePreviewOpen ? 'translate-y-0' : 'translate-y-[calc(100%-44px)]'}`
: `border-2 ${isDark ? 'border-white' : 'border-gray-900'} rounded-lg overflow-hidden h-[85vh] relative`
}
>
<div className={`w-0.5 h-full rounded-full transition-colors ${isDark ? 'bg-slate-700 group-hover:bg-slate-400' : 'bg-gray-300 group-hover:bg-gray-500'}`} />
</div>
<div style={{ width: `${100 - leftPercent}%` }} className={`border-2 ${isDark ? 'border-white' : 'border-gray-900'} rounded-lg overflow-hidden h-[85vh] relative`}>
{isMobile && (
<button
onClick={() => setMobilePreviewOpen(prev => !prev)}
className={`relative flex items-center justify-center px-4 h-11 flex-shrink-0 rounded-t-2xl cursor-pointer ${isDark ? 'bg-slate-800 text-white border-b border-slate-700' : 'bg-white text-gray-900 border-b border-gray-200'}`}
>
<span className='text-sm font-medium'>{showPreview ? 'preview' : 'output'}</span>
<svg
xmlns='http://www.w3.org/2000/svg'
width='16'
height='16'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
className={`absolute right-4 transition-transform ${mobilePreviewOpen ? 'rotate-180' : ''}`}
>
<polyline points='6 9 12 15 18 9' />
</svg>
</button>
)}
<div className={isMobile ? 'flex-1 min-h-0 relative overflow-hidden' : 'h-full relative'}>
{showPreview ? (
<>
{hasError && (
Expand Down Expand Up @@ -611,6 +653,7 @@ function CodeEditor({ code, setCode, ws, roomId, interviewType, users }: CodeEdi
</div>
</div>
)}
</div>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/save/PastInterviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function PastInterviewPage() {
{files[0].name}
</p>
)}
<pre className={`whitespace-pre-wrap break-all p-6 rounded-lg shadow-md
<pre className={`whitespace-pre overflow-x-auto p-6 rounded-lg shadow-md
${isDark ? 'bg-slate-800 text-white' : 'bg-white text-gray-900'}`}>
{files[selectedFile]?.content}
</pre>
Expand Down
Loading