import React, { useState, useEffect } from 'react'; import { Heart, X, BookOpen, Users, User, ChevronLeft, ChevronRight, MessageSquare } from 'lucide-react'; export default function BookDatingApp() { // Sample book data const initialBooks = [ { id: 1, title: "Pride and Prejudice", author: "Jane Austen", year: 1813, genre: ["Romance", "Classic"], personality: ["Witty", "Romantic", "Social Commentary"], description: "A romantic novel of manners that follows the character development of Elizabeth Bennet, who learns about the repercussions of hasty judgments.", lookingFor: ["Historical Fiction", "Social Commentary", "Character-driven"], image: "https://images.unsplash.com/photo-1544947950-fa07a98d237f?q=80&w=1000&auto=format&fit=crop" }, { id: 2, title: "1984", author: "George Orwell", year: 1949, genre: ["Dystopian", "Political Fiction"], personality: ["Dark", "Thought-provoking", "Political"], description: "A dystopian social science fiction novel that examines the consequences of totalitarianism, mass surveillance, and repressive regimentation.", lookingFor: ["Philosophical", "Dystopian", "Political"], image: "https://images.unsplash.com/photo-1541963463532-d68292c34b19?q=80&w=1000&auto=format&fit=crop" }, { id: 3, title: "The Great Gatsby", author: "F. Scott Fitzgerald", year: 1925, genre: ["Tragedy", "Social Commentary"], personality: ["Glamorous", "Melancholic", "Observant"], description: "A novel that depicts the lavish lifestyle of wealthy Americans during the Jazz Age, exploring themes of decadence, idealism, and the American Dream.", lookingFor: ["Period Drama", "Character Study", "Literary Fiction"], image: "https://images.unsplash.com/photo-1543002588-bfa74002ed7e?q=80&w=1000&auto=format&fit=crop" }, { id: 4, title: "To Kill a Mockingbird", author: "Harper Lee", year: 1960, genre: ["Coming-of-age", "Legal Drama"], personality: ["Compassionate", "Moral", "Insightful"], description: "A novel examining racial injustice and moral growth in the American South during the 1930s, told through the eyes of a young girl.", lookingFor: ["Historical Fiction", "Social Justice", "Southern Gothic"], image: "https://images.unsplash.com/photo-1476275466078-4007374efbbe?q=80&w=1000&auto=format&fit=crop" }, { id: 5, title: "The Hobbit", author: "J.R.R. Tolkien", year: 1937, genre: ["Fantasy", "Adventure"], personality: ["Adventurous", "Whimsical", "Brave"], description: "A fantasy novel about the quest of home-loving Bilbo Baggins, who is convinced by the wizard Gandalf to join a group of dwarves to reclaim their mountain home.", lookingFor: ["Epic Fantasy", "Adventure", "Hero's Journey"], image: "https://images.unsplash.com/photo-1629992101753-56d196c8aabb?q=80&w=1000&auto=format&fit=crop" }, { id: 6, title: "Moby-Dick", author: "Herman Melville", year: 1851, genre: ["Adventure", "Epic"], personality: ["Obsessive", "Philosophical", "Complex"], description: "The narrative tells the story of the obsessive quest of Captain Ahab for revenge on Moby Dick, the white whale that bit off his leg.", lookingFor: ["Philosophical", "Epic", "Maritime"], image: "https://images.unsplash.com/photo-1589998059171-988d887df646?q=80&w=1000&auto=format&fit=crop" }, { id: 7, title: "Jane Eyre", author: "Charlotte Brontë", year: 1847, genre: ["Gothic", "Romance"], personality: ["Independent", "Passionate", "Resilient"], description: "A novel that follows the emotions and experiences of its title character, including her growth to adulthood and her love for Mr. Rochester.", lookingFor: ["Gothic Romance", "Character-driven", "Victorian"], image: "https://images.unsplash.com/photo-1512820790803-83ca734da794?q=80&w=1000&auto=format&fit=crop" } ]; // State const [books, setBooks] = useState(initialBooks); const [currentIndex, setCurrentIndex] = useState(0); const [matches, setMatches] = useState([]); const [likedBooks, setLikedBooks] = useState([]); const [activeTab, setActiveTab] = useState('browse'); const [selectedMatch, setSelectedMatch] = useState(null); const [newBook, setNewBook] = useState({ title: "", author: "", year: "", genre: [], personality: [], description: "", lookingFor: [], image: "https://images.unsplash.com/photo-1543002588-bfa74002ed7e?q=80&w=1000&auto=format&fit=crop" }); const [showNewBookForm, setShowNewBookForm] = useState(false); const [newGenre, setNewGenre] = useState(""); const [newPersonality, setNewPersonality] = useState(""); const [newLookingFor, setNewLookingFor] = useState(""); const [messages, setMessages] = useState({}); // Load data from localStorage on initial render useEffect(() => { const savedLikedBooks = localStorage.getItem('likedBooks'); const savedMatches = localStorage.getItem('matches'); const savedMessages = localStorage.getItem('messages'); if (savedLikedBooks) setLikedBooks(JSON.parse(savedLikedBooks)); if (savedMatches) setMatches(JSON.parse(savedMatches)); if (savedMessages) setMessages(JSON.parse(savedMessages)); }, []); // Save data to localStorage when it changes useEffect(() => { localStorage.setItem('likedBooks', JSON.stringify(likedBooks)); localStorage.setItem('matches', JSON.stringify(matches)); localStorage.setItem('messages', JSON.stringify(messages)); }, [likedBooks, matches, messages]); // Calculate compatibility between two books const calculateCompatibility = (book1, book2) => { let score = 0; // Check genre compatibility const genreMatch = book1.lookingFor.some(g => book2.genre.includes(g)); if (genreMatch) score += 30; // Check personality compatibility const personalityMatch = book1.personality.some(p => book2.lookingFor.includes(p)); if (personalityMatch) score += 30; // Time period compatibility (books from similar eras) const yearDiff = Math.abs(book1.year - book2.year); if (yearDiff < 20) score += 20; else if (yearDiff < 50) score += 10; // Add some randomness score += Math.floor(Math.random() * 20); // Cap at 100 return Math.min(score, 100); }; // Handle like action const handleLike = () => { const currentBook = books[currentIndex]; // Add to liked books setLikedBooks(prev => [...prev, currentBook]); // Check for matches with other books books.forEach(book => { if (book.id !== currentBook.id) { const compatibility = calculateCompatibility(currentBook, book); if (compatibility > 70) { // It's a match! const matchExists = matches.some( m => (m.book1.id === currentBook.id && m.book2.id === book.id) || (m.book1.id === book.id && m.book2.id === currentBook.id) ); if (!matchExists) { const newMatch = { id: `${currentBook.id}-${book.id}`, book1: currentBook, book2: book, compatibility: compatibility, date: new Date().toISOString() }; setMatches(prev => [...prev, newMatch]); // Initialize empty message thread for this match setMessages(prev => ({ ...prev, [newMatch.id]: [] })); } } } }); // Move to next book if (currentIndex < books.length - 1) { setCurrentIndex(currentIndex + 1); } }; // Handle dislike action const handleDislike = () => { if (currentIndex < books.length - 1) { setCurrentIndex(currentIndex + 1); } }; // Handle adding a new book const handleAddBook = (e) => { e.preventDefault(); const bookToAdd = { ...newBook, id: Date.now(), }; setBooks(prev => [...prev, bookToAdd]); setNewBook({ title: "", author: "", year: "", genre: [], personality: [], description: "", lookingFor: [], image: "https://images.unsplash.com/photo-1543002588-bfa74002ed7e?q=80&w=1000&auto=format&fit=crop" }); setShowNewBookForm(false); }; // Handle adding tags to new book const handleAddGenre = () => { if (newGenre.trim() !== "") { setNewBook(prev => ({ ...prev, genre: [...prev.genre, newGenre.trim()] })); setNewGenre(""); } }; const handleAddPersonality = () => { if (newPersonality.trim() !== "") { setNewBook(prev => ({ ...prev, personality: [...prev.personality, newPersonality.trim()] })); setNewPersonality(""); } }; const handleAddLookingFor = () => { if (newLookingFor.trim() !== "") { setNewBook(prev => ({ ...prev, lookingFor: [...prev.lookingFor, newLookingFor.trim()] })); setNewLookingFor(""); } }; // Handle sending a message const handleSendMessage = (matchId, message) => { if (message.trim() === "") return; setMessages(prev => ({ ...prev, [matchId]: [...(prev[matchId] || []), { id: Date.now(), text: message, sender: "user", timestamp: new Date().toISOString() }] })); // Simulate a response from the matched book setTimeout(() => { const match = matches.find(m => m.id === matchId); const respondingBook = match.book1.id === books[currentIndex]?.id ? match.book2 : match.book1; let response; switch (respondingBook.personality[0]) { case "Witty": response = "How delightfully unexpected to receive your message! Shall we discuss the finer points of societal expectations?"; break; case "Dark": response = "Your message has been recorded by the Ministry of Truth. Thoughtcrime is death. But hello to you too."; break; case "Glamorous": response = "Old sport! Wonderful to hear from you. Care to join me for a party at my West Egg mansion?"; break; case "Compassionate": response = "It's a sin to kill a mockingbird, but never a sin to chat with a fellow book. How are you?"; break; case "Adventurous": response = "I wasn't expecting visitors or adventures today, but I suppose a good conversation is its own adventure!"; break; case "Obsessive": response = "Call me interested. Let us dive deep into the white waters of literary conversation."; break; case "Independent": response = "Reader, I'm glad to make your acquaintance. Let us converse as equals."; break; default: response = "How lovely to receive your message! What shall we discuss today?"; } setMessages(prev => ({ ...prev, [matchId]: [...prev[matchId], { id: Date.now(), text: response, sender: "match", timestamp: new Date().toISOString() }] })); }, 1000); }; // Render book browsing interface const renderBrowseBooks = () => { if (books.length === 0 || currentIndex >= books.length) { return (
You've seen all the available books. Add more books or check your matches.
{currentBook.description}
Keep browsing to find perfect matches for your books.
by {match.book1.author}
by {match.book2.author}
by {selectedMatch.book1.author}
by {selectedMatch.book2.author}
These books share complementary themes and styles. {selectedMatch.book1.genre.some(g => selectedMatch.book2.lookingFor.includes(g)) && ` ${selectedMatch.book1.title} offers the ${selectedMatch.book1.genre.find(g => selectedMatch.book2.lookingFor.includes(g))} that ${selectedMatch.book2.title} is looking for.`} {selectedMatch.book2.genre.some(g => selectedMatch.book1.lookingFor.includes(g)) && ` ${selectedMatch.book2.title} provides the ${selectedMatch.book2.genre.find(g => selectedMatch.book1.lookingFor.includes(g))} elements that ${selectedMatch.book1.title} desires.`} {Math.abs(selectedMatch.book1.year - selectedMatch.book2.year) < 50 && ` They were published in similar time periods, only ${Math.abs(selectedMatch.book1.year - selectedMatch.book2.year)} years apart.`}
{msg.text}
{new Date(msg.timestamp).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
by {book.author}
{book.description}
Where books find their perfect match