|
1 | 1 | "use client";
|
2 | 2 |
|
| 3 | +import { useState, useCallback } from "react"; |
3 | 4 | import { motion } from "framer-motion";
|
4 | 5 | import SectionTitle from "../SectionTitle";
|
5 | 6 | import { useInView } from "react-intersection-observer";
|
6 |
| -import { useMemo } from "react"; |
| 7 | + |
| 8 | +const faqItems = [ |
| 9 | + { |
| 10 | + question: "Q1: What does teamwork look like?", |
| 11 | + answer: |
| 12 | + "Teamwork is a complex process where all volunteers strive to effectively carry out their assigned tasks. As a team we provide help to each other because everyone is striving for some challenges. There is no better way to learn new things than when mentored by teammate. Approximately every two weeks, we organize meetings to discuss ongoing projects, their progress, and brainstorming sessions where we share ideas about a specific project.", |
| 13 | + }, |
| 14 | + { |
| 15 | + question: "Q2: How can I join the team?", |
| 16 | + answer: |
| 17 | + "Join us by contacting via Discord, where our team interacts and discusses projects. We value not just commitment but also your interests, ideas, and diverse talents. As a member, you'll actively participate in projects, hone skills, and gain experience in a supportive setting. Be part of our exciting team journey, don't hesitate!", |
| 18 | + }, |
| 19 | + { |
| 20 | + question: "Q3: What are the benefits of joining the team?", |
| 21 | + answer: |
| 22 | + "Join our team to learn more about GitHub workflow, understand and use good programming practices like reviewing pull requests. As a team we provide many answers to not so easy questions and everyone of us is a specialist in his own field, meaning problem solving is in our nature. You'll also be able to extend your professional network, demonstrate your skills, and partake in team game competitions. (Shhh! Don't tell anyone about open source licences) Don't hesitate, join us!", |
| 23 | + }, |
| 24 | + { |
| 25 | + question: "Q4: What are the requirements for joining the team?", |
| 26 | + answer: |
| 27 | + "In addition to commitment, we require basic programming knowledge. Our training isn't comprehensive, so it's recommended to have some programming skills. Our team focuses on enhancing existing competencies to aid your professional growth. Currently, we only accept Polish-speaking individuals.", |
| 28 | + }, |
| 29 | +]; |
7 | 30 |
|
8 | 31 | export default function Faq() {
|
9 |
| - const combineVariants = useMemo( |
10 |
| - () => ({ |
11 |
| - hidden: { opacity: 0 }, |
12 |
| - show: { |
13 |
| - opacity: 1, |
14 |
| - transition: { |
15 |
| - duration: 0.3, |
16 |
| - }, |
17 |
| - }, |
18 |
| - }), |
19 |
| - [] |
20 |
| - ); |
| 32 | + const [activeIndex, setActiveIndex] = useState<number | null>(null); |
| 33 | + |
| 34 | + const toggleFaq = useCallback((index: number) => { |
| 35 | + setActiveIndex((prevIndex) => (prevIndex === index ? null : index)); |
| 36 | + }, []); |
21 | 37 |
|
22 |
| - const { ref: q1, inView: inViewFAQ1 } = useInView({ triggerOnce: false }); |
23 |
| - const { ref: q2, inView: inViewFAQ2 } = useInView({ triggerOnce: false }); |
24 |
| - const { ref: q3, inView: inViewFAQ3 } = useInView({ triggerOnce: false }); |
25 |
| - const { ref: s4, inView: inViewFAQ4 } = useInView({ triggerOnce: false }); |
26 |
| - const { ref: sectionTitle, inView: inViewTitle } = useInView({ |
27 |
| - triggerOnce: false, |
| 38 | + const { ref: sectionRef, inView: sectionInView } = useInView({ |
| 39 | + triggerOnce: true, |
| 40 | + threshold: 0.1, |
28 | 41 | });
|
29 | 42 |
|
| 43 | + const containerVariants = { |
| 44 | + hidden: { opacity: 0 }, |
| 45 | + visible: { |
| 46 | + opacity: 1, |
| 47 | + transition: { |
| 48 | + staggerChildren: 0.2, |
| 49 | + }, |
| 50 | + }, |
| 51 | + }; |
| 52 | + |
| 53 | + const itemVariants = { |
| 54 | + hidden: { opacity: 0, y: 20 }, |
| 55 | + visible: { |
| 56 | + opacity: 1, |
| 57 | + y: 0, |
| 58 | + transition: { |
| 59 | + duration: 0.5, |
| 60 | + }, |
| 61 | + }, |
| 62 | + }; |
| 63 | + |
30 | 64 | return (
|
31 | 65 | <section id="faq" className="py-16">
|
32 | 66 | <div className="mx-auto max-w-screen-xl px-4 py-8">
|
33 | 67 | <motion.div
|
34 |
| - ref={sectionTitle} |
35 |
| - variants={combineVariants} |
36 |
| - initial="hidden" |
37 |
| - animate={inViewTitle ? "show" : "hidden"} |
| 68 | + initial={{ opacity: 0, y: 20 }} |
| 69 | + animate={sectionInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }} |
| 70 | + transition={{ duration: 0.5 }} |
| 71 | + ref={sectionRef} |
38 | 72 | >
|
39 | 73 | <SectionTitle
|
40 | 74 | title="Frequently Asked Questions"
|
41 | 75 | description="Here you will find answers to the most frequently asked questions."
|
42 | 76 | />
|
43 | 77 | </motion.div>
|
44 | 78 |
|
45 |
| - <div className="mt-8 grid gap-16 pt-12 text-center lg:grid-cols-2 lg:gap-x-12 lg:gap-y-24 lg:text-left"> |
46 |
| - <motion.div |
47 |
| - className="mt-10" |
48 |
| - ref={q1} |
49 |
| - variants={combineVariants} |
50 |
| - initial="hidden" |
51 |
| - animate={inViewFAQ1 ? "show" : "hidden"} |
52 |
| - > |
53 |
| - <h3 className="text-2xl font-semibold text-gray-900 dark:text-white"> |
54 |
| - Q1: What does teamwork look like? |
55 |
| - </h3> |
56 |
| - <p className="mt-3 text-gray-500 dark:text-gray-400"> |
57 |
| - Teamwork is a complex process where all volunteers strive to |
58 |
| - effectively carry out their assigned tasks. Approximately every |
59 |
| - two weeks, we organize meetings to discuss ongoing projects, their |
60 |
| - progress, and brainstorming sessions where we share ideas about a |
61 |
| - specific project. |
62 |
| - </p> |
63 |
| - </motion.div> |
64 |
| - |
65 |
| - <motion.div |
66 |
| - className="mt-10" |
67 |
| - ref={q2} |
68 |
| - variants={combineVariants} |
69 |
| - initial="hidden" |
70 |
| - animate={inViewFAQ2 ? "show" : "hidden"} |
71 |
| - > |
72 |
| - <h3 className="text-2xl font-semibold text-gray-900 dark:text-white"> |
73 |
| - Q2: How can I join the team? |
74 |
| - </h3> |
75 |
| - <p className="mt-3 text-gray-500 dark:text-gray-400"> |
76 |
| - Join us by contacting via Discord, where our team interacts and |
77 |
| - discusses projects. We value not just commitment but also your |
78 |
| - interests, ideas, and diverse talents. As a member, you'll |
79 |
| - actively participate in projects, hone skills, and gain experience |
80 |
| - in a supportive setting. Be part of our exciting team journey, |
81 |
| - don't hesitate! |
82 |
| - </p> |
83 |
| - </motion.div> |
84 |
| - |
85 |
| - <motion.div |
86 |
| - className="mt-10" |
87 |
| - ref={q3} |
88 |
| - variants={combineVariants} |
89 |
| - initial="hidden" |
90 |
| - animate={inViewFAQ3 ? "show" : "hidden"} |
91 |
| - > |
92 |
| - <h3 className="text-2xl font-semibold text-gray-900 dark:text-white"> |
93 |
| - Q3: What are the benefits of joining the team? |
94 |
| - </h3> |
95 |
| - <p className="mt-3 text-gray-500 dark:text-gray-400"> |
96 |
| - Joining us provides valuable experience and has led previous |
97 |
| - members to their dream IT roles. You'll also be able to extend |
98 |
| - your professional network, demonstrate your skills, and partake in |
99 |
| - team game competitions. Don't hesitate, join us! |
100 |
| - </p> |
101 |
| - </motion.div> |
102 |
| - |
103 |
| - <motion.div |
104 |
| - className="mt-10" |
105 |
| - ref={s4} |
106 |
| - variants={combineVariants} |
107 |
| - initial="hidden" |
108 |
| - animate={inViewFAQ4 ? "show" : "hidden"} |
109 |
| - > |
110 |
| - <h3 className="text-2xl font-semibold text-gray-900 dark:text-white"> |
111 |
| - Q4: What are the requirements for joining the team? |
112 |
| - </h3> |
113 |
| - <p className="mt-3 text-gray-500 dark:text-gray-400"> |
114 |
| - In addition to commitment, we require basic programming knowledge. |
115 |
| - Our training isn't comprehensive, so it's recommended to have some |
116 |
| - programming skills. Our team focuses on enhancing existing |
117 |
| - competencies to aid your professional growth. Currently, we only |
118 |
| - accept Polish-speaking individuals. |
119 |
| - </p> |
120 |
| - </motion.div> |
121 |
| - </div> |
| 79 | + <motion.div |
| 80 | + className="mt-12" |
| 81 | + variants={containerVariants} |
| 82 | + initial="hidden" |
| 83 | + animate={sectionInView ? "visible" : "hidden"} |
| 84 | + > |
| 85 | + {faqItems.map((item, index) => ( |
| 86 | + <motion.div |
| 87 | + key={index} |
| 88 | + variants={itemVariants} |
| 89 | + className="mb-6 overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700" |
| 90 | + > |
| 91 | + <button |
| 92 | + onClick={() => toggleFaq(index)} |
| 93 | + className="flex w-full items-center justify-between bg-[#f0f1f2] px-6 py-4 text-left text-lg font-medium text-gray-800 transition-colors duration-300 hover:bg-[#e6e7e8] dark:bg-[#1F2A37] dark:text-white dark:hover:bg-[#374151]" |
| 94 | + aria-expanded={activeIndex === index} |
| 95 | + aria-controls={`faq-panel-${index}`} |
| 96 | + > |
| 97 | + <span>{item.question}</span> |
| 98 | + <svg |
| 99 | + className={`h-6 w-6 transform transition-transform duration-300 ${activeIndex === index ? "rotate-180" : ""}`} |
| 100 | + fill="none" |
| 101 | + viewBox="0 0 24 24" |
| 102 | + stroke="currentColor" |
| 103 | + > |
| 104 | + <path |
| 105 | + strokeLinecap="round" |
| 106 | + strokeLinejoin="round" |
| 107 | + strokeWidth={2} |
| 108 | + d="M19 9l-7 7-7-7" |
| 109 | + /> |
| 110 | + </svg> |
| 111 | + </button> |
| 112 | + <div |
| 113 | + className={`overflow-hidden transition-all duration-300 ease-in-out ${activeIndex === index ? "max-h-96" : "max-h-0"}`} |
| 114 | + id={`faq-panel-${index}`} |
| 115 | + > |
| 116 | + <div className="bg-[#f5f6f7] p-6 text-gray-700 dark:bg-[#1F2A37] dark:text-gray-400"> |
| 117 | + {item.answer} |
| 118 | + </div> |
| 119 | + </div> |
| 120 | + </motion.div> |
| 121 | + ))} |
| 122 | + </motion.div> |
122 | 123 | </div>
|
123 | 124 | </section>
|
124 | 125 | );
|
|
0 commit comments