* wip: roadmap chat * wip * wip * wip * wip * wip: message rendering * wip: roadmap topics rendering * Update UI for premium page * Update UI for premium page * wip: topic resources rendering * Update premium page design * Update navigation design * Update design for play iconsg * Update design for play iconsg * wip: resource progress * Update premium page * Refactor premium page * wip: resource progress * feat: enhance the progress rendering * feat: add abort functionality to chat and update UI elements * feat: add roadmap recommendations feature and new query for built-in roadmaps * Grid -> flex * Update chat * Handle error screen * wip * fix: empty content check * feat: show loading status * feat: ai chat limit * Refactor content parsing * Handle the wrapping of tag in codeblocks * Refactor * Refactor chat * Fix hydration error * feat: topic details * style: adjust padding and icon size in RoadmapAIChat component * feat: add tab navigation for chat and topic details * fix: chat and details scrolling issue * fix: invalidate progress query * Fix upgrade modal and issue with close button * Refactor topic detail AI * Update progress UI * Shorten the text * Rewrite frontend roadmap content * Minor update to content * Update shrinking issue * Changes to ai chat * UI changes for chat card * UI changes for chat card * Refactor progress actions list * Update progress marking UI * UI Changes * Responsiveness of sidebar * Responsiveness of sidebar * Mobile window for roadmap chat * Responsiveness of AI chat * Close button fix * Make roadmap ai chat header responsive * Escape key handling to close * Update topic rendering node * Make default active tab to AI in topic popup * User progress component * Clear chat only visible when there is chat * wip: user persona * fix: hide upgrade button * fix: show chat input for guest users * feat: persona update * Roadmap recommendations * Update persona form * Update tell us more * Fix persona form * Fix scroll issue * Lock body scroll when mobile is active * Add intro message * Refactor and update * Update UI for AI chat --------- Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
86 lines
2.1 KiB
TypeScript
86 lines
2.1 KiB
TypeScript
import type { LucideIcon } from 'lucide-react';
|
|
import { cn } from '../lib/classname.ts';
|
|
|
|
type TabLinkProps = {
|
|
icon: LucideIcon;
|
|
text: string;
|
|
mobileText?: string;
|
|
isActive: boolean;
|
|
isExternal?: boolean;
|
|
badgeText?: string;
|
|
hideTextOnMobile?: boolean;
|
|
url: string;
|
|
className?: string;
|
|
};
|
|
|
|
export function TabLink(props: TabLinkProps) {
|
|
const {
|
|
icon: Icon,
|
|
badgeText,
|
|
isExternal = false,
|
|
url,
|
|
text,
|
|
mobileText,
|
|
isActive,
|
|
hideTextOnMobile = false,
|
|
className: additionalClassName = '',
|
|
} = props;
|
|
|
|
const className = cn(
|
|
'inline-flex group transition-colors items-center gap-1.5 border-b-2 px-2 pb-2.5 text-sm',
|
|
{
|
|
'cursor-default border-b-black font-medium text-black': isActive,
|
|
'border-b-transparent font-normal text-gray-400 hover:text-gray-700':
|
|
!isActive,
|
|
'font-medium hover:text-black text-gray-500 px-0': isExternal,
|
|
},
|
|
additionalClassName,
|
|
);
|
|
|
|
const textClass = cn({
|
|
'hidden sm:inline': hideTextOnMobile,
|
|
});
|
|
|
|
const badgeNode = badgeText && (
|
|
<span
|
|
className={cn(
|
|
'ml-0.5 hidden items-center gap-0.5 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-black transition-colors sm:flex',
|
|
{
|
|
'bg-gray-200 text-black group-hover:bg-gray-300':
|
|
badgeText?.toLowerCase() == 'soon',
|
|
'bg-yellow-200 text-black group-hover:bg-yellow-300':
|
|
badgeText?.toLowerCase() == 'new',
|
|
},
|
|
)}
|
|
>
|
|
<span className="relative -top-px">{badgeText}</span>
|
|
</span>
|
|
);
|
|
|
|
if (isActive) {
|
|
return (
|
|
<span className={className}>
|
|
<Icon className="h-4 w-4 shrink-0" />
|
|
<span className={textClass}>{text}</span>
|
|
{badgeNode}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<a
|
|
target={isExternal ? '_blank' : undefined}
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
}}
|
|
href={url}
|
|
className={className}
|
|
>
|
|
<Icon className="h-4 w-4 shrink-0" />
|
|
<span className={cn(textClass, 'hidden sm:inline')}>{text}</span>
|
|
<span className={cn(textClass, 'inline sm:hidden')}>{mobileText || text}</span>
|
|
{badgeNode}
|
|
</a>
|
|
);
|
|
}
|