"use client";
import React, { useState, useEffect, useRef } from 'react'
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip"
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu"
import MovingGradient from "@/components/animata/background/moving-gradient";
import {
Search,
Zap,
Code,
Cloud,
Link,
MapPin,
Globe,
Mic,
ArrowRight,
Github,
LucideIcon,
Server,
Palette,
Cpu,
Menu,
X,
BarChart,
CircleDot
} from "lucide-react"
import NextLink from "next/link"
import {
motion,
useScroll,
useTransform,
useSpring,
useInView,
AnimatePresence,
useAnimation
} from "framer-motion"
import { cn } from '@/lib/utils';
import { Tweet } from 'react-tweet'
import Image from 'next/image';
import { TweetGrid } from '@/components/ui/tweet-grid';
function BentoCard({
title,
icon: Icon,
description,
children,
gradient,
className,
}: {
title: string;
icon: React.ElementType;
description: string;
children?: React.ReactNode;
gradient?: string;
className?: string;
}) {
return (
);
}
const TestimonialSection: React.FC = () => {
const tweetIds = [
"1825543755748782500",
"1825876424755941787",
"1827580223606669661",
"1825574082345136506",
"1825973306924872143",
"1825821083817103852"
];
return (
);
};
function GetStarted() {
return (
);
}
function MinimalisticSearch() {
return (
Clean interface
Focused results
Distraction-free
);
}
function AIPowered() {
return (
);
}
function LightningFast() {
return (
);
}
const AboutUsSection: React.FC = () => {
return (
);
};
const MarqueeTestimonials: React.FC = () => {
const testimonials = [
"Absolutely love MiniPerplx! 🚀",
"Game-changer for my workflow. 💼",
"Simplicity at its finest. ✨",
"Can't imagine working without it now. 🙌",
"MiniPerplx is a must-have tool! 🛠️",
];
return (
{testimonials.concat(testimonials).map((text, index) => (
{text}
))}
)
}
interface FeatureCardProps {
icon: LucideIcon;
title: string;
description: string;
}
const FeatureCard: React.FC = ({ icon: Icon, title, description }) => (
{title}
{description}
)
interface Star {
x: number;
y: number;
size: number;
name: string;
category: string;
}
const TechConstellation: React.FC = () => {
const [stars, setStars] = useState([])
const [hoveredCategory, setHoveredCategory] = useState(null)
const constellationRef = useRef(null)
const techStack = [
{
category: "Core Technologies",
icon: Server,
items: ["Next.js", "React", "TypeScript", "Vercel AI SDK", "Tailwind CSS"]
},
{
category: "UI & Styling",
icon: Palette,
items: ["shadcn/ui", "Framer Motion", "Lucide Icons"]
},
{
category: "AI Services & APIs",
icon: Cpu,
items: ["Azure OpenAI", "Tavily AI", "e2b.dev", "OpenWeatherMap", "Google Maps API", "Firecrawl"]
}
];
useEffect(() => {
if (constellationRef.current) {
const { width, height } = constellationRef.current.getBoundingClientRect()
const newStars: Star[] = []
const centerX = width / 2
const centerY = height / 2
const maxRadius = Math.min(width, height) * 0.4 // 40% of the smaller dimension
techStack.forEach((category, categoryIndex) => {
const categoryAngle = (categoryIndex / techStack.length) * Math.PI * 2
const categoryRadius = maxRadius * 0.8 // 80% of maxRadius for category centers
const categoryCenterX = centerX + Math.cos(categoryAngle) * categoryRadius
const categoryCenterY = centerY + Math.sin(categoryAngle) * categoryRadius
category.items.forEach((item, index) => {
const itemAngle = categoryAngle + (index / category.items.length - 0.5) * Math.PI * 0.5
const itemRadius = Math.random() * maxRadius * 0.3 + maxRadius * 0.1 // Between 10% and 40% of maxRadius
const x = categoryCenterX + Math.cos(itemAngle) * itemRadius
const y = categoryCenterY + Math.sin(itemAngle) * itemRadius
newStars.push({
x,
y,
size: Math.random() * 2 + 2,
name: item,
category: category.category
})
})
})
setStars(newStars)
}
}, [])
const getStarColor = (category: string) => {
switch (category) {
case "Core Technologies":
return "#FFD700"
case "UI & Styling":
return "#00CED1"
case "AI Services & APIs":
return "#FF69B4"
default:
return "#FFFFFF"
}
}
return (
{stars.map((star, index) => (
{star.name}
{star.category}
))}
{hoveredCategory && (
{stars
.filter((star) => star.category === hoveredCategory)
.map((star, index, filteredStars) => {
const nextStar = filteredStars[(index + 1) % filteredStars.length]
return (
)
})}
)}
{techStack.map((category, index) => (
setHoveredCategory(category.category)}
onMouseLeave={() => setHoveredCategory(null)}
>
{category.category}
))}
)
}
interface AnimatedSectionProps {
children: React.ReactNode;
className?: string;
delay?: number;
}
const AnimatedSection: React.FC = ({ children, className, delay = 0 }) => {
const ref = useRef(null)
const isInView = useInView(ref, { once: true, margin: "-100px" })
return (
{children}
)
}
const TryButton: React.FC = () => {
return (
Try MiniPerplx
)
}
const ScrollProgress: React.FC = () => {
const { scrollYProgress } = useScroll()
const scaleX = useSpring(scrollYProgress, {
stiffness: 100,
damping: 30,
restDelta: 0.001
})
return (
)
}
const FloatingIcon: React.FC<{ Icon: LucideIcon }> = ({ Icon }) => (
)
const FloatingIcons: React.FC = () => {
const icons = [Search, Zap, Code, Cloud, Link, MapPin, Globe, Mic];
return (
{icons.map((Icon, index) => (
))}
{icons.slice(0, 4).map((Icon, index) => (
))}
)
}
const NavItem: React.FC<{ href: string; children: React.ReactNode }> = ({ href, children }) => {
return (
{children}
)
}
const MobileNavItem: React.FC<{ href: string; children: React.ReactNode; onClick: () => void }> = ({ href, children, onClick }) => {
return (
{children}
)
}
const LandingPage: React.FC = () => {
const { scrollYProgress } = useScroll()
const opacity = useTransform(scrollYProgress, [0, 0.2], [1, 0])
const scale = useTransform(scrollYProgress, [0, 0.2], [1, 0.95])
const y = useTransform(scrollYProgress, [0, 0.2], [0, -50])
const [isMenuOpen, setIsMenuOpen] = useState(false)
const toggleMenu = () => setIsMenuOpen(!isMenuOpen)
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
React.useEffect(() => {
if (isMenuOpen) {
document.body.style.overflow = 'hidden'
} else {
document.body.style.overflow = 'unset'
}
return () => {
document.body.style.overflow = 'unset'
}
}, [isMenuOpen])
useEffect(() => {
document.documentElement.style.scrollBehavior = 'smooth';
return () => {
document.documentElement.style.scrollBehavior = '';
};
}, []);
if (!mounted) return null
const features = [
{ icon: Globe, title: "Web Search", description: "Powered by Tavily AI for comprehensive web results." },
{ icon: Code, title: "Code Interpreter", description: "Utilize e2b.dev for advanced code interpretation and execution." },
{ icon: Cloud, title: "Weather Forecast", description: "Get accurate weather information via OpenWeatherMap." },
{ icon: Link, title: "URL Summary", description: "Summarize web content quickly with FireCrawl's Scrape API." },
{ icon: MapPin, title: "Location Search", description: "Find places and nearby locations using Google Maps API." },
{ icon: Mic, title: "Translation & TTS", description: "Translate text and convert to speech with OpenAI TTS." },
]
const containerVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
when: "beforeChildren",
staggerChildren: 0.1
}
}
};
const itemVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.5 }
}
};
return (
MiniPerplx
Explore
About Us
Learn more about MiniPerplx and our mission.
Features
Discover the powerful capabilities of MiniPerplx.
Tech Stack
Explore the technologies powering MiniPerplx.
Testimonials
See what others are saying about MiniPerplx.
Try It
setIsMenuOpen(!isMenuOpen)} aria-label="Toggle menu">
{isMenuOpen ? : }
{isMenuOpen && (
setIsMenuOpen(false)}>About Us
setIsMenuOpen(false)}>Features
setIsMenuOpen(false)}>Tech Stack
setIsMenuOpen(false)}>Testimonials
setIsMenuOpen(false)}>Try It
)}
Introducing MiniPerplx
A minimalistic AI search engine designed to deliver answers in the simplest and most elegant way possible.✨
Powerful Features
{features.map((feature, index) => (
))}
Our Tech Constellation
Explore the universe of technologies powering MiniPerplx. Hover over the stars to discover the constellations of our tech stack.
Ready to Experience MiniPerplx?
Discover the power of minimalistic AI search.
Try MiniPerplx
View on GitHub
)
}
export default LandingPage