diff --git a/package-lock.json b/package-lock.json index a4a057d..58df27c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "PictoPy", - "version": "0.0.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "PictoPy", - "version": "0.0.0", + "version": "1.0.0", "dependencies": { "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", diff --git a/src/Pages/FaqPage/FAQ.tsx b/src/Pages/FaqPage/FAQ.tsx index 6bd921f..d9b157e 100644 --- a/src/Pages/FaqPage/FAQ.tsx +++ b/src/Pages/FaqPage/FAQ.tsx @@ -93,38 +93,51 @@ interface FAQItemProps { function FAQItem({ question, answer, isOpen, onClick, index, icon }: FAQItemProps) { const contentRef = useRef(null); + const [hovered, setHovered] = useState(false); return ( @@ -180,4 +193,4 @@ function BackgroundAnimation({ darkMode }: { darkMode: boolean }) { ); -} +} \ No newline at end of file diff --git a/src/Pages/Footer/Footer.tsx b/src/Pages/Footer/Footer.tsx index ae4b766..29f2055 100644 --- a/src/Pages/Footer/Footer.tsx +++ b/src/Pages/Footer/Footer.tsx @@ -1,38 +1,218 @@ -import type React from "react" -import { FaDiscord } from 'react-icons/fa' // Import Discord icon from React Icons +import type React from "react"; +import { motion } from "framer-motion"; +import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa"; +import { ExternalLink } from "lucide-react"; + +const fadeUp = { + hidden: { opacity: 0, y: 20 }, + visible: (i: number) => ({ + opacity: 1, + y: 0, + transition: { duration: 0.5, delay: i * 0.1 }, + }), +}; const Footer: React.FC = () => { + const year = new Date().getFullYear(); + return ( -
-
-
- {/* Left-aligned PictoPy text */} -
-

+

+ {/* Main grid */} +
+
+ {/* Column 1 — PictoPy brand */} + +

PictoPy +

+

+ A privacy-first, AI-powered desktop gallery application built with + Tauri, React, and Rust — keeping your data entirely on your + device.

-
- - {/* Right-aligned Discord Icon and "Made with love" text */} - + + + {/* Column 2 — About AOSSIE */} + +

+ About AOSSIE +

+

+ + Australian Open Source Software Innovation and Education + (AOSSIE) + {" "} + is an Australian not-for-profit umbrella organisation for + open-source projects. AOSSIE mentors students and contributors + through programs like Google Summer of Code and Outreachy, + fostering innovation in open-source software across the globe. +

+ + aossie.org + + +
+ + {/* Column 3 — Quick Links */} + +

+ Quick Links +

+
    + {[ + { + label: "Documentation", + href: "https://aossie-org.github.io/PictoPy/", + }, + { + label: "Releases", + href: "https://github.com/AOSSIE-Org/PictoPy/releases", + }, + { + label: "Issue Tracker", + href: "https://github.com/AOSSIE-Org/PictoPy/issues", + }, + { + label: "Contributing Guide", + href: "https://github.com/AOSSIE-Org/PictoPy/blob/main/CONTRIBUTING.md", + }, + { + label: "AOSSIE Projects", + href: "https://aossie.org/#projects", + }, + { + label: "Google Summer of Code", + href: "https://summerofcode.withgoogle.com/", + }, + ].map(({ label, href }) => ( +
  • + + {label} + +
  • + ))} +
+
+ + {/* Column 4 — Community */} + +

+ Community +

+

+ Join our community to report bugs, request features, chat with + contributors, and follow AOSSIE's open-source journey. +

+ +
+
-
- {/* You can add any content here if needed */} + {/* Bottom bar */} +
+
+

+ {`© ${year} `} + + {"AOSSIE"} + + { + ". PictoPy is open-source software released under the MIT License." + } +

+

+ {"Made with ♥ by the "} + + {"AOSSIE Team"} + +

- ) -} + ); +}; -export default Footer +export default Footer; diff --git a/src/Pages/Landing page/Home1.tsx b/src/Pages/Landing page/Home1.tsx index a605326..c6f5caf 100644 --- a/src/Pages/Landing page/Home1.tsx +++ b/src/Pages/Landing page/Home1.tsx @@ -1,14 +1,20 @@ import { motion } from "framer-motion"; -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; + +const SHUFFLE_INTERVAL = 3000; + +interface SquareItem { + id: number; + src: string; +} const ShuffleHero = () => { - // Function to scroll to downloads section const scrollToDownloads = () => { - const downloadsSection = document.getElementById('downloads-section'); + const downloadsSection = document.getElementById("downloads-section"); if (downloadsSection) { downloadsSection.scrollIntoView({ - behavior: 'smooth', - block: 'start', + behavior: "smooth", + block: "start", }); } }; @@ -16,7 +22,7 @@ const ShuffleHero = () => { return (
- { > INTELLIGENT GALLERY MANAGEMENT - - { > PictoPy - - - Advanced desktop gallery application powered by Tauri, React, and Rust with a Python backend for intelligent image analysis and seamless management. + Advanced desktop gallery application powered by Tauri, React, and Rust + with a Python backend for intelligent image analysis and seamless + management. - +
- {/* Download button - scrolls to downloads section */} - Download - - {/* View Docs button - links to documentation */} - { transition={{ duration: 0.5, delay: 0.7 }} whileHover={{ scale: 1.03 }} whileTap={{ scale: 0.98 }} - className="border border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-200 font-medium py-2 px-6 rounded transition-all hover:border-teal-500 hover:text-teal-500" + className="border border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-200 font-semibold py-2 px-6 rounded transition-all hover:bg-teal-600 hover:border-teal-600 hover:text-white dark:hover:bg-teal-600 dark:hover:border-teal-600 dark:hover:text-white" > View Docs @@ -78,24 +84,23 @@ const ShuffleHero = () => { ); }; -const shuffle = (array: (typeof squareData)[0][]) => { - let currentIndex = array.length, - randomIndex; +const shuffle = (array: SquareItem[]): SquareItem[] => { + const result = [...array]; + let currentIndex = result.length; - while (currentIndex != 0) { - randomIndex = Math.floor(Math.random() * currentIndex); + while (currentIndex !== 0) { + const randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; - - [array[currentIndex], array[randomIndex]] = [ - array[randomIndex], - array[currentIndex], + [result[currentIndex], result[randomIndex]] = [ + result[randomIndex], + result[currentIndex], ]; } - return array; + return result; }; -const squareData = [ +const squareData: SquareItem[] = [ { id: 1, src: "https://images.unsplash.com/photo-1547347298-4074fc3086f0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80", @@ -174,30 +179,31 @@ const generateSquares = () => { style={{ backgroundImage: `url(${sq.src})`, backgroundSize: "cover", + backgroundPosition: "center", }} > )); }; const ShuffleGrid = () => { - const timeoutRef = useRef(null); + const timeoutRef = useRef | null>(null); const [squares, setSquares] = useState(generateSquares()); - useEffect(() => { - shuffleSquares(); - - return () => clearTimeout(timeoutRef.current); - }, []); - - const shuffleSquares = () => { + const shuffleSquares = useCallback(() => { setSquares(generateSquares()); + timeoutRef.current = setTimeout(shuffleSquares, SHUFFLE_INTERVAL); + }, []); - timeoutRef.current = setTimeout(shuffleSquares, 3000); - }; + useEffect(() => { + shuffleSquares(); + return () => { + if (timeoutRef.current) clearTimeout(timeoutRef.current); + }; + }, [shuffleSquares]); return (
- {squares.map((sq) => sq)} + {squares}
); };