Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
331 changes: 244 additions & 87 deletions savebook/app/faq/page.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,111 @@
"use client";

import { useState } from "react";
import { useMemo, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ChevronDown, HelpCircle } from "lucide-react";
import {
ChevronDown,
HelpCircle,
Search,
Star,
ShieldCheck,
Smartphone,
Mail,
MessageCircle,
ExternalLink,
BookOpen,
LifeBuoy,
Sparkles,
FolderKanban,
Github,
Clock3,
} from "lucide-react";

const faqs = [
const faqGroups = [
{
question: "What is SaveBook?",
answer:
"SaveBook is a high-performance, modern web application designed for note-taking and knowledge management. It provides a fast, intuitive, and clutter-free environment for organizing your digital life.",
title: "Getting Started",
icon: <BookOpen className="w-5 h-5" />,
faqs: [
{
question: "What is SaveBook?",
answer:
"SaveBook is a modern note-taking and knowledge management platform built for speed, productivity, and simplicity.",
popular: true,
},
{
question: "Do I need an account to use SaveBook?",
answer:
"You can browse without an account, but signing in enables sync and backups.",
},
],
},
{
question: "Do I need an account to use SaveBook?",
answer:
"You can explore SaveBook without an account, but creating a free account lets you securely save your notes to the cloud and access them from any device.",
title: "Features",
icon: <Sparkles className="w-5 h-5" />,
faqs: [
{
question: "Is my data saved automatically?",
answer:
"Yes, SaveBook auto-saves everything in real time.",
popular: true,
},
{
question: "Does SaveBook support dark mode?",
answer:
"Yes, it fully supports system-based dark mode.",
},
],
},
{
question: "How do I create a new note?",
answer:
"Once logged in, navigate to the Notes section and click the 'Add Note' button. You can then write, format, and save your note instantly.",
title: "Security",
icon: <ShieldCheck className="w-5 h-5" />,
faqs: [
{
question: "Is SaveBook free?",
answer: "Yes, core features are completely free.",
popular: true,
},
{
question: "How secure is my data?",
answer:
"All data is encrypted and stored securely.",
},
],
},
];

const quickLinks = [
{
title: "Documentation",
icon: <BookOpen className="w-5 h-5" />,
href: "/docs",
},
{
question: "Is my data saved automatically?",
answer:
"Yes! SaveBook auto-saves your notes as you type, so you never have to worry about losing your work.",
title: "Community",
icon: <MessageCircle className="w-5 h-5" />,
href: "/community",
},
{
question: "Can I access my notes on mobile?",
answer:
"Absolutely. SaveBook is fully responsive and works seamlessly across mobile, tablet, and desktop devices.",
title: "GitHub",
icon: <Github className="w-5 h-5" />,
href: "https://github.com/HarshYadav152/SaveBook",
},
{
question: "How do I organize my notes?",
answer:
"You can organize notes using tags and categories available in your notes dashboard. This makes it easy to find any note quickly.",
title: "Dashboard",
icon: <FolderKanban className="w-5 h-5" />,
href: "/notes",
},
];

const stats = [
{
question: "Is SaveBook free to use?",
answer:
"Yes, SaveBook is completely free. Create an account and start managing your notes at no cost.",
title: "Auto Save Time",
value: "Real-time",
icon: <Clock3 className="w-6 h-6" />,
},
{
question: "How do I report a bug or suggest a feature?",
answer:
"You can open an issue on our GitHub repository at github.com/HarshYadav152/SaveBook. We welcome all feedback and contributions!",
title: "Platforms",
value: "All Devices",
icon: <Smartphone className="w-6 h-6" />,
},
];

Expand All @@ -52,24 +114,33 @@ function FAQItem({ faq, index }) {

return (
<motion.div
initial={{ opacity: 0, y: 20 }}
initial={{ opacity: 0, y: 18 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, delay: index * 0.07 }}
className="border border-gray-200 dark:border-gray-700 rounded-xl overflow-hidden"
transition={{ duration: 0.3, delay: index * 0.05 }}
className="border border-border rounded-2xl bg-card shadow-sm overflow-hidden"
>
<button
onClick={() => setIsOpen(!isOpen)}
className="w-full flex items-center justify-between px-6 py-5 text-left bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-all"
className="w-full flex justify-between items-center px-6 py-5 text-left hover:bg-muted transition"
>
<span className="font-semibold text-gray-900 dark:text-white pr-4">
{faq.question}
</span>
<motion.div
animate={{ rotate: isOpen ? 180 : 0 }}
transition={{ duration: 0.3 }}
className="flex-shrink-0"
>
<ChevronDown className="w-5 h-5 text-blue-500" />
<div className="flex items-start gap-3">
<HelpCircle className="w-5 h-5 text-primary mt-1" />
<div>
<h3 className="text-base md:text-lg font-semibold text-foreground">
{faq.question}
</h3>

{faq.popular && (
<span className="inline-flex items-center gap-1 mt-1 text-xs px-2 py-1 rounded-full bg-yellow-500/10 text-yellow-500">
<Star className="w-3 h-3" />
Popular
</span>
)}
</div>
</div>

<motion.div animate={{ rotate: isOpen ? 180 : 0 }}>
<ChevronDown className="w-5 h-5 text-primary" />
</motion.div>
</button>

Expand All @@ -79,74 +150,160 @@ function FAQItem({ faq, index }) {
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3 }}
className="px-6 py-5 border-t border-border bg-muted/40"
>
<div className="px-6 py-4 bg-gray-50 dark:bg-gray-800/50 border-t border-gray-200 dark:border-gray-700">
<p className="text-gray-600 dark:text-gray-400 leading-relaxed">
{faq.answer}
</p>
</div>
<p className="text-muted-foreground leading-7">
{faq.answer}
</p>
</motion.div>
)}
</AnimatePresence>
</motion.div>
);
}

function SupportCard({ icon, title, text, buttonText, href }) {
return (
<div className="p-6 rounded-2xl border border-border bg-card shadow-sm hover:shadow-md transition">
<div className="w-12 h-12 flex items-center justify-center rounded-xl bg-primary/10 text-primary mb-4">
{icon}
</div>

<h3 className="text-lg font-semibold text-foreground mb-2">
{title}
</h3>

<p className="text-sm text-muted-foreground mb-4 leading-6">
{text}
</p>

<a
href={href}
className="inline-flex items-center gap-2 text-primary font-medium hover:gap-3 transition"
>
{buttonText}
<ExternalLink className="w-4 h-4" />
</a>
</div>
);
}

export default function FAQPage() {
const [search, setSearch] = useState("");

const filteredGroups = useMemo(() => {
return faqGroups
.map((group) => ({
...group,
faqs: group.faqs.filter(
(f) =>
f.question.toLowerCase().includes(search.toLowerCase()) ||
f.answer.toLowerCase().includes(search.toLowerCase())
),
}))
.filter((g) => g.faqs.length > 0);
}, [search]);

return (
<div className="min-h-screen">
<div className="container mx-auto max-w-3xl px-4 py-16">
{/* Header */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
className="text-center mb-12"
>
<div className="flex justify-center mb-4">
<div className="p-3 bg-blue-50 dark:bg-blue-900/20 rounded-full">
<HelpCircle className="w-8 h-8 text-blue-500" />
</div>
</div>
<h1 className="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
<div className="min-h-screen bg-background text-foreground pt-24">
<div className="container mx-auto px-4 max-w-6xl">

{/* HERO */}
<div className="text-center">
<HelpCircle className="w-12 h-12 mx-auto text-primary mb-4" />

<h1 className="text-4xl md:text-5xl font-bold">
Frequently Asked Questions
</h1>
<p className="text-gray-600 dark:text-gray-400 text-lg">

<p className="text-muted-foreground mt-4">
Everything you need to know about SaveBook
</p>
</motion.div>

{/* FAQ Items */}
<div className="space-y-3">
{faqs.map((faq, index) => (
<FAQItem key={index} faq={faq} index={index} />
{/* SEARCH */}
<div className="relative mt-8 max-w-xl mx-auto">
<Search className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search FAQs..."
className="w-full pl-10 pr-4 py-3 rounded-xl border border-border bg-card"
/>
</div>
</div>

{/* STATS */}
<div className="grid md:grid-cols-2 gap-4 mt-10">
{stats.map((s, i) => (
<div
key={i}
className="p-6 rounded-2xl border border-border bg-card"
>
<div className="text-primary mb-2">{s.icon}</div>
<h3 className="text-xl font-bold">{s.value}</h3>
<p className="text-muted-foreground text-sm">{s.title}</p>
</div>
))}
</div>

{/* Footer CTA */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.5 }}
className="mt-12 p-6 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-xl text-center"
>
<p className="text-blue-700 dark:text-blue-400 font-medium mb-1">
Still have questions?
</p>
<p className="text-blue-600 dark:text-blue-500 text-sm">
Open an issue on our{" "}
{/* QUICK LINKS */}
<div className="flex flex-wrap gap-3 justify-center mt-10">
{quickLinks.map((l, i) => (
<a
href="https://github.com/HarshYadav152/SaveBook/issues"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-blue-800 dark:hover:text-blue-300 transition-colors"
key={i}
href={l.href}
className="flex items-center gap-2 px-4 py-2 rounded-xl border border-border bg-card hover:bg-muted transition"
>
GitHub repository
{l.icon}
{l.title}
</a>
. We're happy to help!
</p>
</motion.div>
))}
</div>

{/* FAQ */}
<div className="mt-12 space-y-10">
{filteredGroups.map((g, i) => (
<div key={i}>
<h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
{g.icon}
{g.title}
</h2>

<div className="space-y-4">
{g.faqs.map((f, idx) => (
<FAQItem key={idx} faq={f} index={idx} />
))}
</div>
</div>
))}
</div>

{/* SUPPORT */}
<div className="grid md:grid-cols-3 gap-6 mt-16">
<SupportCard
icon={<Mail className="w-6 h-6" />}
title="Email Support"
text="Get help from our support team."
buttonText="Contact"
href="mailto:support@savebook.app"
/>

<SupportCard
icon={<Github className="w-6 h-6" />}
title="GitHub Issues"
text="Report bugs or request features."
buttonText="Open"
href="https://github.com/HarshYadav152/SaveBook/issues"
/>

<SupportCard
icon={<MessageCircle className="w-6 h-6" />}
title="Community"
text="Connect with other users."
buttonText="Join"
href="/community"
/>
</div>
</div>
</div>
);
Expand Down