Merge version_3 into main

Merge version_3 into main
This commit was merged in pull request #6.
This commit is contained in:
2026-03-08 12:41:21 +00:00
2 changed files with 140 additions and 1403 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
"use client";
import { CheckCircle, HelpCircle, MessageCircle, Sparkles, Star, TrendingUp, Users, Zap } from "lucide-react";
import { CheckCircle, HelpCircle, MessageCircle, Sparkles, Star, TrendingUp, Users, Zap, Send, MessageSquare } from "lucide-react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingInline from "@/components/navbar/NavbarLayoutFloatingInline";
import HeroSplitDoubleCarousel from "@/components/sections/hero/HeroSplitDoubleCarousel";
@@ -11,8 +11,48 @@ import TestimonialCardSix from "@/components/sections/testimonial/TestimonialCar
import TextSplitAbout from "@/components/sections/about/TextSplitAbout";
import FaqBase from "@/components/sections/faq/FaqBase";
import FooterBase from "@/components/sections/footer/FooterBase";
import { useState, useRef, useEffect } from "react";
export default function LandingPage() {
const [chatMessages, setChatMessages] = useState<Array<{ id: string; text: string; sender: 'user' | 'ai'; timestamp: Date }>>([]);
const [chatInput, setChatInput] = useState('');
const [isLoading, setIsLoading] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
scrollToBottom();
}, [chatMessages]);
const handleSendMessage = async () => {
if (!chatInput.trim()) return;
const userMessage = {
id: `msg-${Date.now()}`,
text: chatInput,
sender: 'user' as const,
timestamp: new Date(),
};
setChatMessages(prev => [...prev, userMessage]);
setChatInput('');
setIsLoading(true);
setTimeout(() => {
const aiMessage = {
id: `msg-${Date.now()}-ai`,
text: `I understand you asked: "${chatInput}". This is a simulated response. In a real implementation, this would connect to the PhysicBrain AI engine to provide physics explanations and generate simulations.`,
sender: 'ai' as const,
timestamp: new Date(),
};
setChatMessages(prev => [...prev, aiMessage]);
setIsLoading(false);
}, 1000);
};
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
@@ -118,6 +158,84 @@ export default function LandingPage() {
/>
</div>
<div id="chat" data-section="chat" className="py-16 md:py-24 px-4 md:px-8">
<div className="max-w-2xl mx-auto">
<div className="mb-8 text-center">
<h2 className="text-4xl md:text-5xl font-bold mb-4">Chat with PhysicBrain</h2>
<p className="text-lg text-foreground/70">Ask any physics question and get instant answers with simulations</p>
</div>
<div className="bg-card rounded-lg shadow-lg overflow-hidden flex flex-col h-96 md:h-[500px]">
{/* Chat messages */}
<div className="flex-1 overflow-y-auto p-6 space-y-4">
{chatMessages.length === 0 ? (
<div className="flex items-center justify-center h-full text-center">
<div>
<MessageSquare className="w-12 h-12 mx-auto mb-4 text-primary-cta/50" />
<p className="text-foreground/60">Start a conversation by asking a physics question</p>
</div>
</div>
) : (
chatMessages.map((msg) => (
<div
key={msg.id}
className={`flex ${msg.sender === 'user' ? 'justify-end' : 'justify-start'}`}
>
<div
className={`max-w-xs md:max-w-md px-4 py-2 rounded-lg ${
msg.sender === 'user'
? 'bg-primary-cta text-white'
: 'bg-background text-foreground border border-accent'
}`}
>
<p className="text-sm md:text-base">{msg.text}</p>
<p className="text-xs mt-1 opacity-70">
{msg.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
</p>
</div>
</div>
))
)}
{isLoading && (
<div className="flex justify-start">
<div className="bg-background text-foreground border border-accent px-4 py-2 rounded-lg">
<div className="flex space-x-2">
<div className="w-2 h-2 bg-primary-cta rounded-full animate-bounce"></div>
<div className="w-2 h-2 bg-primary-cta rounded-full animate-bounce delay-100"></div>
<div className="w-2 h-2 bg-primary-cta rounded-full animate-bounce delay-200"></div>
</div>
</div>
</div>
)}
<div ref={messagesEndRef} />
</div>
{/* Input area */}
<div className="border-t border-accent p-4 bg-background">
<div className="flex gap-2">
<input
type="text"
value={chatInput}
onChange={(e) => setChatInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
placeholder="Ask a physics question..."
className="flex-1 px-4 py-2 rounded-lg bg-card border border-accent text-foreground placeholder-foreground/50 focus:outline-none focus:ring-2 focus:ring-primary-cta"
disabled={isLoading}
/>
<button
onClick={handleSendMessage}
disabled={isLoading || !chatInput.trim()}
className="bg-primary-cta hover:opacity-90 disabled:opacity-50 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-opacity"
>
<Send className="w-4 h-4" />
<span className="hidden md:inline">Send</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div id="how-it-works" data-section="how-it-works">
<ProductCardFour
title="How PhysicBrain Works"
@@ -278,4 +396,4 @@ export default function LandingPage() {
</div>
</ThemeProvider>
);
}
}