Spaces:
Runtime error
Runtime error
| import { | |
| Select, | |
| SelectContent, | |
| SelectItem, | |
| SelectTrigger, | |
| SelectValue, | |
| } from "@/components/ui/select" | |
| import { ChevronLeft, Menu } from "lucide-react" | |
| import { useEffect, useState } from "react"; | |
| import { ToastContainer, toast } from "react-toastify" | |
| import 'react-toastify/dist/ReactToastify.css'; | |
| import { Switch } from "@/components/ui/switch" | |
| import { Label } from "@/components/ui/label" | |
| import { Input } from "@/components/ui/input" | |
| function App() { | |
| const [schoolSubject, setSchoolSubject] = useState("biologia"); | |
| const [subject, setSubject] = useState(""); | |
| const [difficultie, setDifficultie] = useState(""); | |
| const [menuState, setMenuState] = useState(true); | |
| const [isLoading, setIsLoading] = useState(false); | |
| const [questions, setQuestions] = useState(null); | |
| const [promptMode, setPromptMode] = useState(false); | |
| const [promptValue, setPromptValue] = useState(''); | |
| const schoolSubjects = [ | |
| { label: "História", value: "historia" }, | |
| { label: "Biologia", value: "biologia" }, | |
| ]; | |
| const historySubjects = [ | |
| { label: "Revoluções", value: "revoluções" }, | |
| { label: "Grécia", value: "grécia" }, | |
| { label: "Roma", value: "roma" }, | |
| { label: "Primeira Guerra Mundial", value: "primeira guerra mundial" }, | |
| { label: "Guerra Fria", value: "guerra fria" }, | |
| { label: "Feudalismo", value: "feudalismo" }, | |
| ] | |
| const biologySubjects = [ | |
| { label: "Fisiologia", value: "fisiologia" }, | |
| { label: "Embriologia", value: "embriologia" }, | |
| { label: "Citologia", value: "citologia" }, | |
| { label: "Genética", value: "genetica" }, | |
| { label: "Botânica", value: "botanica" }, | |
| { label: "Zoologia", value: "zoologia" }, | |
| { label: "Morfologia", value: "morfologia" }, | |
| { label: "Ecologia", value: "ecologia" }, | |
| { label: "Biofísica", value: "biofisica" }, | |
| ] | |
| const difficulties = [ | |
| { label: "Fácil", value: "facil" }, | |
| { label: "Intermediária", value: "intermediaria" }, | |
| { label: "Difícil", value: "dificil" }, | |
| ] | |
| const handleSubmit = async (e) => { | |
| e.preventDefault(); | |
| setIsLoading(true); | |
| try { | |
| const body = promptMode ? { promptValue } : { subject, difficultie, school_subject: schoolSubject }; | |
| const res = await fetch("/generate_questions", { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json" | |
| }, | |
| body: JSON.stringify(body) | |
| }); | |
| console.log(res) | |
| if (res.ok) { | |
| const data = await res.json(); | |
| console.log(data) | |
| setQuestions(data.rag_result.questions); | |
| setPromptValue(''); | |
| } else { | |
| toast.error("Erro ao gerar questões", { | |
| position: "top-right", | |
| autoClose: 5000, | |
| hideProgressBar: false, | |
| closeOnClick: true, | |
| pauseOnHover: true, | |
| draggable: true, | |
| progress: undefined, | |
| className: "bg-slate-900 text-white font-semibold", | |
| }); | |
| } | |
| } catch (err) { | |
| console.error(err); | |
| toast.error("Erro ao gerar questões", { | |
| position: "top-right", | |
| autoClose: 5000, | |
| hideProgressBar: false, | |
| closeOnClick: true, | |
| pauseOnHover: true, | |
| draggable: true, | |
| progress: undefined, | |
| className: "bg-slate-900 text-white font-semibold", | |
| }); | |
| } | |
| setIsLoading(false); | |
| } | |
| useEffect(() => { | |
| const handleResize = () => { | |
| if (window.innerWidth > 768) { | |
| setMenuState(true); | |
| } else { | |
| setMenuState(false); | |
| } | |
| } | |
| window.addEventListener("resize", handleResize); | |
| return () => window.removeEventListener("resize", handleResize); | |
| } | |
| , []); | |
| return ( | |
| <div className="font-sans h-screen text-white min-h-screen bg-slate-900 flex flex-col relative overflow-hidden"> | |
| <header className="p-10 flex items-center gap-2.5"> | |
| <Menu className="md:hidden" onClick={() => setMenuState(prev => !prev)} /> | |
| <h1 className="text-3xl font-bold"> | |
| Pergunt.<span className="text-transparent bg-clip-text bg-gradient-to-r from-green-300 to bg-blue-500">AÍ</span> | |
| </h1> | |
| </header> | |
| <main className="flex-1 flex overflow-hidden"> | |
| {menuState && | |
| <div className="min-w-72 p-10 flex flex-col gap-5 absolute h-full top-0 bg-black/95 md:h-fit z-10 md:static md:bg-transparent"> | |
| <div className="md:sr-only"> | |
| <ChevronLeft className="w-10 h-10" onClick={e => setMenuState(prev => !prev)} /> | |
| </div> | |
| <div className="flex items-center space-x-2"> | |
| <Switch id="prompt-mode" checked={promptMode} onCheckedChange={setPromptMode} /> | |
| <Label htmlFor="prompt-mode">Prompt Mode</Label> | |
| </div> | |
| {!promptMode && ( | |
| <form | |
| onSubmit={handleSubmit} | |
| className="flex flex-col gap-2.5 top-0 h-full "> | |
| <fieldset> | |
| <h2>Selecione uma matéria:</h2> | |
| <Select defaultValue="biologia" onValueChange={value => setSchoolSubject(value)}> | |
| <SelectTrigger className="w-[180px]"> | |
| <SelectValue placeholder="Matéria" /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| { | |
| schoolSubjects.map(({ label, value }) => ( | |
| <SelectItem key={value} value={value}>{label}</SelectItem> | |
| )) | |
| } | |
| </SelectContent> | |
| </Select> | |
| <h2>Selecione um conteúdo:</h2> | |
| <Select onValueChange={value => setSubject(value)}> | |
| <SelectTrigger className="w-[180px]"> | |
| <SelectValue placeholder="Conteúdo" /> | |
| </SelectTrigger> | |
| <SelectContent> | |
| {schoolSubjects && | |
| schoolSubject === "historia" ? | |
| historySubjects.map(({ label, value }) => ( | |
| <SelectItem key={value} value={value}>{label}</SelectItem> | |
| )) | |
| : | |
| biologySubjects.map(({ label, value }) => ( | |
| <SelectItem key={value} value={value}>{label}</SelectItem> | |
| )) | |
| } | |
| </SelectContent> | |
| </Select> | |
| <h2>Selecione uma dificuldade:</h2> | |
| <Select onValueChange={value => setDifficultie(value)}> | |
| <SelectTrigger className="w-[180px]"> | |
| <SelectValue placeholder="Dificuldade" /> | |
| </SelectTrigger> | |
| <SelectContent onChange={e => console.log(e)}> | |
| {difficulties && difficulties.map(({ label, value }) => ( | |
| <SelectItem key={value} value={value}>{label}</SelectItem> | |
| ))} | |
| </SelectContent> | |
| </Select> | |
| </fieldset> | |
| <button className="h-10 bg-purple-500 rounded px-2.5 py-1 mt-5 hover:brightness-110 transition-all flex items-center justify-center disabled:hover:brightness-75 disabled:brightness-75" | |
| disabled={isLoading || !subject || !difficultie}> | |
| {isLoading ? | |
| <div className="animate-spin h-5 w-5 border-2 border-white border-r-purple-500 rounded-full"></div> | |
| : | |
| "Enviar" | |
| } | |
| </button> | |
| </form> | |
| )} | |
| </div> | |
| } | |
| <section className="p-10 flex-1 md:border-l-2 md:border-l-white flex flex-col gap-2.5 "> | |
| {promptMode && | |
| <form | |
| onSubmit={handleSubmit}> | |
| <h2 className="text-2xl font-bold mb-5">Digite seu prompt para gerarmos as questões!</h2> | |
| <Input placeholder="Digite seu prompt:" value={promptValue} onChange={(e) => setPromptValue(e.target.value)} /> | |
| <button className="h-10 w-full bg-purple-500 rounded px-2.5 py-1 mt-5 hover:brightness-110 transition-all flex items-center justify-center disabled:hover:brightness-75 disabled:brightness-75" | |
| disabled={isLoading || !promptValue}> | |
| {isLoading ? | |
| <div className="animate-spin h-5 w-5 border-2 border-white border-r-purple-500 rounded-full"></div> | |
| : | |
| "Enviar" | |
| } | |
| </button> | |
| </form> | |
| } | |
| <h2 className="text-2xl font-bold">Questões</h2> | |
| <div className="w-full h-full flex flex-col gap-5 rounded p-2.5 overflow-y-scroll"> | |
| {questions ? | |
| questions.map(({ question, options, answer }, index) => ( | |
| <div key={index} className="bg-slate-950 ring-2 ring-white p-2.5 rounded"> | |
| {question}<br /><br /> | |
| {options.map((option, i) => ( | |
| <div key={i}> | |
| {option} | |
| </div> | |
| ))}<br /> | |
| Resposta correta: {answer} | |
| </div> | |
| )) | |
| : | |
| !promptMode && <div className="p-2.5 bg-slate-950 ring-2 ring-white rounded">Escolha os filtros para criar as questões</div> | |
| } | |
| </div> | |
| </section> | |
| <ToastContainer /> | |
| </main> | |
| </div> | |
| ) | |
| } | |
| export default App | |