Implement topic ai changes

feat/topic-chat
Kamran Ahmed 1 week ago
parent f173a4723c
commit fb052e9793
  1. 20
      src/components/TopicDetail/PredefinedActionGroup.tsx
  2. 2
      src/components/TopicDetail/PredefinedActions.tsx
  3. 9
      src/components/TopicDetail/TopicDetail.tsx
  4. 26
      src/components/TopicDetail/TopicDetailAI.tsx

@ -2,19 +2,19 @@ import type { LucideIcon } from 'lucide-react';
import { useState, useRef } from 'react'; import { useState, useRef } from 'react';
import { useOutsideClick } from '../../hooks/use-outside-click'; import { useOutsideClick } from '../../hooks/use-outside-click';
import { import {
type PredefinedMessageType, type PredefinedActionType,
PredefinedActionButton, PredefinedActionButton,
} from './PredefinedActions'; } from './PredefinedActions';
type PredefinedMessageGroupProps = { type PredefinedActionGroupProps = {
label: string; label: string;
icon: LucideIcon; icon: LucideIcon;
messages: PredefinedMessageType[]; actions: PredefinedActionType[];
onSelect: (message: PredefinedMessageType) => void; onSelect: (action: PredefinedActionType) => void;
}; };
export function PredefinedActionGroup(props: PredefinedMessageGroupProps) { export function PredefinedActionGroup(props: PredefinedActionGroupProps) {
const { label, icon: Icon, messages, onSelect } = props; const { label, icon: Icon, actions, onSelect } = props;
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
@ -34,14 +34,14 @@ export function PredefinedActionGroup(props: PredefinedMessageGroupProps) {
{isOpen && ( {isOpen && (
<div className="absolute top-full left-0 z-20 mt-1 divide-y overflow-hidden rounded-md border border-gray-200 bg-white p-0"> <div className="absolute top-full left-0 z-20 mt-1 divide-y overflow-hidden rounded-md border border-gray-200 bg-white p-0">
{messages.map((m) => { {actions.map((action) => {
return ( return (
<PredefinedActionButton <PredefinedActionButton
key={m.message} key={action.label}
{...m} {...action}
className="h-7 w-full rounded-none bg-transparent hover:bg-gray-200" className="h-7 w-full rounded-none bg-transparent hover:bg-gray-200"
onClick={() => { onClick={() => {
onSelect(m); onSelect(action);
setIsOpen(false); setIsOpen(false);
}} }}
/> />

@ -79,7 +79,7 @@ export function PredefinedActions(props: PredefinedActionsProps) {
key={action.label} key={action.label}
label={action.label} label={action.label}
icon={action.icon} icon={action.icon}
messages={action.children} actions={action.children}
onSelect={onSelect} onSelect={onSelect}
/> />
); );

@ -25,7 +25,10 @@ import { Ban, FileText, HeartHandshake, Star, X } from 'lucide-react';
import { getUrlParams, parseUrl } from '../../lib/browser'; import { getUrlParams, parseUrl } from '../../lib/browser';
import { Spinner } from '../ReactIcons/Spinner'; import { Spinner } from '../ReactIcons/Spinner';
import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx'; import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx';
import { resourceTitleFromId, type AllowedRoadmapRenderer } from '../../lib/roadmap.ts'; import {
resourceTitleFromId,
type AllowedRoadmapRenderer,
} from '../../lib/roadmap.ts';
import { lockBodyScroll } from '../../lib/dom.ts'; import { lockBodyScroll } from '../../lib/dom.ts';
import { TopicDetailLink } from './TopicDetailLink.tsx'; import { TopicDetailLink } from './TopicDetailLink.tsx';
import { ResourceListSeparator } from './ResourceListSeparator.tsx'; import { ResourceListSeparator } from './ResourceListSeparator.tsx';
@ -441,6 +444,10 @@ export function TopicDetail(props: TopicDetailProps) {
aiChatHistory={aiChatHistory} aiChatHistory={aiChatHistory}
setAiChatHistory={setAiChatHistory} setAiChatHistory={setAiChatHistory}
onUpgrade={() => setShowUpgradeModal(true)} onUpgrade={() => setShowUpgradeModal(true)}
onLogin={() => {
handleClose();
showLoginPopup();
}}
/> />
)} )}

@ -40,6 +40,7 @@ type TopicDetailAIProps = {
setAiChatHistory: (history: AIChatHistoryType[]) => void; setAiChatHistory: (history: AIChatHistoryType[]) => void;
onUpgrade: () => void; onUpgrade: () => void;
onLogin: () => void;
}; };
export function TopicDetailAI(props: TopicDetailAIProps) { export function TopicDetailAI(props: TopicDetailAIProps) {
@ -50,6 +51,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
resourceType, resourceType,
topicId, topicId,
onUpgrade, onUpgrade,
onLogin,
} = props; } = props;
const textareaRef = useRef<HTMLTextAreaElement>(null); const textareaRef = useRef<HTMLTextAreaElement>(null);
@ -307,6 +309,11 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
<button <button
className="hidden rounded-md bg-gray-200 px-2 py-1 text-sm hover:bg-gray-300 sm:block" className="hidden rounded-md bg-gray-200 px-2 py-1 text-sm hover:bg-gray-300 sm:block"
onClick={() => { onClick={() => {
if (!isLoggedIn()) {
onLogin();
return;
}
setShowAILimitsPopup(true); setShowAILimitsPopup(true);
}} }}
> >
@ -315,7 +322,14 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
</button> </button>
<button <button
className="flex items-center gap-1 rounded-md bg-yellow-400 px-2 py-1 text-sm text-black hover:bg-yellow-500" className="flex items-center gap-1 rounded-md bg-yellow-400 px-2 py-1 text-sm text-black hover:bg-yellow-500"
onClick={onUpgrade} onClick={() => {
if (!isLoggedIn()) {
onLogin();
return;
}
onUpgrade();
}}
> >
<Gift className="size-4" /> <Gift className="size-4" />
Upgrade Upgrade
@ -328,6 +342,16 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
<PredefinedActions <PredefinedActions
onSelect={(action) => { onSelect={(action) => {
if (!isLoggedIn()) {
onLogin();
return;
}
if (isLimitExceeded) {
onUpgrade();
return;
}
if (!action?.prompt) { if (!action?.prompt) {
toast.error('Something went wrong'); toast.error('Something went wrong');
return; return;

Loading…
Cancel
Save