ai-flash-card / src / app / flashcards / page.tsx
page.tsx
Raw
"use client";

import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import "./flashcard.css";
import Navbar from '../../components/navbar';

export default function Flashcards() {
  const router = useRouter();
  const [parsedText, setParsedText] = useState<string | undefined>(undefined);
  const [flashcardType, setFlashcardType] = useState<'flashcard' | 'definition'>('flashcard');
  const [response, setResponse] = useState<{ question: string, answer: string } | undefined>(undefined);
  const [loading, setLoading] = useState<boolean>(false);
  const [cards, setCards] = useState<React.ReactElement[]>([]);
  const [isScattered, setIsScattered] = useState(false);

  useEffect(() => {
    if (response) {
      // Add the new card with the parsed content
      addNewCard(response.question, response.answer);
    }
  }, [response]);

  useEffect(() => {
    setTimeout(() => {
      setIsScattered(true);
    }, 1);
  }, []);

  const removeTopCard = () => {
    setCards((prevCards) => {
      if (prevCards.length === 0) return prevCards;

      const newCards = [...prevCards];
      const topCard = newCards.pop();
      console.log("Removing top card:", topCard);

      if (topCard) {
        newCards.push(
          React.cloneElement(topCard, { className: "card is-offscreen--l" })
        );
        setTimeout(() => {
          setCards(newCards.slice(0, newCards.length - 1));
        }, 500);
      }

      return newCards;
    });
  };

  const addNewCard = (question: string, answer: string) => {
    const newCard = (
      <div className="card is-offscreen--r absolute top-0 left-0 w-full h-full bg-white shadow-md transition-all duration-500 ease-in-out">
        <header className="card-header">
          <h3>{question}</h3>
        </header>
        <div className="card-body">{answer}</div>
      </div>
    );
    setCards((prevCards) => [...prevCards, newCard]);
    setTimeout(() => {
      setCards((prevCards) => {
        const newCards = [...prevCards];
        if (newCards.length > 0) {
          newCards[newCards.length - 1] = React.cloneElement(newCard, {
            className: "card",
          });
        }
        return newCards;
      });
    }, 1);
  };

  const generateFlashcard = async () => {
    if (!parsedText) return;

    setLoading(true);

    try {
      const res = await fetch('/api/flashcard-generator', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ prompt: parsedText, type: flashcardType }),
      });

      if (res.ok) {
        const result = await res.json();
        setResponse(result);
      } else {
        console.error('Error generating flashcards');
      }
    } catch (error) {
      console.error('Error:', error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    const { searchParams } = new URL(window.location.href);
    const parsedTextParam = searchParams.get('parsedText');
    if (parsedTextParam) {
      setParsedText(decodeURIComponent(parsedTextParam));
    }
  }, []);

  return (
    <div>
      <Navbar is_game={false}/>
          <div className="flex flex-col items-center pt-7 bg-gradient">
            <div className="button-container">
              <button
                onClick={generateFlashcard}
                className="add-card-button"
                disabled={loading}
              >
                {loading ? 'Generating...' : '+'}
              </button>
              <button
                onClick={removeTopCard}
                className="remove-card-button"
              >
                -
              </button>
            </div>
            <div
              className={`relative w-72 h-48 mt-24 ${isScattered ? "is-scattered" : ""}`}
            >
              {cards.map((card, index) => {
                console.log("Rendering card:", card);
                return React.cloneElement(card, { key: index });
              })}
            </div>
          </div>
          </div>
        
  );
}