Improve topic popup

feat/topic-chat
Kamran Ahmed 1 week ago
parent b5caccfb51
commit 29dc2afc7f
  1. 1
      .astro/types.d.ts
  2. 6
      src/components/TopicDetail/TopicDetail.tsx
  3. 56
      src/components/TopicDetail/TopicDetailAI.tsx
  4. 6
      src/components/TopicDetail/TopicDetailsTabs.tsx

1
.astro/types.d.ts vendored

@ -1,2 +1 @@
/// <reference types="astro/client" />
/// <reference path="content.d.ts" />

@ -375,7 +375,7 @@ export function TopicDetail(props: TopicDetailProps) {
)}
{isLoading && (
<div className="flex h-full w-full items-center justify-center">
<div className="flex h-full w-full justify-center">
<Spinner
outerFill="#d1d5db"
className="h-6 w-6 sm:h-8 sm:w-8"
@ -392,7 +392,7 @@ export function TopicDetail(props: TopicDetailProps) {
'flex flex-col': activeTab === 'ai',
})}
>
<div className="flex items-center justify-between">
<div className="flex justify-between">
{shouldShowAiTab && (
<TopicDetailsTabs
activeTab={activeTab}
@ -570,7 +570,7 @@ export function TopicDetail(props: TopicDetailProps) {
<a
href={contributionUrl}
target="_blank"
className="hidden rounded-md border bg-gray-200 px-2 py-2 text-sm hover:bg-gray-300 sm:flex items-center justify-center"
className="hidden items-center justify-center rounded-md border bg-gray-200 px-2 py-2 text-sm hover:bg-gray-300 sm:flex"
>
<GitHubIcon className="mr-2 inline-block h-4 w-4 text-current" />
Help us Improve this Content

@ -14,10 +14,11 @@ import { queryClient } from '../../stores/query-client';
import { isLoggedIn, removeAuthToken } from '../../lib/jwt';
import {
BotIcon,
Gift,
Loader2Icon,
LockIcon,
RotateCcwIcon,
SendIcon,
Trash2
} from 'lucide-react';
import { showLoginPopup } from '../../lib/popup';
import { cn } from '../../lib/classname';
@ -34,6 +35,7 @@ import type { ResourceType } from '../../lib/resource-progress';
import { getPercentage } from '../../lib/number';
import { roadmapTreeMappingOptions } from '../../queries/roadmap-tree';
import { defaultChatHistory } from './TopicDetail';
import { AILimitsPopup } from '../GenerateCourse/AILimitsPopup';
type TopicDetailAIProps = {
resourceId: string;
@ -67,7 +69,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
const [message, setMessage] = useState('');
const [isStreamingMessage, setIsStreamingMessage] = useState(false);
const [streamedMessage, setStreamedMessage] = useState('');
const [showAILimitsPopup, setShowAILimitsPopup] = useState(false);
const { data: tokenUsage, isLoading } = useQuery(
getAiCourseLimitOptions(),
queryClient,
@ -234,10 +236,20 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
</div>
)}
{showAILimitsPopup && (
<AILimitsPopup
onClose={() => setShowAILimitsPopup(false)}
onUpgrade={() => {
setShowAILimitsPopup(false);
onUpgrade();
}}
/>
)}
{hasSubjects && (
<div className="border-b border-gray-200 px-4 py-2">
<h4 className="flex items-center gap-2 text-base">
Complete the following courses on AI Tutor
<div className="border-b border-gray-200 p-3">
<h4 className="flex items-center gap-2 text-sm">
Complete the following AI Tutor courses
</h4>
<div className="mt-2.5 flex flex-wrap gap-1 text-sm">
@ -247,7 +259,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
key={subject}
target="_blank"
href={`/ai/search?term=${subject}&difficulty=beginner&src=topic`}
className="rounded-md border px-1.5"
className="flex items-center bg-gray-100 gap-1 gap-2 rounded-md border border-gray-300 px-2 py-1 hover:bg-gray-200 hover:text-black"
>
{subject}
</a>
@ -259,13 +271,16 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
<div
className={cn(
'flex items-center justify-between gap-2 border-gray-200 px-4 py-2 text-sm',
!hasSubjects && 'border-b',
'flex items-center justify-between gap-2 border-gray-200 px-3 py-2 text-sm',
)}
>
{hasSubjects && (
<span className="flex items-center gap-2 text-base">
or start chatting with AI
<span className="flex items-center gap-2 text-sm">
<BotIcon
className="relative -top-[1px] size-4 shrink-0 text-black"
strokeWidth={2.5}
/>
Chat with AI
</span>
)}
@ -280,29 +295,36 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
)}
{!isDataLoading && (
<div className="flex items-center gap-2.5">
<div className="flex gap-1.5">
{hasChatHistory && (
<button
className="rounded-md bg-white p-1 text-xs font-medium text-black hover:bg-gray-200"
className="rounded-md bg-white px-2 text-xs font-medium text-black hover:bg-gray-200"
onClick={() => {
setAiChatHistory(defaultChatHistory);
}}
>
<RotateCcwIcon className="size-3.5" />
<Trash2 className="size-3.5" />
</button>
)}
{!isPaidUser && (
<>
<button
className="underline underline-offset-2 hover:no-underline"
className="rounded-md bg-gray-200 px-2 py-1 text-sm hover:bg-gray-300"
onClick={() => {
setShowAILimitsPopup(true);
}}
>
<span className="font-medium">{usagePercentage}%</span>{' '}
credits used
</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"
onClick={onUpgrade}
>
<Gift className="size-4" />
Upgrade
</button>
<p className="text-sm text-gray-500">
<span className="font-medium">{usagePercentage}%</span> used
</p>
</>
)}
</div>

@ -42,16 +42,16 @@ function TopicDetailsTab(props: TopicDetailsTabProps) {
return (
<button
className="flex border data-[state=active]:border-black border-gray-300 hover:bg-gray-100 items-center gap-2 px-2 py-1 rounded-md text-sm text-gray-500 data-[state=active]:bg-black data-[state=active]:text-white"
className="flex items-center gap-2 rounded-md border border-gray-300 px-2 py-1 text-sm text-gray-500 hover:border-gray-400 data-[state=active]:border-black data-[state=active]:bg-black data-[state=active]:text-white"
data-state={isActive ? 'active' : 'inactive'}
onClick={onClick}
disabled={isActive}
type="button"
>
<Icon className="h-4 w-4" />
{label}
<span className="hidden sm:block">{label}</span>
{isNew && (
<span className="text-xs bg-yellow-400 text-black rounded-sm px-1">
<span className="hidden rounded-sm bg-yellow-400 px-1 text-xs text-black sm:block">
New
</span>
)}

Loading…
Cancel
Save