From 4d5796138d8f9e4fd27391131c7221fab024717b Mon Sep 17 00:00:00 2001 From: Mounika Vojjala Date: Fri, 12 Jun 2026 09:40:19 -0400 Subject: [PATCH 1/5] change: added cutom footer for future funder --- CHANGELOG.mdx | 4 + .../FooterFutureFunder.stories.tsx | 19 ++++ .../FooterFutureFunder/FooterFutureFunder.tsx | 96 +++++++++++++++++++ lib/data/FooterStandardData.ts | 48 ++++++++++ lib/main.ts | 1 + 5 files changed, 168 insertions(+) create mode 100644 lib/components/Footer/FooterFutureFunder/FooterFutureFunder.stories.tsx create mode 100644 lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx diff --git a/CHANGELOG.mdx b/CHANGELOG.mdx index 0df9ff754..3abd27b73 100644 --- a/CHANGELOG.mdx +++ b/CHANGELOG.mdx @@ -17,6 +17,10 @@ Prefix the change with one of these keywords: ## [Unreleased] +### Added + +- Custom footer for FutureFunder + ### Changed - FutureFunder example templates diff --git a/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.stories.tsx b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.stories.tsx new file mode 100644 index 000000000..cd502f109 --- /dev/null +++ b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.stories.tsx @@ -0,0 +1,19 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' +import { FooterFutureFunder } from './FooterFutureFunder' + +const meta: Meta = { + title: 'Components/Footers/FutureFunder', + component: FooterFutureFunder, + tags: ['autodocs'], + parameters: { + controls: { + sort: 'requiredFirst', + layout: 'fullscreen', + }, + }, +} +export default meta +type Story = StoryObj + +export const Primary: Story = {} +Primary.args = {} diff --git a/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx new file mode 100644 index 000000000..a23641361 --- /dev/null +++ b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx @@ -0,0 +1,96 @@ +import { FooterLogoLinks } from '../FooterLogoLinks/FooterLogoLinks' +import { FooterFutureFunderLinks as futureFunderData } from '../../../data/FooterStandardData' +import { useLinkContext } from '../../LinkProvider/useLinkContext' + +const styles = { + linkHeaders: `text-base font-bold text-white mt-8`, +} + +export const FooterFutureFunder = () => { + const LinkComponent = useLinkContext() + + return ( +
+ + +
+ +
+ +
+ +
+
+ ) +} diff --git a/lib/data/FooterStandardData.ts b/lib/data/FooterStandardData.ts index 4b825349e..0f898c67e 100644 --- a/lib/data/FooterStandardData.ts +++ b/lib/data/FooterStandardData.ts @@ -115,3 +115,51 @@ export const FooterAthleticsLinks = { { name: 'Undergraduate Admissions', href: 'https://admissions.carleton.ca/' }, ], } + +export const FooterFutureFunderLinks = { + Explore: [ + { name: 'Donate Now', href: 'https://futurefunder.carleton.ca/donate' }, + { name: 'Explore Campaigns', href: 'https://futurefunder.carleton.ca/campaigns' }, + { name: 'Submit a Campaign', href: 'https://futurefunder.carleton.ca/submit' }, + { name: 'Learn About FutureFunder', href: 'https://futurefunder.carleton.ca/about' }, + { name: 'Frequently Asked Questions', href: 'https://futurefunder.carleton.ca/faq' }, + { name: 'Read Our Blog', href: 'https://futurefunder.carleton.ca/blog' }, + { name: 'Contact Us', href: 'https://futurefunder.carleton.ca/contact' }, + ], + Categories: [ + { name: 'Arts', href: 'https://futurefunder.carleton.ca/campaigns?category=arts' }, + { name: 'Athletics', href: 'https://futurefunder.carleton.ca/campaigns?category=athletics' }, + { name: 'Business', href: 'https://futurefunder.carleton.ca/campaigns?category=business' }, + { name: 'Community', href: 'https://futurefunder.carleton.ca/campaigns?category=community' }, + { name: 'Environment', href: 'https://futurefunder.carleton.ca/campaigns?category=environment' }, + { name: 'Global Impact', href: 'https://futurefunder.carleton.ca/campaigns?category=global-impact' }, + { name: 'Health', href: 'https://futurefunder.carleton.ca/campaigns?category=health' }, + { name: 'Science & Innovation', href: 'https://futurefunder.carleton.ca/campaigns?category=science-innovation' }, + { name: 'Student Experience', href: 'https://futurefunder.carleton.ca/campaigns?category=student-experience' }, + { + name: 'Arts & Social Sciences', + href: 'https://futurefunder.carleton.ca/campaigns?category=arts-social-sciences', + }, + { name: 'Engineering & Design', href: 'https://futurefunder.carleton.ca/campaigns?category=engineering-design' }, + { name: 'Library', href: 'https://futurefunder.carleton.ca/campaigns?category=library' }, + { + name: 'Recreation & Athletics', + href: 'https://futurefunder.carleton.ca/campaigns?category=recreation-athletics', + }, + { name: 'Science', href: 'https://futurefunder.carleton.ca/campaigns?category=science' }, + { name: 'Sprott School of Business', href: 'https://futurefunder.carleton.ca/campaigns?category=sprott' }, + { name: 'University Wide', href: 'https://futurefunder.carleton.ca/campaigns?category=university-wide' }, + ], + RegisterLogin: [ + { name: 'Login', href: 'https://futurefunder.carleton.ca/login' }, + { name: 'Sign Up', href: 'https://futurefunder.carleton.ca/signup' }, + { name: 'Password Reset', href: 'https://futurefunder.carleton.ca/password-reset' }, + { name: 'Account Support', href: 'https://futurefunder.carleton.ca/support' }, + { name: 'Newsletter Sign Up', href: 'https://futurefunder.carleton.ca/newsletter' }, + ], + HereForGood: [ + { name: 'University Advancement', href: 'https://carleton.ca/advancement/' }, + { name: 'Our Mission', href: 'https://futurefunder.carleton.ca/mission' }, + { name: 'Giving at Carleton', href: 'https://futurefunder.carleton.ca/giving' }, + ], +} diff --git a/lib/main.ts b/lib/main.ts index ec276c6bb..feb41fc87 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -18,6 +18,7 @@ export { Embed } from './components/Embed/Embed' export { FilterPanel } from './components/FilterPanel/FilterPanel' export { FooterBasic } from './components/Footer/FooterBasic/FooterBasic' export { FooterAthletics } from './components/Footer/FooterAthletics/FooterAthletics' +export { FooterFutureFunder } from './components/Footer/FooterFutureFunder/FooterFutureFunder' export { FooterCookie } from './components/Footer/FooterCookie/FooterCookie' export { FooterLogoLinks } from './components/Footer/FooterLogoLinks/FooterLogoLinks' export { FooterStandard } from './components/Footer/FooterStandard/FooterStandard' From 227231dea4f7253fa497dc8a0968599c1a926a0b Mon Sep 17 00:00:00 2001 From: Mounika Vojjala Date: Fri, 12 Jun 2026 11:02:58 -0400 Subject: [PATCH 2/5] change: added social icons,acknowledgment to the footer --- docs/motion-enhancement-plan.md | 32 +++--- .../FooterAthletics/FooterAthletics.tsx | 98 ++--------------- .../FooterFutureFunder/FooterFutureFunder.tsx | 33 +++++- lib/components/Footer/FooterSocialIcons.tsx | 100 ++++++++++++++++++ lib/components/Footer/footerStyles.ts | 3 + 5 files changed, 154 insertions(+), 112 deletions(-) create mode 100644 lib/components/Footer/FooterSocialIcons.tsx create mode 100644 lib/components/Footer/footerStyles.ts diff --git a/docs/motion-enhancement-plan.md b/docs/motion-enhancement-plan.md index a20004c09..efcf9c5ec 100644 --- a/docs/motion-enhancement-plan.md +++ b/docs/motion-enhancement-plan.md @@ -60,23 +60,23 @@ This plan proposes a cohesive motion-and-interactivity layer for RDS. It is an _ ### 2.1 Motion already in the codebase -| Component | Motion present | File:line | Notes | -| -------------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------- | -| Card | hover scale (1.02) + shadow | `lib/components/Card/Card.tsx:45` | `duration-300 ease-in`. No `motion-reduce` | -| Toast | slide-in + fade, JS removal after 200 ms | `lib/components/Toast/Toast.tsx:48,57` | Hard-coded timeout couples JS to CSS | -| Nav | header hide-on-scroll | `lib/components/Nav/Nav.tsx:28`, `scrollingNav.ts:12-32` | Unthrottled scroll listener; no `motion-reduce` | -| Nav | item color transitions, arrow rotation | `lib/components/Nav/Nav.Styles.ts:8-13`, `priority-plus.css:17,60` | No `motion-reduce` | +| Component | Motion present | File:line | Notes | +| -------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| Card | hover scale (1.02) + shadow | `lib/components/Card/Card.tsx:45` | `duration-300 ease-in`. No `motion-reduce` | +| Toast | slide-in + fade, JS removal after 200 ms | `lib/components/Toast/Toast.tsx:48,57` | Hard-coded timeout couples JS to CSS | +| Nav | header hide-on-scroll | `lib/components/Nav/Nav.tsx:28`, `scrollingNav.ts:12-32` | Unthrottled scroll listener; no `motion-reduce` | +| Nav | item color transitions, arrow rotation | `lib/components/Nav/Nav.Styles.ts:8-13`, `priority-plus.css:17,60` | No `motion-reduce` | | Description | accordion icon rotation (`rotate-0` ↔ `rotate-90`) | `lib/components/Description/DescriptionAccordion.tsx:27`, `script.ts` | Content shows/hides via `hidden` attribute — no height animation | -| FilterPanel | dropdown arrow rotation + color | `lib/components/FilterPanel/FilterPanelTop.tsx:34`, `dropdown.ts:66,88,141` | No `motion-reduce` | -| ProgressBar | width fill animation | `lib/components/ProgressBar/ProgressBar.tsx:31-32` | `transition-all duration-1000` — animates `width` (H3 violation) | -| ImageSlider | carousel slide (inline `transform 0.5s`) | `lib/components/ImageSlider/script.ts:78-113` | JS-set transitions; 50 ms timeouts to sequence phases | -| ImageSlider item | 5 s background-image transition | `lib/components/ImageSlider/ImageSliderItem.tsx:31` | `duration-[5000]`. Borderline H6 | -| Loaders (21+) | `animate-pulse` skeletons | `lib/components/Loaders/**` | None opt into `motion-reduce` (Tailwind does NOT auto-disable) | -| PageLoader | `animate-spin` + slowed-spin under reduced-motion | `lib/components/Loaders/PageLoader/PageLoader.tsx:5` | **Only** component currently honouring reduced-motion | -| TopNavLoader | `animate-spin` | `lib/components/Loaders/TopNavLoader/TopNavLoader.tsx:6` | No `motion-reduce` | -| Splash / FullBanner / WideBanner video | `autoPlay muted loop playsInline` | `lib/hooks/useVideoBanner.tsx:39-41` | Loops indefinitely. No pause control. **H6 risk.** | -| Modal | none (snap `block`/`hidden`) | `lib/components/Modal/Modal.tsx:129` | Open/close is instant — felt jarring per typical UX | -| Dialog | none (uses native `` `showModal()`) | `lib/components/Dialog/Dialog.tsx:21` | Same — no entrance/exit | +| FilterPanel | dropdown arrow rotation + color | `lib/components/FilterPanel/FilterPanelTop.tsx:34`, `dropdown.ts:66,88,141` | No `motion-reduce` | +| ProgressBar | width fill animation | `lib/components/ProgressBar/ProgressBar.tsx:31-32` | `transition-all duration-1000` — animates `width` (H3 violation) | +| ImageSlider | carousel slide (inline `transform 0.5s`) | `lib/components/ImageSlider/script.ts:78-113` | JS-set transitions; 50 ms timeouts to sequence phases | +| ImageSlider item | 5 s background-image transition | `lib/components/ImageSlider/ImageSliderItem.tsx:31` | `duration-[5000]`. Borderline H6 | +| Loaders (21+) | `animate-pulse` skeletons | `lib/components/Loaders/**` | None opt into `motion-reduce` (Tailwind does NOT auto-disable) | +| PageLoader | `animate-spin` + slowed-spin under reduced-motion | `lib/components/Loaders/PageLoader/PageLoader.tsx:5` | **Only** component currently honouring reduced-motion | +| TopNavLoader | `animate-spin` | `lib/components/Loaders/TopNavLoader/TopNavLoader.tsx:6` | No `motion-reduce` | +| Splash / FullBanner / WideBanner video | `autoPlay muted loop playsInline` | `lib/hooks/useVideoBanner.tsx:39-41` | Loops indefinitely. No pause control. **H6 risk.** | +| Modal | none (snap `block`/`hidden`) | `lib/components/Modal/Modal.tsx:129` | Open/close is instant — felt jarring per typical UX | +| Dialog | none (uses native `` `showModal()`) | `lib/components/Dialog/Dialog.tsx:21` | Same — no entrance/exit | ### 2.2 What's missing diff --git a/lib/components/Footer/FooterAthletics/FooterAthletics.tsx b/lib/components/Footer/FooterAthletics/FooterAthletics.tsx index 3595dc220..6dcb67917 100644 --- a/lib/components/Footer/FooterAthletics/FooterAthletics.tsx +++ b/lib/components/Footer/FooterAthletics/FooterAthletics.tsx @@ -1,88 +1,8 @@ import { FooterLogoLinks } from '../FooterLogoLinks/FooterLogoLinks' import { FooterAthleticsLinks as athleticsData } from '../../../data/FooterStandardData' import { useLinkContext } from '../../LinkProvider/useLinkContext' - -const Social = [ - { - name: 'Facebook', - href: 'https://www.facebook.com/carletonuniversity', - icon: () => ( - - ), - }, - { - name: 'Instagram', - href: 'https://www.instagram.com/carleton_u', - icon: () => ( - - ), - }, - { - name: 'Twitter', - href: 'https://twitter.com/@Carleton_U', - icon: () => ( - - ), - }, - { - name: 'YouTube', - href: 'https://www.youtube.com/user/carletonuvideos', - icon: () => ( - - ), - }, - { - name: 'LinkedIn', - href: 'https://www.linkedin.com/school/carleton-university', - icon: () => ( - - ), - }, -] - -const styles = { - linkHeaders: `text-base font-bold text-white mt-8`, -} +import { FooterSocialIcons } from '../FooterSocialIcons' +import { footerStyles as styles } from '../footerStyles' export const FooterAthletics = () => { const LinkComponent = useLinkContext() @@ -130,6 +50,7 @@ export const FooterAthletics = () => { ))} +

Facilities

    @@ -152,6 +73,7 @@ export const FooterAthletics = () => { ))}
+

Camps

    @@ -199,6 +121,7 @@ export const FooterAthletics = () => {
+

@@ -218,16 +141,7 @@ export const FooterAthletics = () => {

1125 Colonel By Drive, Ottawa, ON, K1S 5B6, Canada

-
    - {Social.map((item, index) => ( -
  • - - {item.name} - - -
  • - ))} -
+
diff --git a/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx index a23641361..d0777d321 100644 --- a/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx +++ b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx @@ -1,10 +1,8 @@ import { FooterLogoLinks } from '../FooterLogoLinks/FooterLogoLinks' import { FooterFutureFunderLinks as futureFunderData } from '../../../data/FooterStandardData' import { useLinkContext } from '../../LinkProvider/useLinkContext' - -const styles = { - linkHeaders: `text-base font-bold text-white mt-8`, -} +import { FooterSocialIcons } from '../FooterSocialIcons' +import { footerStyles as styles } from '../footerStyles' export const FooterFutureFunder = () => { const LinkComponent = useLinkContext() @@ -18,6 +16,13 @@ export const FooterFutureFunder = () => { Footer +
+

+ Carleton University acknowledges the location of its campus on the traditional, unceded territories of the + Algonquin Anishinàbeg nation +

+
+
+
+

+ Contact us by{' '} + + phone + {' '} + or{' '} + + email + +

+

1125 Colonel By Drive, Ottawa, ON, K1S 5B6, Canada

+ +
diff --git a/lib/components/Footer/FooterSocialIcons.tsx b/lib/components/Footer/FooterSocialIcons.tsx new file mode 100644 index 000000000..085308913 --- /dev/null +++ b/lib/components/Footer/FooterSocialIcons.tsx @@ -0,0 +1,100 @@ +import { useLinkContext } from '../LinkProvider/useLinkContext' + +export const socialLinks = [ + { + name: 'Facebook', + href: 'https://www.facebook.com/carletonuniversity', + icon: () => ( + + ), + }, + { + name: 'Instagram', + href: 'https://www.instagram.com/carleton_u', + icon: () => ( + + ), + }, + { + name: 'Twitter', + href: 'https://twitter.com/@Carleton_U', + icon: () => ( + + ), + }, + { + name: 'YouTube', + href: 'https://www.youtube.com/user/carletonuvideos', + icon: () => ( + + ), + }, + { + name: 'LinkedIn', + href: 'https://www.linkedin.com/school/carleton-university', + icon: () => ( + + ), + }, +] + +interface FooterSocialIconsProps { + hoverColor?: string +} + +export const FooterSocialIcons = ({ hoverColor = 'hover:text-white' }: FooterSocialIconsProps) => { + const LinkComponent = useLinkContext() + + return ( +
    + {socialLinks.map((item, index) => ( +
  • + + {item.name} + + +
  • + ))} +
+ ) +} diff --git a/lib/components/Footer/footerStyles.ts b/lib/components/Footer/footerStyles.ts new file mode 100644 index 000000000..cfafae68c --- /dev/null +++ b/lib/components/Footer/footerStyles.ts @@ -0,0 +1,3 @@ +export const footerStyles = { + linkHeaders: `text-base font-bold text-white mt-8`, +} From 956374c4d88e41680f08787146a7d4fd918b9cab Mon Sep 17 00:00:00 2001 From: Mounika Vojjala Date: Fri, 12 Jun 2026 11:11:18 -0400 Subject: [PATCH 3/5] change: added wave to the footer --- lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx index d0777d321..c23dbff0e 100644 --- a/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx +++ b/lib/components/Footer/FooterFutureFunder/FooterFutureFunder.tsx @@ -9,7 +9,7 @@ export const FooterFutureFunder = () => { return (