pages/Projects.jsx

import {useTranslation} from 'react-i18next';
import {Card} from "../components/ui/Card";
import {CardContent} from "../components/ui/CardContent";
import {Disclosure} from '@headlessui/react';
import {ChevronDown} from 'lucide-react';
import {useState} from "react";
import PageSection from "../components/ui/PageSection";
import {ExpandableText} from "../components/ui/ExpandableText";
import {AnimatePresence, motion} from "framer-motion";

/**
 * Projects component displays a list of projects grouped by company.
 *
 * Features:
 * - Sidebar with buttons to filter projects by company.
 * - Shows project details including name, company, period, type, and technologies used.
 * - Each project has a collapsible panel to toggle visibility of technology stack.
 * - Uses i18n translation for UI texts and project types.
 *
 * @component
 * @module pages/Projects
 * @returns {JSX.Element} Rendered Projects section with filtering and collapsible tech details.
 */
export default function Projects() {
    const {t} = useTranslation();
    const [selectedCompany, setSelectedCompany] = useState("RGI");
    const [page, setPage] = useState(1);
    const itemsPerPage = 2;

    const projects = [
        {
            name: "Passportal client",
            tech: "MySQL · REST APIs · SQL · JSON · JBoss Application Server · HTML · Docker · Node.js · HTML5 · JEE · AngularJS · Git · Java · Maven · OOP · JavaScript · CSS · XML",
            type: "Enterprise Application",
            company: "RGI",
            period: "03/2023"
        },
        {
            name: "HalfLife",
            tech: "MySQL · REST APIs · SQL · JSON · JBoss Application Server · HTML · Docker · Node.js · HTML5 · JEE · AngularJS · Git · Java · Maven · OOP · JavaScript · CSS · XML",
            type: "Enterprise Application",
            company: "RGI",
            period: "01/2023 - 03/2023"
        },
        {
            name: "AXA Mobility",
            tech: "MySQL · REST APIs · SQL · JSON · JBoss Application Server · HTML · Docker · Node.js · HTML5 · JEE · AngularJS · Git · Maven · OOP · JavaScript · CSS · XML",
            type: "Mobility Portal",
            company: "RGI",
            period: "03/2022 - 01/2023"
        },
        {
            name: "Group Policy Library",
            tech: "MySQL · REST APIs · SQL · JSON · JBoss Application Server · HTML · Docker · Node.js · HTML5 · JEE · AngularJS · Git · Maven · OOP · JavaScript · CSS · XML",
            type: "UI Library",
            company: "RGI",
            period: "02/2022 - 05/2022"
        },
        {
            name: "AfterLife",
            tech: "MySQL · REST APIs · SQL · JSON · JBoss Application Server · HTML · Docker · Node.js · HTML5 · JEE · AngularJS · Git · Maven · OOP · JavaScript · CSS · XML",
            type: "Insurance Web Portal",
            company: "RGI",
            period: "09/2021 - 02/2022"
        },
        {
            name: "Area Clienti ",
            tech: " MySQL · REST APIs · SQL · JSON · Hibernate · JBoss Application Server · HTML · Docker · Node.js · HTML5 · JEE · AngularJS · Git · Java · Maven · OOP · JavaScript · Tomcat · Machine learning · CSS · Framework Spring · XML",
            type: "areaClienti",
            company: "Italiaonline",
            period: "05/2019 - 09/2021"
        },
        {
            name: "IDB rest services",
            tech: "MySQL · REST APIs · SQL · JSON · Hibernate · JBoss Application Server · JEE · Git · Java · Maven · OOP · Tomcat · XML",
            type: "restServices",
            company: "Italiaonline",
            period: "07/2019 - 09/2021"
        },
        {
            name: "2In1App",
            tech: "MySQL · REST APIs · SQL · React Native · Git · Java · Android · OOP · XML",
            type: "Hybrid Mobile App",
            company: "TECNAVIA APPS s.r.l.",
            period: "07/2018 - 05/2019"
        },
        {
            name: "Newsmemory",
            tech: "MySQL · REST APIs · SQL · PHP · JSON · HTML · HTML5 · Eclipse · Git · SQLite · OOP · JavaScript · CSS · jQuery · XML",
            type: "Newspaper CMS",
            company: "TECNAVIA APPS s.r.l.",
            period: "07/2018 - 05/2019"
        },
        {
            name: "DART",
            tech: "MySQL · REST APIs · SQL · JSON · Hibernate · JBoss Application Server · HTML · Node.js · HTML5 · JEE · AngularJS · Git · Maven · OOP · JavaScript · Tomcat · CSS · jQuery · Spring · XML",
            type: "dart",
            company: "Teoresi",
            period: "10/2017 - 07/2018"
        },
        {
            name: "io.T Tecno",
            tech: "MySQL · REST APIs · SQL · JSON · Hibernate · JBoss Application Server · HTML · Node.js · HTML5 · JEE· AngularJS · Git · Maven · OOP · JavaScript · Tomcat · CSS · jQuery · Spring · XML",
            type: "IoT Workplace Booking",
            company: "Teoresi",
            period: "10/2017 - 07/2018"
        },
        {
            name: "OSS Trasformation",
            tech: "MySQL · REST APIs · JSON · JBoss Application Server · HTML · Node.js · HTML5 · JEE · AngularJS · Git· OOP · JavaScript · CSS · jQuery · XML",
            type: "Enterprise Portal",
            company: "Fastweb",
            period: "09/2016 - 10/2017"
        },
        {
            name: "OLO Gateway",
            tech: "MySQL · REST APIs · JSON · JBoss Application Server · HTML · Node.js · HTML5 · JEE · AngularJS · Git· OOP · JavaScript · CSS · jQuery · XML",
            type: "Enterprise Portal",
            company: "Fastweb",
            period: "09/2016 - 10/2017"
        }
    ];

    const companies = [...new Set(projects.map(p => p.company))];

    const groupedProjects = projects.reduce((acc, proj) => {
        acc[proj.company] = acc[proj.company] || [];
        acc[proj.company].push(proj);
        return acc;
    }, {});

    return (
        <PageSection title={t("projects_title")}>
            <div className="flex flex-col md:flex-row gap-6">
                {/* Sidebar Tabs */}
                <div className="md:w-1/4 flex flex-row md:flex-col overflow-x-auto gap-2 md:gap-4">
                    {companies.map((company) => (
                        <button
                            key={company}
                            onClick={() => {
                                setSelectedCompany(company);
                                setPage(1);
                            }}
                            className={`px-4 py-2 rounded-lg border text-sm whitespace-nowrap
                            ${
                                selectedCompany === company
                                    ? "bg-blue-600 text-white dark:bg-blue-500"
                                    : "bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200"
                            }`}
                        >
                            {company}
                        </button>
                    ))}
                </div>

                {/* Content */}
                <div className="flex-1">
                    <AnimatePresence mode="wait">
                        <motion.div
                            key={selectedCompany + page}
                            initial={{opacity: 0, y: 40}}
                            animate={{opacity: 1, y: 0}}
                            exit={{opacity: 0, y: -40}}
                            transition={{duration: 0.4}}
                            layout
                            className="flex flex-wrap gap-6 min-h-[500px] items-start"
                        >
                            {(() => {
                                const currentProjects = groupedProjects[selectedCompany] || [];
                                const totalPages = Math.ceil(currentProjects.length / itemsPerPage);
                                const paginated = currentProjects.slice(
                                    (page - 1) * itemsPerPage,
                                    page * itemsPerPage
                                );

                                return (
                                    <>
                                        {paginated.map((proj, idx) => (
                                            <Card
                                                key={idx}
                                                className="bg-white border border-gray-200 text-gray-900 dark:bg-gray-900 dark:border-gray-700 dark:text-white transition-colors duration-300"
                                            >
                                                <CardContent>
                                                    <h3 className="text-lg font-semibold">{proj.name}</h3>
                                                    <p className="text-gray-700 dark:text-gray-400">{proj.company}</p>
                                                    <p className="text-sm mb-2 text-gray-600 dark:text-gray-500">{proj.period}</p>
                                                    {proj.type && (
                                                        <ExpandableText
                                                            value={t(`project_types.${proj.type}`, proj.type)}
                                                            maxLines={3}
                                                            className="mb-2 text-sm"
                                                        />
                                                    )}
                                                    <Disclosure>
                                                        {({open}) => (
                                                            <div>
                                                                <Disclosure.Button
                                                                    className="flex items-center text-sm text-blue-600 dark:text-blue-400 hover:underline focus:outline-none mt-2"
                                                                >
                                                                    <span>{t("show_technologies")}</span>
                                                                    <ChevronDown
                                                                        className={`ml-1 w-4 h-4 transition-transform ${open ? "rotate-180" : ""}`}
                                                                    />
                                                                </Disclosure.Button>
                                                                <Disclosure.Panel
                                                                    className="mt-2 text-sm text-gray-700 dark:text-gray-300">
                                                                    {proj.tech}
                                                                </Disclosure.Panel>
                                                            </div>
                                                        )}
                                                    </Disclosure>
                                                </CardContent>
                                            </Card>
                                        ))}

                                        {/* Pagination Controls */}
                                        {totalPages > 1 && (
                                            <div className="w-full flex justify-center mt-8 space-x-4">
                                                <button
                                                    onClick={() => setPage(p => Math.max(p - 1, 1))}
                                                    disabled={page === 1}
                                                    className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium
                                                               text-gray-800 dark:text-gray-200 bg-white dark:bg-gray-900
                                                               hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-50 transition"
                                                >
                                                    ← {t("previous")}
                                                </button>

                                                <span data-testid="pagination-info"
                                                      className="px-4 py-2 text-sm text-gray-600 dark:text-gray-300">
                                                    {page} / {totalPages}
                                                </span>

                                                <button
                                                    onClick={() => setPage(p => Math.min(p + 1, totalPages))}
                                                    disabled={page === totalPages}
                                                    className="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium
                                                                text-gray-800 dark:text-gray-200 bg-white dark:bg-gray-900
                                                                hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-50 transition"
                                                >
                                                    {t("next")} →
                                                </button>
                                            </div>
                                        )}
                                    </>
                                );
                            })()}
                        </motion.div>
                    </AnimatePresence>
                </div>

            </div>
        </PageSection>
    );
}