Roadmap to becoming a developer in 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

135 lines
3.4 KiB

import {
Blocks,
Check,
Flag,
Hammer,
type LucideIcon,
Play,
PlayCircle,
Send,
} from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { cn } from '../../lib/classname.ts';
type StepperActionProps = {
isActive?: boolean;
isCompleted?: boolean;
icon: LucideIcon;
text: string;
number: number;
};
function StepperAction(props: StepperActionProps) {
const { isActive, isCompleted, icon: DisplayIcon, text, number } = props;
if (isActive) {
return (
<button className="flex items-center gap-1.5 rounded-xl bg-purple-600 py-1 pl-2 pr-2.5 text-sm text-white hover:bg-purple-700">
<DisplayIcon size={13} />
<span>{text}</span>
</button>
);
}
if (isCompleted) {
return (
<span className="flex cursor-default items-center gap-1.5 text-sm font-medium text-green-600">
<Check size={14} strokeWidth={3} />
<span>{text}</span>
</span>
);
}
return (
<span className="flex cursor-default items-center gap-1.5 text-sm text-gray-400">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-gray-400/70 text-xs text-white">
{number}
</span>
<span>{text}</span>
</span>
);
}
type StepperStepSeparatorProps = {
isActive: boolean;
};
function StepperStepSeparator(props: StepperStepSeparatorProps) {
const { isActive } = props;
return (
<hr
className={cn('flex-grow border border-gray-300', {
'border-green-500': isActive,
})}
/>
);
}
export function ProjectStepper() {
const stickyElRef = useRef<HTMLDivElement>(null);
const [isSticky, setIsSticky] = useState(false);
// on scroll check if the element has sticky class in effect
useEffect(() => {
const handleScroll = () => {
if (stickyElRef.current) {
setIsSticky(stickyElRef.current.getBoundingClientRect().top <= 8);
}
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
return (
<div
ref={stickyElRef}
className={cn(
'sticky top-0 -mx-2 -mt-2 mb-5 overflow-hidden rounded-lg border bg-white transition-all',
{
'-mx-5 rounded-none border-x-0 border-t-0 bg-gray-50': isSticky,
},
)}
>
<div
className={cn(
'border-b bg-gray-100 px-4 py-2 text-sm text-gray-500 transition-colors',
{
'bg-purple-600 text-white': isSticky,
},
)}
>
Start building, submit solution and get feedback from the community.
</div>
<div className="flex min-h-[60px] items-center justify-between gap-3 px-4">
<StepperAction
isCompleted={true}
icon={Play}
text={'Start Building'}
number={1}
/>
<StepperStepSeparator isActive={true} />
<StepperAction
isActive={true}
icon={Send}
text={'Submit Solution'}
number={2}
/>
<StepperStepSeparator isActive={false} />
<button className="flex items-center gap-1.5 text-sm text-gray-400">
<Flag size={14} />
<span>5 Upvotes</span>
</button>
<hr className="flex-grow border border-gray-300" />
<button className="flex items-center gap-1.5 text-sm text-gray-400">
<Flag size={14} />
<span>10+ Upvotes</span>
</button>
</div>
</div>
);
}