Files
developer-roadmap/src/components/TabLink.tsx
T
Arik ChakmaandKamran Ahmed 62f31a4964 feat: roadmap chat (#8666)
* 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>
2025-05-27 21:02:36 +01:00

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>
);
}