Skip to content

Commit

Permalink
ui: improve personnality picker
Browse files Browse the repository at this point in the history
  • Loading branch information
mamadoudicko committed Aug 4, 2023
1 parent 84bff50 commit 5dd47fb
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TextArea } from "@/lib/components/ui/TextArea";
import { models, paidModels } from "@/lib/context/BrainConfigProvider/types";
import { defineMaxTokens } from "@/lib/helpers/defineMexTokens";

import { PublicPrompts } from "./components/PublicPrompts";
import { PublicPrompts } from "./components/PublicPrompts/PublicPrompts";
import { useSettingsTab } from "./hooks/useSettingsTab";

type SettingsTabProps = {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { PublicPromptsList } from "./components/PublicPromptsList/PublicPromptsList";
import { usePublicPrompts } from "./hooks/usePublicPrompts";

type PublicPromptsProps = {
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

export const PublicPrompts = ({
onSelect,
}: PublicPromptsProps): JSX.Element => {
const { handleChange, publicPrompts } = usePublicPrompts({
onSelect,
});

return (
<PublicPromptsList
options={publicPrompts}
onChange={handleChange}
onSelect={onSelect}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ChangeEvent } from "react";

import { Prompt } from "@/lib/types/Prompt";

import { usePublicPromptsList } from "./hooks/usePublicPromptsList";

type PublicPromptsListProps = {
options: Prompt[];
onChange: (event: ChangeEvent<HTMLSelectElement>) => void;
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

export const PublicPromptsList = ({
options,
onChange,
onSelect,
}: PublicPromptsListProps): JSX.Element => {
const {
handleOptionClick,
isOpen,
selectRef,
selectedOption,
toggleDropdown,
} = usePublicPromptsList({
onChange,
onSelect,
});

return (
<div ref={selectRef} className="relative min-w-[200px] inline-block">
<button
onClick={toggleDropdown}
type="button"
className="px-4 py-2 w-full text-gray-700 bg-white border rounded-md focus:outline-none focus:border-blue-500"
>
{selectedOption ? selectedOption.title : "Select a Quivr Personality"}
</button>
{isOpen && (
<div className="absolute top-10 w-full bg-white border rounded-md shadow-lg">
{options.map((option) => (
<div
key={option.id}
className="px-4 py-2 cursor-pointer hover:bg-gray-100"
onClick={() => handleOptionClick(option)}
>
{option.title}
</div>
))}
</div>
)}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ChangeEvent, useEffect, useRef, useState } from "react";

import { Prompt } from "@/lib/types/Prompt";

type UsePublicPromptsListProps = {
onChange: (event: ChangeEvent<HTMLSelectElement>) => void;
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const usePublicPromptsList = ({
onChange,
onSelect,
}: UsePublicPromptsListProps) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState<Prompt | null>(null);
const selectRef = useRef<HTMLDivElement>(null);

const toggleDropdown = () => {
setIsOpen((prevIsOpen) => !prevIsOpen);
};

const handleOptionClick = (option: Prompt) => {
setSelectedOption(option);
setIsOpen(false);
onChange({
target: { value: option.id },
} as ChangeEvent<HTMLSelectElement>);
onSelect({
title: option.title,
content: option.content,
});
};

const handleClickOutside = (event: MouseEvent) => {
if (
selectRef.current &&
!selectRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
};

useEffect(() => {
document.addEventListener("click", handleClickOutside, true);

return () => {
document.removeEventListener("click", handleClickOutside, true);
};
}, []);

return {
isOpen,
selectedOption,
selectRef,
toggleDropdown,
handleOptionClick,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPromptsList";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPromptsList";
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ChangeEvent, useEffect, useState } from "react";

import { usePromptApi } from "@/lib/api/prompt/usePromptApi";
import { Prompt } from "@/lib/types/Prompt";

type UsePublicPromptsProps = {
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const usePublicPrompts = ({ onSelect }: UsePublicPromptsProps) => {
const [publicPrompts, setPublicPrompts] = useState<Prompt[]>([]);
const { getPublicPrompts } = usePromptApi();

useEffect(() => {
const fetchPublicPrompts = async () => {
setPublicPrompts(await getPublicPrompts());
};
void fetchPublicPrompts();
}, []);

const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
const selectedPrompt = publicPrompts.find(
(prompt) => prompt.id === event.target.value
);
if (selectedPrompt) {
onSelect({
title: selectedPrompt.title,
content: selectedPrompt.content,
});
}
};

return {
publicPrompts,
handleChange,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPrompts";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPrompts";

0 comments on commit 5dd47fb

Please sign in to comment.