1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-09-03 06:12:53 +02:00

Upgrade flow in floating chat

This commit is contained in:
Kamran Ahmed
2025-06-10 17:30:44 +01:00
parent c4043cc77a
commit 474dd14631
3 changed files with 36 additions and 6 deletions

View File

@@ -185,6 +185,7 @@ export function UpgradeAccountModal(props: UpgradeAccountModalProps) {
bodyClassName="p-4 sm:p-6 bg-white"
wrapperClassName="h-auto rounded-xl max-w-3xl w-full min-h-[540px] mx-2 sm:mx-4"
overlayClassName="items-start md:items-center"
hasCloseButton={true}
>
<div onClick={(e) => e.stopPropagation()}>
{errorContent}

View File

@@ -22,14 +22,15 @@ import {
import { cn } from '../../lib/classname';
import { lockBodyScroll } from '../../lib/dom';
import { slugify } from '../../lib/slugger';
import { getAiCourseLimitOptions } from '../../queries/ai-course';
import { billingDetailsOptions } from '../../queries/billing';
import { roadmapJSONOptions } from '../../queries/roadmap';
import { roadmapQuestionsOptions } from '../../queries/roadmap-questions';
import { queryClient } from '../../stores/query-client';
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal';
import { RoadmapAIChatCard } from '../RoadmapAIChat/RoadmapAIChatCard';
import { UpdatePersonaModal } from '../UserPersona/UpdatePersonaModal';
import { CLOSE_TOPIC_DETAIL_EVENT } from '../TopicDetail/TopicDetail';
import { billingDetailsOptions } from '../../queries/billing';
import { getAiCourseLimitOptions } from '../../queries/ai-course';
import { UpdatePersonaModal } from '../UserPersona/UpdatePersonaModal';
type ChatHeaderButtonProps = {
onClick?: () => void;
@@ -156,6 +157,7 @@ export function RoadmapFloatingChat(props: RoadmapChatProps) {
const [inputValue, setInputValue] = useState('');
const inputRef = useRef<HTMLInputElement>(null);
const [isPersonalizeOpen, setIsPersonalizeOpen] = useState(false);
const [showUpgradeModal, setShowUpgradeModal] = useState(false);
// Fetch questions from API
const { data: questionsData } = useQuery(
@@ -292,6 +294,14 @@ export function RoadmapFloatingChat(props: RoadmapChatProps) {
></div>
)}
{showUpgradeModal && (
<UpgradeAccountModal
onClose={() => {
setShowUpgradeModal(false);
}}
/>
)}
{isPersonalizeOpen && (
<UpdatePersonaModal
roadmapId={roadmapId}
@@ -366,6 +376,12 @@ export function RoadmapFloatingChat(props: RoadmapChatProps) {
key={`default-question-${index}`}
className="flex h-full self-start rounded-md bg-yellow-500/10 px-3 py-2 text-left text-sm text-black hover:bg-yellow-500/20"
onClick={() => {
if (isLimitExceeded) {
setShowUpgradeModal(true);
setIsOpen(false);
return;
}
handleChatSubmit(
textToJSON(question),
isRoadmapDetailLoading,
@@ -415,7 +431,8 @@ export function RoadmapFloatingChat(props: RoadmapChatProps) {
{isLimitExceeded && (
<UpgradeMessage
onUpgradeClick={() => {
window.open('/premium', '_blank');
setShowUpgradeModal(true);
setIsOpen(false);
}}
/>
)}
@@ -436,7 +453,8 @@ export function RoadmapFloatingChat(props: RoadmapChatProps) {
<UsageButton
percentageUsed={percentageUsed}
onUpgradeClick={() => {
window.open('/premium', '_blank');
setShowUpgradeModal(true);
setIsOpen(false);
}}
/>
)}

View File

@@ -2,6 +2,7 @@ import { type ReactNode, useRef } from 'react';
import { useOutsideClick } from '../hooks/use-outside-click';
import { useKeydown } from '../hooks/use-keydown';
import { cn } from '../lib/classname';
import { X } from 'lucide-react';
type ModalProps = {
onClose: () => void;
@@ -9,6 +10,7 @@ type ModalProps = {
overlayClassName?: string;
bodyClassName?: string;
wrapperClassName?: string;
hasCloseButton?: boolean;
};
export function Modal(props: ModalProps) {
@@ -18,6 +20,7 @@ export function Modal(props: ModalProps) {
bodyClassName,
wrapperClassName,
overlayClassName,
hasCloseButton = true,
} = props;
const popupBodyEl = useRef<HTMLDivElement>(null);
@@ -33,7 +36,7 @@ export function Modal(props: ModalProps) {
return (
<div
className={cn(
'fixed left-0 right-0 top-0 z-99 flex h-full items-center justify-center overflow-y-auto overflow-x-hidden bg-black/50',
'fixed top-0 right-0 left-0 z-99 flex h-full items-center justify-center overflow-x-hidden overflow-y-auto bg-black/50',
overlayClassName,
)}
>
@@ -50,6 +53,14 @@ export function Modal(props: ModalProps) {
bodyClassName,
)}
>
{hasCloseButton && (
<button
onClick={onClose}
className="absolute top-4 right-4 text-gray-300 hover:text-gray-700"
>
<X className="h-5 w-5" />
</button>
)}
{children}
</div>
</div>