fix: roadmap refetching

fix/ai-roadmap
Arik Chakma 9 months ago
parent 09cb1ea827
commit e66822e1b9
  1. 55
      src/components/GenerateRoadmap/GenerateRoadmap.tsx
  2. 8
      src/components/GenerateRoadmap/RoadmapSearch.tsx

@ -23,6 +23,12 @@ import { cn } from '../../lib/classname.ts';
const ROADMAP_ID_REGEX = new RegExp('@ROADMAPID:(\\w+)@'); const ROADMAP_ID_REGEX = new RegExp('@ROADMAPID:(\\w+)@');
type GetAIRoadmapResponse = {
id: string;
topic: string;
data: string;
};
export function GenerateRoadmap() { export function GenerateRoadmap() {
const roadmapContainerRef = useRef<HTMLDivElement>(null); const roadmapContainerRef = useRef<HTMLDivElement>(null);
@ -33,6 +39,8 @@ export function GenerateRoadmap() {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [roadmapTopic, setRoadmapTopic] = useState(''); const [roadmapTopic, setRoadmapTopic] = useState('');
const [generatedRoadmap, setGeneratedRoadmap] = useState(''); const [generatedRoadmap, setGeneratedRoadmap] = useState('');
const [currentRoadmap, setCurrentRoadmap] =
useState<GetAIRoadmapResponse | null>(null);
const [roadmapLimit, setRoadmapLimit] = useState(0); const [roadmapLimit, setRoadmapLimit] = useState(0);
const [roadmapLimitUsed, setRoadmapLimitUsed] = useState(0); const [roadmapLimitUsed, setRoadmapLimitUsed] = useState(0);
@ -51,6 +59,10 @@ export function GenerateRoadmap() {
return; return;
} }
if (roadmapTopic === currentRoadmap?.topic) {
return;
}
setIsLoading(true); setIsLoading(true);
setHasSubmitted(true); setHasSubmitted(true);
@ -104,6 +116,11 @@ export function GenerateRoadmap() {
const roadmapId = result.match(ROADMAP_ID_REGEX)?.[1] || ''; const roadmapId = result.match(ROADMAP_ID_REGEX)?.[1] || '';
setUrlParams({ id: roadmapId }); setUrlParams({ id: roadmapId });
result = result.replace(ROADMAP_ID_REGEX, ''); result = result.replace(ROADMAP_ID_REGEX, '');
setCurrentRoadmap({
id: roadmapId,
topic: roadmapTopic,
data: result,
});
} }
await renderRoadmap(result); await renderRoadmap(result);
@ -150,11 +167,17 @@ export function GenerateRoadmap() {
if (error || !response) { if (error || !response) {
toast.error(error?.message || 'Something went wrong'); toast.error(error?.message || 'Something went wrong');
pageProgressMessage.set('');
setIsLoading(false); setIsLoading(false);
return; return;
} }
window.location.href = `${import.meta.env.PUBLIC_EDITOR_APP_URL}/${response.roadmapId}`; setIsLoading(false);
pageProgressMessage.set('');
window.open(
`${import.meta.env.PUBLIC_EDITOR_APP_URL}/${response.roadmapId}`,
'_blank',
);
}; };
const downloadGeneratedRoadmap = async () => { const downloadGeneratedRoadmap = async () => {
@ -208,6 +231,11 @@ export function GenerateRoadmap() {
const { topic, data } = response; const { topic, data } = response;
await renderRoadmap(data); await renderRoadmap(data);
setCurrentRoadmap({
id: roadmapId,
topic,
data,
});
setRoadmapTopic(topic); setRoadmapTopic(topic);
setGeneratedRoadmap(data); setGeneratedRoadmap(data);
}; };
@ -217,7 +245,7 @@ export function GenerateRoadmap() {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (!roadmapId) { if (!roadmapId || roadmapId === currentRoadmap?.id) {
return; return;
} }
@ -225,7 +253,7 @@ export function GenerateRoadmap() {
loadAIRoadmap(roadmapId).finally(() => { loadAIRoadmap(roadmapId).finally(() => {
pageProgressMessage.set(''); pageProgressMessage.set('');
}); });
}, [roadmapId]); }, [roadmapId, currentRoadmap]);
if (!hasSubmitted) { if (!hasSubmitted) {
return ( return (
@ -282,12 +310,12 @@ export function GenerateRoadmap() {
</div> </div>
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="my-3 flex w-full flex-col sm:flex-row sm:items-center sm:justify-center gap-2" className="my-3 flex w-full flex-col gap-2 sm:flex-row sm:items-center sm:justify-center"
> >
<input <input
type="text" type="text"
autoFocus autoFocus
placeholder="e.g. Ansible" placeholder="e.g. Try searching for Ansible or DevOps"
className="flex-grow rounded-md border border-gray-400 px-3 py-2 transition-colors focus:border-black focus:outline-none" className="flex-grow rounded-md border border-gray-400 px-3 py-2 transition-colors focus:border-black focus:outline-none"
value={roadmapTopic} value={roadmapTopic}
onInput={(e) => onInput={(e) =>
@ -297,14 +325,15 @@ export function GenerateRoadmap() {
<button <button
type={'submit'} type={'submit'}
className={cn( className={cn(
'flex min-w-[127px] flex-shrink-0 items-center gap-2 rounded-md bg-black px-4 py-2 text-white justify-center', 'flex min-w-[127px] flex-shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2 text-white',
{ 'disabled:cursor-not-allowed disabled:opacity-50',
'cursor-not-allowed opacity-50':
!roadmapLimit ||
!roadmapTopic ||
roadmapLimitUsed >= roadmapLimit,
},
)} )}
disabled={
!roadmapLimit ||
!roadmapTopic ||
roadmapLimitUsed >= roadmapLimit ||
roadmapTopic === currentRoadmap?.topic
}
> >
{roadmapLimit > 0 && canGenerateMore && ( {roadmapLimit > 0 && canGenerateMore && (
<> <>
@ -354,7 +383,7 @@ export function GenerateRoadmap() {
<div <div
ref={roadmapContainerRef} ref={roadmapContainerRef}
id="roadmap-container" id="roadmap-container"
className="relative px-4 py-5 [&>svg]:mx-auto [&>svg]:max-w-[1300px]" className="pointer-events-none relative px-4 py-5 [&>svg]:mx-auto [&>svg]:max-w-[1300px]"
/> />
</section> </section>
); );

@ -52,7 +52,7 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
<input <input
autoFocus autoFocus
type="text" type="text"
placeholder="e.g. Ansible" placeholder="e.g. Try searching for Ansible or DevOps"
className="w-full rounded-md border border-gray-400 px-3 py-2.5 transition-colors focus:border-black focus:outline-none" className="w-full rounded-md border border-gray-400 px-3 py-2.5 transition-colors focus:border-black focus:outline-none"
value={roadmapTopic} value={roadmapTopic}
onInput={(e) => setRoadmapTopic((e.target as HTMLInputElement).value)} onInput={(e) => setRoadmapTopic((e.target as HTMLInputElement).value)}
@ -60,11 +60,9 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
<button <button
className={cn( className={cn(
'flex min-w-[143px] flex-shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2 text-white', 'flex min-w-[143px] flex-shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2 text-white',
{ 'disabled:cursor-not-allowed disabled:opacity-50',
'cursor-not-allowed opacity-50':
!limit || !roadmapTopic || limitUsed >= limit,
},
)} )}
disabled={!limit || !roadmapTopic || limitUsed >= limit}
> >
{limit > 0 && canGenerateMore && ( {limit > 0 && canGenerateMore && (
<> <>

Loading…
Cancel
Save