feat(footer): expand footer with AOSSIE info and multi-column layout#10
feat(footer): expand footer with AOSSIE info and multi-column layout#10hk2166 wants to merge 3 commits intoAOSSIE-Org:mainfrom
Conversation
WalkthroughEnhanced the FAQ component with interactive hover effects and styling transitions. Redesigned the footer with a responsive multi-column layout featuring AOSSIE branding, navigation links, and social icons. Introduced type-safe shuffling logic to the home page with improved immutability patterns. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR upgrades PictoPy’s footer from a minimal single-line element to a responsive, multi-column footer that adds AOSSIE context plus direct links to project and community resources (addressing issue #9).
Changes:
- Replaces the existing footer with a 4-column layout (brand, About AOSSIE, Quick Links, Community) and a bottom bar with an auto-updating year.
- Adds scroll-triggered
framer-motionfade-up animations for each footer column. - Updates FAQ item styling/behavior to add a hover-driven background/text accent.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/Pages/Footer/Footer.tsx |
New multi-column footer with AOSSIE info, resource links, community links, animations, and bottom bar. |
src/Pages/FaqPage/FAQ.tsx |
Refactors FAQ item styling and introduces hover state for additional UI feedback. |
package-lock.json |
Updates lockfile package version metadata. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| `} | ||
| onClick={onClick} | ||
| onMouseEnter={() => setHovered(true)} | ||
| onMouseLeave={() => setHovered(false)} |
There was a problem hiding this comment.
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.
| onMouseLeave={() => setHovered(false)} | |
| onMouseLeave={() => setHovered(false)} | |
| onFocus={() => setHovered(true)} | |
| onBlur={() => setHovered(false)} |
| {"AOSSIE"} | ||
| </a> | ||
| { | ||
| ". PictoPy is open-source software released under the MIT License." |
There was a problem hiding this comment.
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.
| ". 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." |
| ? 'border-pink-500 dark:border-grey-500' | ||
| : 'dark:border-grey-500'} |
There was a problem hiding this comment.
The border color classes here look incorrect/incomplete:
dark:border-grey-500usesgrey(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
currentColorborder (often too dark/unintended).
Usedark: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.
| ? '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'} |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Pages/FaqPage/FAQ.tsx`:
- Around line 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.
- Around line 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.
In `@src/Pages/Footer/Footer.tsx`:
- Around line 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.
- Around line 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.
In `@src/Pages/Landing` page/Home1.tsx:
- Around line 49-79: The new hardcoded hero paragraph and CTA labels in the
Home1 component should be moved into your i18n resources and referenced via your
localization helper (e.g., useTranslation/t or equivalent); add keys like
"home.hero.description", "home.cta.download", and "home.cta.viewDocs" to the
locale files, replace the paragraph text and the two button labels in Home1.tsx
with the translated strings from the localization API, and ensure the external
link text uses the same key so all user-visible strings in the motion.p,
motion.button (onClick={scrollToDownloads}) and motion.a are localized.
- Around line 55-65: The motion.button for the Download action currently lacks
an explicit type which can cause it to act as a form submitter if the component
is ever nested inside a form; update the motion.button element (the component
using motion.button with onClick={scrollToDownloads}) to include type="button"
so it will always behave as a non-submit clickable button and avoid accidental
form submissions.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
src/Pages/FaqPage/FAQ.tsxsrc/Pages/Footer/Footer.tsxsrc/Pages/Landing page/Home1.tsx
| bg-white dark:bg-black border | ||
| ${isOpen | ||
| ? 'border-pink-500 dark:border-grey-500' | ||
| : 'dark:border-grey-500'} |
There was a problem hiding this comment.
🧩 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.
| 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.
| <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} | ||
| > |
There was a problem hiding this comment.
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.
| <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.
| <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> | ||
| <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." | ||
| } | ||
| </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> |
There was a problem hiding this comment.
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.
| 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> |
There was a problem hiding this comment.
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.
| Advanced desktop gallery application powered by Tauri, React, and Rust | ||
| with a Python backend for intelligent image analysis and seamless | ||
| management. | ||
| </motion.p> | ||
|
|
||
| <div className="flex space-x-4"> | ||
| {/* Download button - scrolls to downloads section */} | ||
| <motion.button | ||
| <motion.button | ||
| onClick={scrollToDownloads} | ||
| initial={{ scale: 0.9, opacity: 0 }} | ||
| animate={{ scale: 1, opacity: 1 }} | ||
| transition={{ duration: 0.5, delay: 0.6 }} | ||
| whileHover={{ scale: 1.03 }} | ||
| whileTap={{ scale: 0.98 }} | ||
| className="bg-gradient-to-r from-yellow-500 to-green-500 text-white font-medium py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | ||
| className="bg-gradient-to-r from-yellow-500 to-green-500 hover:from-yellow-600 hover:to-green-600 text-white font-semibold py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | ||
| > | ||
| Download | ||
| </motion.button> | ||
|
|
||
| {/* View Docs button - links to documentation */} | ||
| <motion.a | ||
| href="https://aossie-org.github.io/PictoPy/" | ||
|
|
||
| <motion.a | ||
| href="https://aossie-org.github.io/PictoPy/" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| initial={{ scale: 0.9, opacity: 0 }} | ||
| animate={{ scale: 1, opacity: 1 }} | ||
| 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 | ||
| </motion.a> |
There was a problem hiding this comment.
Externalize new hero and CTA strings for i18n compliance.
The newly added paragraph and CTA labels are hardcoded in JSX. Move them to localization resources.
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/Landing` page/Home1.tsx around lines 49 - 79, The new hardcoded
hero paragraph and CTA labels in the Home1 component should be moved into your
i18n resources and referenced via your localization helper (e.g.,
useTranslation/t or equivalent); add keys like "home.hero.description",
"home.cta.download", and "home.cta.viewDocs" to the locale files, replace the
paragraph text and the two button labels in Home1.tsx with the translated
strings from the localization API, and ensure the external link text uses the
same key so all user-visible strings in the motion.p, motion.button
(onClick={scrollToDownloads}) and motion.a are localized.
| <motion.button | ||
| onClick={scrollToDownloads} | ||
| initial={{ scale: 0.9, opacity: 0 }} | ||
| animate={{ scale: 1, opacity: 1 }} | ||
| transition={{ duration: 0.5, delay: 0.6 }} | ||
| whileHover={{ scale: 1.03 }} | ||
| whileTap={{ scale: 0.98 }} | ||
| className="bg-gradient-to-r from-yellow-500 to-green-500 text-white font-medium py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | ||
| className="bg-gradient-to-r from-yellow-500 to-green-500 hover:from-yellow-600 hover:to-green-600 text-white font-semibold py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | ||
| > | ||
| Download | ||
| </motion.button> |
There was a problem hiding this comment.
Set explicit type="button" for the Download action.
Line [55] is a clickable button and should specify type="button" to avoid accidental submit behavior if nested inside forms later.
Suggested fix
<motion.button
+ type="button"
onClick={scrollToDownloads}📝 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.
| <motion.button | |
| onClick={scrollToDownloads} | |
| initial={{ scale: 0.9, opacity: 0 }} | |
| animate={{ scale: 1, opacity: 1 }} | |
| transition={{ duration: 0.5, delay: 0.6 }} | |
| whileHover={{ scale: 1.03 }} | |
| whileTap={{ scale: 0.98 }} | |
| className="bg-gradient-to-r from-yellow-500 to-green-500 text-white font-medium py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | |
| className="bg-gradient-to-r from-yellow-500 to-green-500 hover:from-yellow-600 hover:to-green-600 text-white font-semibold py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | |
| > | |
| Download | |
| </motion.button> | |
| <motion.button | |
| type="button" | |
| onClick={scrollToDownloads} | |
| initial={{ scale: 0.9, opacity: 0 }} | |
| animate={{ scale: 1, opacity: 1 }} | |
| transition={{ duration: 0.5, delay: 0.6 }} | |
| whileHover={{ scale: 1.03 }} | |
| whileTap={{ scale: 0.98 }} | |
| className="bg-gradient-to-r from-yellow-500 to-green-500 hover:from-yellow-600 hover:to-green-600 text-white font-semibold py-2 px-6 rounded transition-all shadow-sm hover:shadow-md" | |
| > | |
| Download | |
| </motion.button> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/Pages/Landing` page/Home1.tsx around lines 55 - 65, The motion.button for
the Download action currently lacks an explicit type which can cause it to act
as a form submitter if the component is ever nested inside a form; update the
motion.button element (the component using motion.button with
onClick={scrollToDownloads}) to include type="button" so it will always behave
as a non-submit clickable button and avoid accidental form submissions.
Fixes #9
Screenshots/Recordings:

Additional Notes:
The previous footer was a single line with just a Discord icon and "Made with love by AOSSIE team". This PR replaces it with a fully featured, responsive multi-column footer.
Changes made:
About AOSSIE — paragraph explaining AOSSIE's mission (Australian not-for-profit, GSoC/Outreachy mentorship) with a link to aossie.org
⚠️ AI Notice - Important!
Quick Links — Documentation, Releases, Issue Tracker, Contributing Guide, AOSSIE Projects, Google Summer of Code
Community — Discord, AOSSIE GitHub org, and Twitter with branded icons
Bottom bar — copyright year (auto-updated via new Date().getFullYear()) and "Made with ♥ by AOSSIE Team"
Scroll-triggered framer-motion fade-up animations on each column
Fully dark-mode compatible using existing yellow→green gradient design tokens
No new dependencies — uses framer-motion, lucide-react, and react-icons already in package.json
Checklist
My code follows the project's code style and conventions
I have made corresponding changes to the documentation
My changes generate no new warnings or errors
I have joined the Discord server and I will share a link to this PR with the project maintainers there
I have read the Contributing Guidelines
We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.
Summary by CodeRabbit
Release Notes
New Features
Style