Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 28 additions & 15 deletions src/Pages/FaqPage/FAQ.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,38 +93,51 @@ interface FAQItemProps {

function FAQItem({ question, answer, isOpen, onClick, index, icon }: FAQItemProps) {
const contentRef = useRef<HTMLDivElement>(null);
const [hovered, setHovered] = useState(false);

return (
<motion.div
className={`rounded-xl overflow-hidden transition-all duration-300
bg-white dark:bg-black
border
${isOpen
? 'border- 6 border-pink-500 dark:border-grey-500'
: 'border- 6 - dark:border-grey-500'}
`}
bg-white dark:bg-black border
${isOpen
? 'border-pink-500 dark:border-grey-500'
: 'dark:border-grey-500'}
Comment on lines +103 to +104
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The border color classes here look incorrect/incomplete:

  • dark:border-grey-500 uses grey (not in Tailwind’s default palette, and not defined in this repo’s Tailwind config), so it won’t apply.
  • In the collapsed state you only set a dark-mode border color, so light mode falls back to the default currentColor border (often too dark/unintended).
    Use dark:border-gray-* and also set an explicit light-mode border color (e.g., border-gray-200) for the non-open state to match the rest of the UI.
Suggested change
? 'border-pink-500 dark:border-grey-500'
: 'dark:border-grey-500'}
? 'border-pink-500 dark:border-gray-500'
: 'border-gray-200 dark:border-gray-500'}

Copilot uses AI. Check for mistakes.
Comment on lines +101 to +104
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, check the specific file and lines mentioned
echo "=== Content at src/Pages/FaqPage/FAQ.tsx lines 101-104 ==="
if [ -f "src/Pages/FaqPage/FAQ.tsx" ]; then
  sed -n '95,110p' "src/Pages/FaqPage/FAQ.tsx"
else
  echo "File not found"
fi

# Check for "grey" token usage in the file
echo -e "\n=== Occurrences of 'grey' in FAQ.tsx ==="
rg -n 'grey' "src/Pages/FaqPage/FAQ.tsx" || echo "No matches found"

# Check for Tailwind config files
echo -e "\n=== Tailwind configuration files ==="
fd 'tailwind\.config\.(js|ts|cjs|mjs)$' -x sh -c 'echo "--- File: {} ---"; cat "{}"' || echo "No Tailwind config found"

Repository: AOSSIE-Org/PictoPy-Website

Length of output: 2281


Change grey to gray to use a valid Tailwind color token.

Lines 103 and 104 use dark:border-grey-500, but Tailwind's default grayscale token uses the American spelling gray, not British grey. The custom Tailwind config does not define a grey color, so these classes will silently fail to apply styling.

Suggested fix
-          ? 'border-pink-500 dark:border-grey-500'
-          : 'dark:border-grey-500'}
+          ? 'border-pink-500 dark:border-gray-500'
+          : 'dark:border-gray-500'}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bg-white dark:bg-black border
${isOpen
? 'border-pink-500 dark:border-grey-500'
: 'dark:border-grey-500'}
bg-white dark:bg-black border
${isOpen
? 'border-pink-500 dark:border-gray-500'
: 'dark:border-gray-500'}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Pages/FaqPage/FAQ.tsx` around lines 101 - 104, The Tailwind class string
that builds the container border uses the British spelling "grey" which doesn't
exist in the default tokens; update the interpolated class values where the
ternary uses 'dark:border-grey-500' to use 'dark:border-gray-500' instead (i.e.,
in the JSX that composes the className for the FAQ item surrounding the isOpen
conditional), changing both occurrences so Tailwind applies the dark gray border
correctly.

`}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
viewport={{ once: true }}
>
<button
className="flex justify-between items-center w-full text-left p-6 group"
className={`flex justify-between items-center w-full text-left p-6 group
transition-colors duration-300 rounded-xl
${hovered && !isOpen ? 'bg-green-50 dark:bg-green-900/10' : ''}
`}
onClick={onClick}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new hover styling is driven by onMouseEnter / onMouseLeave state only, so keyboard users won’t see the same affordance when tabbing to the FAQ button. Consider adding onFocus/onBlur to mirror the hover state, or prefer focus-visible:* Tailwind classes so the visual feedback is accessible.

Suggested change
onMouseLeave={() => setHovered(false)}
onMouseLeave={() => setHovered(false)}
onFocus={() => setHovered(true)}
onBlur={() => setHovered(false)}

Copilot uses AI. Check for mistakes.
aria-expanded={isOpen}
>
Comment on lines 111 to 120
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Set an explicit button type on the FAQ toggle.

Line [111] should declare type="button" to prevent implicit form submission behavior.

Suggested fix
       <button
+        type="button"
         className={`flex justify-between items-center w-full text-left p-6 group
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button
className="flex justify-between items-center w-full text-left p-6 group"
className={`flex justify-between items-center w-full text-left p-6 group
transition-colors duration-300 rounded-xl
${hovered && !isOpen ? 'bg-green-50 dark:bg-green-900/10' : ''}
`}
onClick={onClick}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
aria-expanded={isOpen}
>
<button
type="button"
className={`flex justify-between items-center w-full text-left p-6 group
transition-colors duration-300 rounded-xl
${hovered && !isOpen ? 'bg-green-50 dark:bg-green-900/10' : ''}
`}
onClick={onClick}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
aria-expanded={isOpen}
>
🧰 Tools
🪛 Biome (2.4.4)

[error] 111-120: Provide an explicit type prop for the button element.

(lint/a11y/useButtonType)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Pages/FaqPage/FAQ.tsx` around lines 111 - 120, The FAQ toggle button
element (the JSX <button> with props onClick, onMouseEnter, onMouseLeave,
aria-expanded) currently lacks an explicit type and may implicitly submit
surrounding forms; add type="button" to that button element so it does not
trigger form submission, keeping all existing props (className, onClick,
onMouseEnter, onMouseLeave, aria-expanded) intact.

<div className="flex items-center">
<div className={`mr-4 p-2 rounded-full
${isOpen ? 'bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-300' :
'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400 group-hover:bg-green-50 group-hover:text-green-500 dark:group-hover:bg-green-900/30 dark:group-hover:text-green-300'}
transition-colors duration-300`}>
<div className={`mr-4 p-2 rounded-full transition-colors duration-300
${isOpen
? 'bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-300'
: 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400 group-hover:bg-green-50 group-hover:text-green-500 dark:group-hover:bg-green-900/30 dark:group-hover:text-green-300'}
`}>
{icon}
</div>
<span className="font-semibold text-lg">{question}</span>
<span className={`font-semibold text-lg transition-colors duration-300
${hovered && !isOpen ? 'text-green-600 dark:text-green-400' : ''}
${isOpen ? 'text-green-600 dark:text-green-400' : ''}
`}>
{question}
</span>
</div>
<div className={`p-1 rounded-full transition-colors duration-300
${isOpen ? 'bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-300' :
'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400 group-hover:bg-green-50 group-hover:text-green-500 dark:group-hover:bg-green-900/30 dark:group-hover:text-green-300'}`}>
${isOpen
? 'bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-300'
: 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400 group-hover:bg-green-50 group-hover:text-green-500 dark:group-hover:bg-green-900/30 dark:group-hover:text-green-300'}
`}>
{isOpen ? <ChevronUp className="w-5 h-5" /> : <ChevronDown className="w-5 h-5" />}
</div>
</button>
Expand Down Expand Up @@ -180,4 +193,4 @@ function BackgroundAnimation({ darkMode }: { darkMode: boolean }) {
</div>
</div>
);
}
}
230 changes: 205 additions & 25 deletions src/Pages/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<footer className="relative bg-white dark:bg-black text-black dark:text-white py-8 overflow-hidden border-t border-black dark:border-white transition-colors duration-300">
<div className="relative container mx-auto px-6">
<div className="flex justify-between items-center">
{/* Left-aligned PictoPy text */}
<div className="flex items-center space-x-2">
<p className="text-xl font-medium text-transparent bg-clip-text bg-gradient-to-r from-yellow-400 to-green-400 hover:scale-105 transition-all duration-300 ease-in-out">
<footer className="bg-white dark:bg-black text-gray-700 dark:text-gray-300 border-t border-gray-200 dark:border-gray-800 transition-colors duration-300">
{/* Main grid */}
<div className="container mx-auto px-6 py-16">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12">
{/* Column 1 — PictoPy brand */}
<motion.div
custom={0}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={fadeUp}
>
<h3 className="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-yellow-500 to-green-500 mb-3">
PictoPy
</h3>
<p className="text-sm leading-relaxed mb-4">
A privacy-first, AI-powered desktop gallery application built with
Tauri, React, and Rust — keeping your data entirely on your
device.
</p>
</div>

{/* Right-aligned Discord Icon and "Made with love" text */}
<div className="flex items-center space-x-2">
<a
href="https://discord.com/channels/1022871757289422898/1311271974630330388"
target="_blank"
rel="noopener noreferrer"
className="text-sm font-medium text-transparent bg-clip-text bg-gradient-to-r from-yellow-400 to-green-400 hover:bg-gradient-to-r hover:from-yellow-500 hover:to-green-500 transition duration-300 ease-in-out"
<a
href="https://github.com/AOSSIE-Org/PictoPy"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 text-sm font-medium text-yellow-500 hover:text-green-500 transition-colors duration-200"
>
<FaDiscord className="inline-block mr-2 text-yellow-400 hover:text-green-400 transition duration-300 ease-in-out transform scale-150" /> {/* Scale it to 1.5x */}
<span>Made with love by AOSSIE team</span>
<FaGithub className="text-base" />
View on GitHub
<ExternalLink className="w-3 h-3" />
</a>
</div>
</motion.div>

{/* Column 2 — About AOSSIE */}
<motion.div
custom={1}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={fadeUp}
className="lg:col-span-1"
>
<h4 className="text-sm font-semibold uppercase tracking-wider text-gray-900 dark:text-white mb-3">
About AOSSIE
</h4>
<p className="text-sm leading-relaxed mb-3">
<span className="font-semibold text-gray-900 dark:text-white">
Australian Open Source Software Innovation and Education
(AOSSIE)
</span>{" "}
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.
</p>
<a
href="https://aossie.org"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1.5 text-sm font-medium text-yellow-500 hover:text-green-500 transition-colors duration-200"
>
aossie.org
<ExternalLink className="w-3 h-3" />
</a>
</motion.div>

{/* Column 3 — Quick Links */}
<motion.div
custom={2}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={fadeUp}
>
<h4 className="text-sm font-semibold uppercase tracking-wider text-gray-900 dark:text-white mb-3">
Quick Links
</h4>
<ul className="space-y-2 text-sm">
{[
{
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 }) => (
<li key={label}>
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="hover:text-yellow-500 dark:hover:text-green-400 transition-colors duration-200"
>
{label}
</a>
</li>
))}
</ul>
</motion.div>

{/* Column 4 — Community */}
<motion.div
custom={3}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={fadeUp}
>
<h4 className="text-sm font-semibold uppercase tracking-wider text-gray-900 dark:text-white mb-3">
Community
</h4>
<p className="text-sm leading-relaxed mb-4">
Join our community to report bugs, request features, chat with
contributors, and follow AOSSIE's open-source journey.
</p>
<div className="flex flex-col gap-3">
<a
href="https://discord.com/channels/1022871757289422898/1311271974630330388"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-sm font-medium hover:text-yellow-500 dark:hover:text-green-400 transition-colors duration-200"
>
<FaDiscord className="text-lg text-indigo-500" />
Discord Server
</a>
Comment on lines +153 to +160
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use a public Discord invite URL instead of a channel deep-link.

Line [153] links to a specific Discord channel route, which usually fails for users who are not already in the server. Use a server invite (discord.gg/...) for public onboarding.

Suggested fix
- href="https://discord.com/channels/1022871757289422898/1311271974630330388"
+ href="https://discord.gg/<your-invite-code>"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Pages/Footer/Footer.tsx` around lines 153 - 160, The Discord link in the
Footer component uses a channel deep-link which fails for users not in the
server; update the anchor element (the <a> that currently wraps the <FaDiscord
/> icon and "Discord Server" text in Footer.tsx) to use a public invite URL
(discord.gg/...) instead of the channel-specific URL, keeping the existing
attributes (target, rel, className) and content so the link opens in a new tab
and preserves styling and accessibility.

<a
href="https://github.com/AOSSIE-Org"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-sm font-medium hover:text-yellow-500 dark:hover:text-green-400 transition-colors duration-200"
>
<FaGithub className="text-lg" />
AOSSIE on GitHub
</a>
<a
href="https://twitter.com/aossie_org"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-sm font-medium hover:text-yellow-500 dark:hover:text-green-400 transition-colors duration-200"
>
<FaTwitter className="text-lg text-sky-500" />
@aossie_org
</a>
</div>
</motion.div>
</div>
</div>

<div className="mt-4 text-center border-t border-white pt-2">
{/* You can add any content here if needed */}
{/* Bottom bar */}
<div className="border-t border-gray-200 dark:border-gray-800">
<div className="container mx-auto px-6 py-5 flex flex-col sm:flex-row items-center justify-between gap-3 text-xs text-gray-500 dark:text-gray-500">
<p>
{`© ${year} `}
<a
href="https://aossie.org"
target="_blank"
rel="noopener noreferrer"
className="hover:text-yellow-500 transition-colors duration-200"
>
{"AOSSIE"}
</a>
{
". PictoPy is open-source software released under the MIT License."
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Footer text claims PictoPy is released under the MIT License, but the repository LICENSE file is GNU GPLv3. This is misleading (and potentially legally incorrect). Please update the footer copy to match the actual project license (or link to the LICENSE file) so it stays accurate if the license ever changes.

Suggested change
". PictoPy is open-source software released under the MIT License."
". PictoPy is open-source software licensed under the terms described in the project's LICENSE file."

Copilot uses AI. Check for mistakes.
}
</p>
<p className="flex items-center gap-1">
{"Made with ♥ by the "}
<a
href="https://aossie.org"
target="_blank"
rel="noopener noreferrer"
className="ml-1 font-medium text-transparent bg-clip-text bg-gradient-to-r from-yellow-500 to-green-500 hover:opacity-80 transition-opacity duration-200"
>
{"AOSSIE Team"}
</a>
</p>
Comment on lines +31 to +211
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Externalize footer copy to localization resources.

Most newly added user-facing strings are hardcoded in JSX (headings, descriptions, labels, bottom bar). Move them to i18n resource files.

Suggested direction
- <h4 className="...">About AOSSIE</h4>
+ <h4 className="...">{t("footer.about.title")}</h4>

- <p className="text-sm leading-relaxed mb-4">
-   Join our community to report bugs, request features...
- </p>
+ <p className="text-sm leading-relaxed mb-4">
+   {t("footer.community.description")}
+ </p>

As per coding guidelines Internationalization: User-visible strings should be externalized to resource files (i18n).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Pages/Footer/Footer.tsx` around lines 31 - 211, The Footer component
currently contains many hardcoded user-facing strings (e.g., headings "PictoPy",
"About AOSSIE", "Quick Links", "Community", link labels, description paragraph,
bottom bar copy and "Made with ♥ by the AOSSIE Team") — replace each literal
with i18n lookup keys (e.g., t('footer.title'), t('footer.description'),
t('footer.about.heading'), t('footer.quickLinks.docs'),
t('footer.bottom.copyright'), t('footer.madeBy')) by importing and using your
i18n hook (e.g., useTranslation or t) at the top of the Footer component, add
corresponding keys into the locale resource files for supported languages, and
keep the existing JSX structure/props (FaGithub, motion.div, year variable, link
hrefs) intact so only string values change; ensure pluralization/fallbacks as
needed and update tests or snapshots that assert exact text if present.

</div>
</div>
</footer>
)
}
);
};

export default Footer
export default Footer;
Loading
Loading