mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-08 16:20:40 +02:00
wip
This commit is contained in:
@@ -5,7 +5,12 @@ import {
|
|||||||
type AIQuestionSuggestionsResponse,
|
type AIQuestionSuggestionsResponse,
|
||||||
} from '../../queries/user-ai-session';
|
} from '../../queries/user-ai-session';
|
||||||
import type { AllowedFormat } from './ContentGenerator';
|
import type { AllowedFormat } from './ContentGenerator';
|
||||||
import { Loader2Icon, RotateCwIcon, SendIcon } from 'lucide-react';
|
import {
|
||||||
|
Loader2Icon,
|
||||||
|
RefreshCcwIcon,
|
||||||
|
RotateCwIcon,
|
||||||
|
SendIcon,
|
||||||
|
} from 'lucide-react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { cn } from '../../lib/classname';
|
import { cn } from '../../lib/classname';
|
||||||
import { flushSync } from 'react-dom';
|
import { flushSync } from 'react-dom';
|
||||||
@@ -28,6 +33,7 @@ type QuestionAnswerChatProps = {
|
|||||||
) => void;
|
) => void;
|
||||||
onGenerateNow: () => void;
|
onGenerateNow: () => void;
|
||||||
defaultQuestions?: AIQuestionSuggestionsResponse['questions'];
|
defaultQuestions?: AIQuestionSuggestionsResponse['questions'];
|
||||||
|
type?: 'create' | 'update';
|
||||||
};
|
};
|
||||||
|
|
||||||
export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
||||||
@@ -38,6 +44,7 @@ export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
|||||||
questionAnswerChatMessages,
|
questionAnswerChatMessages,
|
||||||
setQuestionAnswerChatMessages,
|
setQuestionAnswerChatMessages,
|
||||||
onGenerateNow,
|
onGenerateNow,
|
||||||
|
type = 'create',
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [activeMessageIndex, setActiveMessageIndex] = useState(
|
const [activeMessageIndex, setActiveMessageIndex] = useState(
|
||||||
@@ -117,7 +124,7 @@ export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}, [defaultQuestions]);
|
}, [defaultQuestions, type]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -145,7 +152,7 @@ export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
|||||||
|
|
||||||
{!isLoadingAiQuestionSuggestions && status === 'answering' && (
|
{!isLoadingAiQuestionSuggestions && status === 'answering' && (
|
||||||
<>
|
<>
|
||||||
{canReset && (
|
{canReset && type === 'create' && (
|
||||||
<div className="absolute top-2 left-2 z-10">
|
<div className="absolute top-2 left-2 z-10">
|
||||||
<button
|
<button
|
||||||
className="flex cursor-pointer items-center gap-1.5 rounded-lg bg-gray-50 px-2 py-1 text-xs text-gray-500 hover:bg-gray-200 focus:outline-none"
|
className="flex cursor-pointer items-center gap-1.5 rounded-lg bg-gray-50 px-2 py-1 text-xs text-gray-500 hover:bg-gray-200 focus:outline-none"
|
||||||
@@ -189,6 +196,22 @@ export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{!activeMessage && type === 'update' && (
|
||||||
|
<div className="p-2">
|
||||||
|
<button
|
||||||
|
className="flex w-full items-center justify-center gap-2 rounded-lg border border-gray-200 bg-white p-2"
|
||||||
|
onClick={() => {
|
||||||
|
setQuestionAnswerChatMessages([]);
|
||||||
|
setActiveMessageIndex(0);
|
||||||
|
setStatus('answering');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RefreshCcwIcon className="size-4" />
|
||||||
|
Reanswer the questions
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{activeMessage && (
|
{activeMessage && (
|
||||||
<div className="p-2">
|
<div className="p-2">
|
||||||
<div className="rounded-lg border border-gray-200 bg-white">
|
<div className="rounded-lg border border-gray-200 bg-white">
|
||||||
@@ -212,13 +235,7 @@ export function QuestionAnswerChat(props: QuestionAnswerChatProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div className="flex w-full items-center justify-between gap-2 p-2">
|
||||||
className="flex w-full items-center justify-between gap-2 p-2"
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
handleAnswerSelect(message);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
value={message}
|
value={message}
|
||||||
onChange={(e) => setMessage(e.target.value)}
|
onChange={(e) => setMessage(e.target.value)}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import type { AIQuestionSuggestionsResponse } from '../../queries/user-ai-session';
|
import type { AIQuestionSuggestionsResponse } from '../../queries/user-ai-session';
|
||||||
import type { AllowedFormat } from '../ContentGenerator/ContentGenerator';
|
import type { AllowedFormat } from '../ContentGenerator/ContentGenerator';
|
||||||
import {
|
import {
|
||||||
@@ -21,7 +21,7 @@ type UpdatePreferencesProps = {
|
|||||||
export function UpdatePreferences(props: UpdatePreferencesProps) {
|
export function UpdatePreferences(props: UpdatePreferencesProps) {
|
||||||
const {
|
const {
|
||||||
onClose,
|
onClose,
|
||||||
questionAndAnswers,
|
questionAndAnswers: defaultQuestionAndAnswers,
|
||||||
term,
|
term,
|
||||||
format,
|
format,
|
||||||
onUpdatePreferences,
|
onUpdatePreferences,
|
||||||
@@ -30,15 +30,22 @@ export function UpdatePreferences(props: UpdatePreferencesProps) {
|
|||||||
|
|
||||||
const [questionAnswerChatMessages, setQuestionAnswerChatMessages] = useState<
|
const [questionAnswerChatMessages, setQuestionAnswerChatMessages] = useState<
|
||||||
QuestionAnswerChatMessage[]
|
QuestionAnswerChatMessage[]
|
||||||
>(questionAndAnswers || []);
|
>(defaultQuestionAndAnswers || []);
|
||||||
|
|
||||||
const defaultQuestions = questionAndAnswers
|
const defaultQuestions = defaultQuestionAndAnswers
|
||||||
?.filter((message) => message.role === 'assistant')
|
?.filter((message) => message.role === 'assistant')
|
||||||
.map((message) => ({
|
.map((message) => ({
|
||||||
question: message.question,
|
question: message.question,
|
||||||
possibleAnswers: message.possibleAnswers,
|
possibleAnswers: message.possibleAnswers,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const hasChangedQuestionAndAnswers = useMemo(() => {
|
||||||
|
return (
|
||||||
|
JSON.stringify(questionAnswerChatMessages) !==
|
||||||
|
JSON.stringify(defaultQuestionAndAnswers)
|
||||||
|
);
|
||||||
|
}, [questionAnswerChatMessages, defaultQuestionAndAnswers]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
@@ -61,17 +68,20 @@ export function UpdatePreferences(props: UpdatePreferencesProps) {
|
|||||||
onGenerateNow={() => {
|
onGenerateNow={() => {
|
||||||
onUpdatePreferences(questionAnswerChatMessages);
|
onUpdatePreferences(questionAnswerChatMessages);
|
||||||
}}
|
}}
|
||||||
|
type="update"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button
|
{hasChangedQuestionAndAnswers && (
|
||||||
className="rounded-lg bg-black px-4 py-2 text-white disabled:opacity-50"
|
<button
|
||||||
disabled={isUpdating}
|
className="rounded-lg bg-black px-4 py-2 text-white disabled:opacity-50"
|
||||||
onClick={() => {
|
disabled={isUpdating || !hasChangedQuestionAndAnswers}
|
||||||
onUpdatePreferences(questionAnswerChatMessages);
|
onClick={() => {
|
||||||
}}
|
onUpdatePreferences(questionAnswerChatMessages);
|
||||||
>
|
}}
|
||||||
{isUpdating ? 'Updating...' : 'Update Preferences'}
|
>
|
||||||
</button>
|
{isUpdating ? 'Updating...' : 'Update Preferences'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user