diff --git a/frontend/next-env.d.ts b/frontend/next-env.d.ts index c4b7818..9edff1c 100644 --- a/frontend/next-env.d.ts +++ b/frontend/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/frontend/public/images/deaf-focus-logo.png b/frontend/public/images/deaf-focus-logo.png new file mode 100644 index 0000000..adfd637 Binary files /dev/null and b/frontend/public/images/deaf-focus-logo.png differ diff --git a/frontend/src/app/about/page.tsx b/frontend/src/app/about/page.tsx index 3864639..b6a25ba 100644 --- a/frontend/src/app/about/page.tsx +++ b/frontend/src/app/about/page.tsx @@ -4,7 +4,7 @@ import type { Metadata } from 'next'; export const metadata: Metadata = { title: 'About Us | Louisiana Association of the Deaf', - description: 'Learn about the history, mission, and vision of the Louisiana Association of the Deaf, serving the deaf community since 1908.', + description: 'Learn about the Louisiana Association of the Deaf — the oldest, largest, and premier nonprofit organization for the Deaf, DeafBlind, and hard of hearing community in Louisiana since 1908.', }; export default function AboutPage() { @@ -16,84 +16,113 @@ export default function AboutPage() {

About Louisiana Association of the Deaf

- Connecting and empowering the deaf community in Louisiana since 1908. + The oldest, largest, and premier nonprofit organization for the Deaf, DeafBlind, and hard of hearing community in Louisiana since 1908.

- {/* Mission and Vision */} + {/* About Us */}
-
-
-

Our Mission

-

- To promote social, educational, and recreational opportunities for deaf individuals and their families while fostering a sense of community and belonging. -

-

- We strive to create an inclusive environment where deaf and hard-of-hearing individuals can connect, share experiences, and access resources. -

-
-
-

Our Vision

-

- To be a leading organization that bridges the gap between the deaf and hearing communities, promoting awareness, understanding, and equal opportunities. -

-

- We envision a world where deaf and hard-of-hearing individuals have full access to communication, education, and community participation. -

+

About Us

+
+

+ Louisiana Association of the Deaf (LAD) is the oldest, largest, and premier nonprofit organization for the Deaf, DeafBlind, and hard of hearing (DDBHH) citizens in the state of Louisiana. LAD was founded in 1908 by the alumni of the Louisiana School for the Deaf and is one of fifty (50) states affiliated with the National Association of the Deaf (NAD). LAD advocates the promotion of the educational, economic, and social well-being of DDBHH individuals in Louisiana. +

+
+

In addition, LAD, doing business as Deaf Focus, provides a variety of services to the DDBHH community, including:

+
    +
  • Interpreting Services
  • +
  • Educational Support/Tutoring
  • +
  • Expert Consulting
  • +
  • Law Enforcement & First Responders Training
  • +
  • Professional Development
  • +
  • Health and Wellness Services
  • +
  • Social and Recreational Activities
  • +
  • ASL Classes
  • +
  • Advocacy: Legislative, Education, Services, Employment, and Access
  • +
+

+ LAD is supported by its members and other stakeholders interested in achieving LAD's goals. Membership is open to any Louisiana citizen who is DDBHH; parents of children who are DDBHH; professionals who work with DDBHH youth and adults; including those who are not deaf, and other DDBHH individuals outside of Louisiana, interested in supporting our mission. +

+

+ Our organization is Deaf-led with a team passionate about the Deaf-Centric approach in the provision of our services. We believe collaboration is essential to achieving our goals, and we strive to collaborate with various community partners, businesses, schools, government agencies, and other non-profit organizations. We aim to be a model example of a Deaf-Led organization. Together, we can elevate the journey of positive and meaningful progress in creating a more inclusive world where everyone has the opportunity to succeed. +

- {/* History */} + {/* Mission, Vision, Values */}
-

Our History

-
-

- The Louisiana Association of the Deaf (LAD) was established in 1908 by a group of deaf community members who recognized the need for a dedicated organization to serve the growing deaf population in Louisiana. -

-

- Starting with just a handful of members, LAD quickly grew into a vibrant community hub, hosting regular social events, educational workshops, and advocacy initiatives. -

-

- Throughout the decades, LAD has continued to evolve and expand its services while staying true to its core mission of fostering community and providing support for deaf and hard-of-hearing individuals in Louisiana and surrounding areas. -

+

Mission, Vision & Values

+
+
+

Mission

+

+ The mission of the LAD is to preserve, protect, and promote the civil, human, and linguistic rights of deaf citizens of Louisiana. +

+
+
+

Vision

+

+ The vision of the LAD is a society in which the language, culture, and heritage of deaf Louisianans are acknowledged and respected. As a result, deaf people will have the fullness of life, liberty, and equality. +

+
+
+
+ {[ + { title: 'Service', desc: 'Every deaf person should have equal access to any service provided to tax-paying citizens. We advocate to raise the bar in services, public or private, and awareness within society.' }, + { title: 'Education', desc: 'We believe in Free and Appropriate Public Education with emphasis on early access for establishing a language foundation, and promotion of lifelong learning for all adults.' }, + { title: 'Social', desc: 'We believe in preserving our heritage, culture, and the status of our linguistic minority. We promote every opportunity where deaf people can engage and build relationships.' }, + { title: 'Welfare', desc: 'We believe in nourishing every deaf person\'s well-being toward healthy self-esteem, self-confidence, and self-advocacy abilities so that every deaf person can lead a self-sufficient life.' }, + ].map((v) => ( +
+

{v.title}

+

{v.desc}

+
+ ))}
- {/* Board Members */} + {/* Board of Directors */}
-
-

Leadership Team

-

- LAD is governed by an elected board representing the deaf community across Louisiana. - The 2019–2021 board: +

+

Board of Directors

+

+ LAD Board of Directors for the 2023–2027 term.

-
+

+ The Board of Directors is elected by the general membership during the organization's biennial conference and governs the LAD. Board members are DDBHH and serve on a voluntary basis. +

+
{[ - { name: 'Jimmy Challis Gore', role: 'President' }, - { name: 'Sherry Crosby', role: 'Vice President' }, - { name: 'Jay Isch', role: 'Secretary' }, - { name: 'Alla Tarasyuk', role: 'Treasurer' }, + { name: 'Sherry Crosby', role: 'President', email: 'President@lad1908.org' }, + { name: 'Jerrod Wingate', role: 'Vice President', email: 'VicePresident@lad1908.org' }, + { name: 'Cammy Gaspar', role: 'Secretary', email: 'Secretary@lad1908.org' }, + { name: 'Ben Wimberly', role: 'Treasurer', email: 'Treasurer@lad1908.org' }, + { name: 'Katrina Williams', role: 'Member-at-Large', email: 'MAL1@lad1908.org' }, + { name: 'Vacant', role: 'Member-at-Large', email: 'MAL2@lad1908.org' }, + { name: 'Rosalyn Watson', role: 'Member-at-Large', email: 'MAL3@lad1908.org' }, + { name: 'Jay Isch', role: 'Executive Director (ex-officio)', email: 'Jay@deaffocus.org' }, ].map((member) => ( -
-
- - {member.name.charAt(0)} +
+
+ + {member.name === 'Vacant' ? '?' : member.name.charAt(0)}
-

{member.name}

-

{member.role}

+

{member.name}

+

{member.role}

+ {member.email}
))}
@@ -109,15 +138,13 @@ export default function AboutPage() {
{[ { abbr: 'NAD', name: 'National Association of the Deaf', desc: 'LAD\'s national affiliate — the nation\'s premier civil rights organization for the Deaf.' }, - { abbr: 'LCD', name: 'Louisiana Commission for the Deaf', desc: 'State agency serving as the official liaison between the deaf community and state government.' }, - { abbr: 'LSD', name: 'Louisiana School for the Deaf', desc: 'Residential school providing K–12 education in ASL for deaf students statewide.' }, + { abbr: 'LCD', name: 'Louisiana Commission for the Deaf', desc: 'State agency serving as the official liaison between the Deaf community and state government.' }, + { abbr: 'LSD', name: 'Louisiana School for the Deaf', desc: 'Residential school providing K–12 education in ASL for Deaf students statewide.' }, { abbr: 'Deaf Focus', name: 'Deaf Focus', desc: 'Deaf-led services organization operated by LAD — interpreting, advocacy, and ASL classes.' }, - { abbr: 'BRAD', name: 'Baton Rouge Association of the Deaf', desc: 'Local affiliate serving the deaf community in the Greater Baton Rouge area.' }, - { abbr: 'GNOAD', name: 'Greater New Orleans Association of the Deaf', desc: 'Local affiliate serving the deaf community in the New Orleans area.' }, + { abbr: 'BRAD', name: 'Baton Rouge Association of the Deaf', desc: 'Local affiliate serving the Deaf community in the Greater Baton Rouge area.' }, + { abbr: 'GNOAD', name: 'Greater New Orleans Association of the Deaf', desc: 'Local affiliate serving the Deaf community in the New Orleans area.' }, { abbr: 'NOBDA', name: 'New Orleans Black Deaf Association', desc: 'Organization serving the Black Deaf community in New Orleans.' }, { abbr: 'LRID', name: 'Louisiana Registry of Interpreters for the Deaf', desc: 'Professional organization for sign language interpreters in Louisiana.' }, - { abbr: 'DGM-LA', name: 'Deaf Grassroots Movement of Louisiana', desc: 'Endorsed by LAD — grassroots advocacy organization for the Deaf community statewide.' }, - { abbr: 'LAAD', name: 'Lafayette Athletic Association of the Deaf', desc: 'Local affiliate serving the deaf community in the Lafayette area.' }, ].map((org) => (
{org.abbr} @@ -132,51 +159,22 @@ export default function AboutPage() {
- {/* Values */} -
-
-
-

Our Values

-
-
-

Inclusion

-

- We welcome and embrace individuals of all backgrounds, abilities, and experiences. -

-
-
-

Accessibility

-

- We are committed to removing barriers and ensuring full access to communication and resources. -

-
-
-

Community

-

- We foster meaningful connections and a sense of belonging for all members. -

-
-
-
-
-
- {/* CTA */}

Get Involved

- Join us in our mission to support and empower the deaf community in Louisiana. + Join us in our mission to support and empower the Deaf community in Louisiana.

- Become a Member - Contact Us diff --git a/frontend/src/app/contact/page.tsx b/frontend/src/app/contact/page.tsx index 837664e..8df2366 100644 --- a/frontend/src/app/contact/page.tsx +++ b/frontend/src/app/contact/page.tsx @@ -61,6 +61,15 @@ export default function ContactPage() {

Hours: Mon–Fri, 9am–4pm

+
+

Mailing Address

+

+ Louisiana Association of the Deaf
+ 3112 Valley Creek Drive, Suite E
+ Baton Rouge, LA 70808 +

+
+

Follow Us

diff --git a/frontend/src/app/deaf-focus/page.tsx b/frontend/src/app/deaf-focus/page.tsx index b83930a..47a15d9 100644 --- a/frontend/src/app/deaf-focus/page.tsx +++ b/frontend/src/app/deaf-focus/page.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type { Metadata } from 'next'; import Image from 'next/image'; import Link from 'next/link'; +import { sanitizeHtml } from '@/utils/sanitize-html'; export const metadata: Metadata = { title: 'Deaf Focus | Louisiana Association of the Deaf', @@ -41,7 +42,7 @@ export default async function DeafFocusPage() {
Deaf Focus logo {article.body && ( -
- {article.body.split('\n').map((line, i) => ( -

{line}

- ))} -
+
)} )) @@ -97,12 +97,20 @@ export default async function DeafFocusPage() {

Request an Interpreter

Deaf Focus provides professional, certified sign language interpreters throughout Louisiana. - Contact us at least 10 business days in advance. + Submit requests at least 30 days in advance for best availability.

+ Submit Online Request + + Email Request @@ -113,6 +121,7 @@ export default async function DeafFocusPage() { Call (225) 319-5586
+

Fax: (225) 308-4025 · Hours: Mon–Fri, 9am–4pm

diff --git a/frontend/src/app/donate/page.tsx b/frontend/src/app/donate/page.tsx index 04303df..01792c6 100644 --- a/frontend/src/app/donate/page.tsx +++ b/frontend/src/app/donate/page.tsx @@ -96,7 +96,10 @@ export default function DonatePage() { {/* Impact */}
-

Your Impact

+

Your Impact

+

+ Since 2019, LAD has disbursed over $100,000 directly supporting our community — services, project funding, sponsorships, scholarships, and more. +

How Your Donation Helps

@@ -104,71 +107,41 @@ export default function DonatePage() {
  • - Community Events: Funds community gatherings, social events, and cultural celebrations that bring our deaf community together. + Community Events: Funds community gatherings, social events, and cultural celebrations that bring our Deaf community together.

  • - Educational Workshops: Supports ASL classes, interpreter training, and educational workshops for members and the broader community. + Educational Programs: Supports ASL classes, tutoring, and educational workshops for members and the broader community.

  • - Advocacy: Enables our work advocating for accessibility and deaf rights in local businesses, schools, and government. + Advocacy: Enables our work advancing Deaf rights through legislation, policy, and public awareness.

  • - Youth Programs: Funds activities and mentorship opportunities for deaf and hard-of-hearing youth in our community. + Youth & Emergency: Supports Deaf youth programs, toy drives, book drives, and emergency disaster relief.

  • -

    Donation Allocation

    -
    -
    -
    - Community Events - 40% +

    Established Funds

    +

    You may designate your contribution to a specific fund:

    +
    + {['Youth Fund', 'Apparel Fund', 'Book Drive Fund', 'Toy Drive Fund', 'Office Renovations Fund', 'Emergency Disaster Fund'].map((fund) => ( +
    +

    {fund}

    -
    -
    -
    -
    -
    -
    - Educational Programs - 30% -
    -
    -
    -
    -
    -
    -
    - Advocacy - 15% -
    -
    -
    -
    -
    -
    -
    - Youth Programs - 15% -
    -
    -
    -
    -
    + ))}

    - Financial information and annual reports are available upon request. + Undesignated contributions support general operations. Financial information and annual reports are available upon request.

    @@ -181,7 +154,7 @@ export default function DonatePage() {

    Corporate Sponsorship

    - We welcome partnerships with businesses and organizations that share our commitment to the deaf community. + We welcome partnerships with businesses and organizations that share our commitment to the Deaf community. Corporate sponsors receive recognition in our events, publications, and website.

    @@ -211,7 +184,11 @@ export default function DonatePage() {

    Do you accept donations by check or mail?

    - Yes, checks can be made payable to "Louisiana Association of the Deaf" and mailed to our office address. Please contact us for the current mailing address. + Yes. Make checks or money orders payable to Louisiana Association of the Deaf and mail to: +

    +

    + 3112 Valley Creek Drive, Suite E
    + Baton Rouge, LA 70808

    diff --git a/frontend/src/app/events/page.tsx b/frontend/src/app/events/page.tsx index e05cdf1..eb29a5a 100644 --- a/frontend/src/app/events/page.tsx +++ b/frontend/src/app/events/page.tsx @@ -1,6 +1,7 @@ import React from 'react'; import Link from 'next/link'; import type { Metadata } from 'next'; +import { sanitizeHtml } from '@/utils/sanitize-html'; export const metadata: Metadata = { title: 'Events | Louisiana Association of the Deaf', @@ -47,7 +48,10 @@ const EventCard = ({ event }: { event: Event }) => (

    {event.title}

    {formatDate(event.date)}{event.time ? ` · ${event.time}` : ''}

    {event.location}

    -

    {event.description}

    +
    ); diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 1d6d0ed..2415953 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -519,6 +519,21 @@ main { color: var(--color-primary); } +.nav-dropdown { + background-color: var(--color-bg); + border: 1px solid var(--color-border); +} + +.nav-dropdown-item { + color: var(--color-text); + transition: all 0.15s ease; +} + +.nav-dropdown-item:hover { + background-color: var(--color-bg-secondary); + color: var(--color-primary); +} + /* ========================================== */ /* HIGH CONTRAST NAVIGATION FIXES */ /* ========================================== */ @@ -605,6 +620,36 @@ main { border: 3px solid #FFFFFF !important; } +.high-contrast-light .nav-dropdown { + background-color: #FFFFFF !important; + border: 2px solid #000000 !important; +} + +.high-contrast-light .nav-dropdown-item { + color: #000000 !important; + font-weight: 700 !important; +} + +.high-contrast-light .nav-dropdown-item:hover { + background-color: #000000 !important; + color: #FFFFFF !important; +} + +.high-contrast-dark .nav-dropdown { + background-color: #000000 !important; + border: 2px solid #FFFFFF !important; +} + +.high-contrast-dark .nav-dropdown-item { + color: #FFFFFF !important; + font-weight: 700 !important; +} + +.high-contrast-dark .nav-dropdown-item:hover { + background-color: #FFFFFF !important; + color: #000000 !important; +} + /* ========================================== */ /* HERO COMPONENTS */ /* ========================================== */ diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 8b902f7..43f5073 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -15,13 +15,13 @@ const inter = Inter({ export const metadata: Metadata = { title: 'Louisiana Association of the Deaf', - description: 'The statewide organization serving the deaf and hard-of-hearing community in Louisiana since 1908.', + description: 'The statewide organization serving the Deaf and hard-of-hearing community in Louisiana since 1908.', metadataBase: new URL('https://lad1908.org'), - keywords: ['deaf', 'louisiana', 'LAD', 'association', 'ASL', 'events', 'advocacy'], + keywords: ['Deaf', 'louisiana', 'LAD', 'association', 'ASL', 'events', 'advocacy'], authors: [{ name: 'Louisiana Association of the Deaf' }], openGraph: { title: 'Louisiana Association of the Deaf', - description: 'The statewide organization serving the deaf and hard-of-hearing community in Louisiana since 1908.', + description: 'The statewide organization serving the Deaf and hard-of-hearing community in Louisiana since 1908.', url: 'https://lad1908.org', siteName: 'Louisiana Association of the Deaf', images: [ @@ -38,7 +38,7 @@ export const metadata: Metadata = { twitter: { card: 'summary_large_image', title: 'Louisiana Association of the Deaf', - description: 'The statewide organization serving the deaf and hard-of-hearing community in Louisiana since 1908.', + description: 'The statewide organization serving the Deaf and hard-of-hearing community in Louisiana since 1908.', images: ['/images/og-image.jpg'], }, }; diff --git a/frontend/src/app/membership/page.tsx b/frontend/src/app/membership/page.tsx index 6f420cf..4ecdcd8 100644 --- a/frontend/src/app/membership/page.tsx +++ b/frontend/src/app/membership/page.tsx @@ -4,7 +4,7 @@ import type { Metadata } from 'next'; export const metadata: Metadata = { title: 'Membership | Louisiana Association of the Deaf', - description: 'Join the Louisiana Association of the Deaf and become part of our statewide community. Learn about membership benefits and how to apply.', + description: 'Join the Louisiana Association of the Deaf. Membership is open to Deaf, DeafBlind, and hard of hearing individuals, their families, and allies across Louisiana.', }; export default function MembershipPage() { @@ -16,7 +16,7 @@ export default function MembershipPage() {

    Become a Member

    - Join our statewide community and connect with Deaf individuals and allies across Louisiana. + Join our statewide community and connect with Deaf, DeafBlind, and hard of hearing individuals and allies across Louisiana.

    @@ -36,7 +36,7 @@ export default function MembershipPage() {
  • - Opportunities to build relationships with other deaf community members + Opportunities to build relationships with other Deaf community members
  • @@ -45,7 +45,7 @@ export default function MembershipPage() {
  • -

    Club Governance

    +

    Governance & Voice

    • @@ -53,24 +53,24 @@ export default function MembershipPage() {
    • - Eligibility to run for board positions + Eligibility to run for board positions (Full Members)
    • - Opportunity to shape the future of LAD through input and feedback + Shape the future of LAD through input and feedback
    -

    Resources & Support

    +

    Resources & Support

    • - Access to club resources and information + Access to members-only meeting minutes and documents
    • - Support network of deaf and hard-of-hearing individuals + Support network of Deaf and hard-of-hearing individuals
    • @@ -85,104 +85,44 @@ export default function MembershipPage() { {/* Membership Types */}
      -

      Membership Types

      -
      -
      -
      -

      Regular

      -

      Annual membership

      +

      Membership Types

      +

      + LAD membership is open to Deaf, DeafBlind, and hard of hearing individuals, their families, professionals, and allies. +

      +
      + {[ + { + title: 'Full Member', + who: 'Deaf individuals 18+ residing in Louisiana with dues paid.', + rights: 'Full voting rights and eligibility to hold office.', + }, + { + title: 'Associate Member', + who: 'Hearing individuals (in or out of Louisiana), or non-Louisiana Deaf individuals 18+ with dues paid.', + rights: 'All rights of Full Members except holding office.', + }, + { + title: 'Honorary Member', + who: 'Conferred by a two-thirds vote of members at a biennial Conference Meeting.', + rights: 'All rights of Full Members.', + }, + { + title: 'Student Member', + who: 'Deaf high school seniors may request membership.', + rights: '2-year complimentary membership; all rights except holding office.', + }, + { + title: 'Senior Member', + who: 'Senior Deaf community members meeting eligibility criteria.', + rights: 'Reduced dues; full participation in LAD activities.', + }, + ].map((t) => ( +
      +

      {t.title}

      +

      Who: {t.who}

      +

      Rights: {t.rights}

      -
        -
      • - - Standard membership for individuals 18+ -
      • -
      • - - Full voting rights -
      • -
      • - - Access to all events and activities -
      • -
      • - - Eligibility for board positions -
      • -
      -
      - Apply Now -
      -
      -
      -
      - Most Popular -

      Family

      -

      Annual membership

      -
      -
        -
      • - - Covers 2 adults and children under 18 -
      • -
      • - - Two voting memberships -
      • -
      • - - Access to all events and activities -
      • -
      • - - Eligibility for board positions -
      • -
      • - - Family-friendly event notifications -
      • -
      -
      - Apply Now -
      -
      -
      -
      -

      Lifetime

      -

      One-time payment

      -
      -
        -
      • - - One-time payment for lifetime membership -
      • -
      • - - Full voting rights -
      • -
      • - - Access to all events and activities -
      • -
      • - - Eligibility for board positions -
      • -
      • - - Recognition as lifetime supporter -
      • -
      -
      - Apply Now -
      -
      -
      -
      -

      - Please contact us - for current membership rates and any available discounts. -

      + ))}
      @@ -198,10 +138,9 @@ export default function MembershipPage() { 1
    -

    Complete Application

    +

    Complete the Membership Form

    - Contact us through the website or attend one of our events to get a membership application form. - You can also download the form and submit it via email. + Download and fill out the membership application form. Contact us or attend one of our events to get a copy.

    @@ -211,9 +150,23 @@ export default function MembershipPage() {

    Pay Membership Dues

    -

    - Submit your membership dues via check, cash, or online payment. Dues can be paid annually or as a one-time payment for lifetime membership. +

    + Submit your dues using one of the following methods:

    +
    +
    +

    Venmo

    +

    @LAD1908 — please include “Membership” in the note

    +
    +
    +

    Mail a Check or Money Order

    +

    + Payable to Louisiana Association of the Deaf
    + 3112 Valley Creek Drive, Suite E
    + Baton Rouge, LA 70808 +

    +
    +
    @@ -221,20 +174,9 @@ export default function MembershipPage() { 3
    -

    Board Approval

    +

    Get Connected

    - All applications are reviewed and approved by the LAD board. This process typically takes 1-2 weeks. -

    -
    - -
    -
    - 4 -
    -
    -

    Receive Membership Card

    -

    - Once approved, you'll receive your official LAD membership confirmation and welcome packet with information about upcoming events and activities. + Once your membership is processed, you'll receive confirmation and gain access to member resources, upcoming events, and the LAD community.

    @@ -244,43 +186,13 @@ export default function MembershipPage() { href="/contact" className="btn-primary inline-block px-8 py-3 rounded-lg" > - Request Application Form + Contact Us to Get Started
    - {/* Testimonials */} -
    -
    -

    What Our Members Say

    -
    -
    -
    - "Joining LAD was one of the best decisions I've made. It's helped me connect with the Deaf community across Louisiana and make lifelong friends." -
    -
    Sarah K.
    -
    Member since 2019
    -
    -
    -
    - "As a parent of a deaf child, LAD has been an invaluable resource for our family. The events and workshops have helped us all learn and grow together." -
    -
    David M.
    -
    Member since 2021
    -
    -
    -
    - "I love being part of such a vibrant and supportive community. The social events and activities have really enriched my life." -
    -
    Maria J.
    -
    Member since 2018
    -
    -
    -
    -
    - {/* CTA */}
    diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index c8499e4..fcf07f5 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -2,111 +2,31 @@ import React from 'react'; import Link from 'next/link'; -import Image from 'next/image'; import Hero from '../components/molecules/Hero'; -// Featured Event Card Component -interface EventCardProps { - title: string; - description: string; - date: string; - imageUrl?: string; - slug: string; -} - -const EventCard: React.FC = ({ - title, - description, - date, - imageUrl, - slug -}) => { - return ( -
    -
    - {imageUrl ? ( - {title} - ) : ( -
    - No image available -
    - )} -
    -
    -

    {title}

    -

    {description}

    -
    - {date} - - Learn more - -
    -
    -
    - ); -}; - export default function Home() { return ( <> - {/* Announcement Banner */} -
    - Upcoming: - - NOBDA & LAD Collaboration — A Special Book Reading with Franklin Jones on BASL, - Saturday, May 23rd. - - Details → -
    - {/* Hero Section */} - {/* Featured events section */} + {/* Events CTA section */}
    -
    -

    Featured Events

    -
    - - - -
    -
    - - View All Events - -
    +
    +

    Upcoming Events

    +

    + From our monthly ASL Meet & Greet at Torchy's Tacos to our biennial statewide conference — there's always something happening in the Louisiana Deaf community. +

    + + View All Events +
    @@ -117,13 +37,13 @@ export default function Home() {

    - The Louisiana Association of the Deaf (LAD) is a non-profit statewide organization dedicated to serving the deaf and hard-of-hearing community across Louisiana. + The Louisiana Association of the Deaf (LAD) is the oldest, largest, and premier nonprofit organization for the Deaf, DeafBlind, and hard of hearing (DDBHH) citizens in Louisiana. Founded in 1908 by alumni of the Louisiana School for the Deaf, LAD is one of fifty state affiliates of the National Association of the Deaf.

    - Our mission is to advocate for the rights, education, and well-being of deaf and hard-of-hearing individuals throughout Louisiana while fostering a strong sense of community. + Our mission is to preserve, protect, and promote the civil, human, and linguistic rights of Deaf citizens of Louisiana — while fostering community, culture, and equal access for all DDBHH individuals.

    - Founded in 1908, LAD has over a century of advocacy and community service, working to advance opportunities and equal access for the deaf community. + LAD also operates Deaf Focus, a Deaf-led services organization providing interpreting, ASL classes, advocacy, and community resources statewide.

    Learn More About Us @@ -159,7 +79,7 @@ export default function Home() {

    Advocacy Support

    - Benefit from LAD's statewide advocacy work advancing the rights of deaf Louisianans. + Benefit from LAD's statewide advocacy work advancing the rights of Deaf Louisianans.

    @@ -179,7 +99,7 @@ export default function Home() {

    Join Our Community

    - Become a member today and connect with the deaf community across Louisiana. + Become a member today and connect with the Deaf community across Louisiana.

    Support Network

    - Connect with a supportive network of deaf and hard-of-hearing individuals. + Connect with a supportive network of Deaf and hard-of-hearing individuals.

    @@ -141,7 +141,7 @@ export default function ThemeSamples() {

    Support Network

    - Connect with a supportive network of deaf and hard-of-hearing individuals. + Connect with a supportive network of Deaf and hard-of-hearing individuals.

    diff --git a/frontend/src/app/updates/page.tsx b/frontend/src/app/updates/page.tsx index 1e61893..9f2a791 100644 --- a/frontend/src/app/updates/page.tsx +++ b/frontend/src/app/updates/page.tsx @@ -1,6 +1,7 @@ import React from 'react'; import type { Metadata } from 'next'; import Link from 'next/link'; +import { sanitizeHtml } from '@/utils/sanitize-html'; export const metadata: Metadata = { title: 'Updates | Louisiana Association of the Deaf', @@ -68,21 +69,15 @@ export default async function UpdatesPage() {

    {update.title}

    -

    {update.body}

    +
    )) )}
    -
    -

    - Showing recent highlights. Full update archive available to members.{' '} - - Join LAD - {' '} - for complete access. -

    -
    diff --git a/frontend/src/components/molecules/Hero.tsx b/frontend/src/components/molecules/Hero.tsx index 31a83a5..22ca707 100644 --- a/frontend/src/components/molecules/Hero.tsx +++ b/frontend/src/components/molecules/Hero.tsx @@ -66,7 +66,7 @@ const Hero: React.FC = ({ return (
    @@ -74,12 +74,13 @@ const Hero: React.FC = ({ {title} @@ -89,6 +90,7 @@ const Hero: React.FC = ({ className={`text-xl md:text-2xl mb-8 ${ backgroundImageUrl ? 'hero-subtitle-image' : 'hero-subtitle' }`} + initial={false} variants={itemVariants} > {subtitle} @@ -96,6 +98,7 @@ const Hero: React.FC = ({ ( - +const MenuIcon = () => ( + ); -const CloseIcon = ({ className = '' }: { className?: string }) => ( - +const CloseIcon = () => ( + ); +const ChevronDown = ({ open }: { open: boolean }) => ( + + + +); + interface NavLinkProps { href: string; children: React.ReactNode; @@ -43,19 +35,11 @@ interface NavLinkProps { const NavLink = ({ href, children, isMobile = false, onClick }: NavLinkProps) => { const pathname = usePathname(); const isActive = pathname === href; - - const baseStyles = "transition-colors duration-200 px-2 py-2 rounded-md text-base font-medium"; - const mobileStyles = isMobile ? "block w-full text-left" : ""; - // Create a visually distinct style for active links using CSS variables - const activeStyles = isActive - ? "nav-link-active" - : "nav-link"; - return ( {children} @@ -63,51 +47,61 @@ const NavLink = ({ href, children, isMobile = false, onClick }: NavLinkProps) => ); }; +const getInvolvedLinks = [ + { href: '/membership', label: 'Membership' }, + { href: '/minutes', label: 'Minutes' }, + { href: '/contact', label: 'Contact' }, +]; + const Navigation = () => { const [isOpen, setIsOpen] = useState(false); + const [dropdownOpen, setDropdownOpen] = useState(false); + const [mobileDropdownOpen, setMobileDropdownOpen] = useState(false); const [scrolled, setScrolled] = useState(false); - - const toggleMenu = () => setIsOpen(!isOpen); - const closeMenu = () => setIsOpen(false); - - // Handle scroll effect + const dropdownRef = useRef(null); + const pathname = usePathname(); + + const closeMenu = () => { + setIsOpen(false); + setMobileDropdownOpen(false); + }; + + const dropdownActive = getInvolvedLinks.some(l => l.href === pathname); + useEffect(() => { - const handleScroll = () => { - const offset = window.scrollY; - if (offset > 50) { - setScrolled(true); - } else { - setScrolled(false); - } - }; - + const handleScroll = () => setScrolled(window.scrollY > 50); window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); - - // Close menu on ESC key + useEffect(() => { - const handleEsc = (event: KeyboardEvent) => { - if (event.key === 'Escape') { - setIsOpen(false); - } - }; - + const handleEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') { setIsOpen(false); setDropdownOpen(false); } }; window.addEventListener('keydown', handleEsc); return () => window.removeEventListener('keydown', handleEsc); }, []); - + + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) { + setDropdownOpen(false); + } + }; + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + // Close dropdown on route change + useEffect(() => { setDropdownOpen(false); }, [pathname]); + return ( -
    - {/* Logo and site name */} + + {/* Logo */}
    { LAD
    - - {/* Desktop navigation */} -
    -
    - Home - About - Updates - Events - Minutes - Deaf Focus - Membership - Contact - Donate - + + {/* Desktop nav */} +
    + About + Updates + Events + Deaf Focus + + {/* Get Involved dropdown */} +
    + + {dropdownOpen && ( +
    + {getInvolvedLinks.map(l => ( + + {l.label} + + ))} +
    + )}
    + + {/* Donate button */} + + Donate + + +
    - + {/* Mobile menu button */} -
    +
    + + Donate +
    - - {/* Mobile menu, show/hide based on menu state */} -
    + + {/* Mobile menu */} +
    - Home About Updates Events - Minutes Deaf Focus - Membership - Contact - Donate + + {/* Get Involved accordion */} + + {mobileDropdownOpen && ( +
    + {getInvolvedLinks.map(l => ( + {l.label} + ))} +
    + )} +
    diff --git a/frontend/src/utils/sanitize-html.ts b/frontend/src/utils/sanitize-html.ts new file mode 100644 index 0000000..593728a --- /dev/null +++ b/frontend/src/utils/sanitize-html.ts @@ -0,0 +1,28 @@ +const ALLOWED_TAGS = new Set([ + 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'ul', 'ol', 'li', + 'strong', 'em', 'b', 'i', + 'br', 'a', 'span', 'blockquote', +]); + +export function sanitizeHtml(html: string): string { + if (!html) return ''; + return html + .replace(/<(\/?)([a-zA-Z][a-zA-Z0-9]*)\b([^>]*)>/g, (_, close, tag, attrs) => { + const t = tag.toLowerCase(); + if (!ALLOWED_TAGS.has(t)) return ''; + if (close) return ``; + if (t === 'a') { + const m = attrs.match(/href="([^"]*)"/i); + const href = m ? m[1] : null; + if (!href) return ''; + const safe = /^(https?:|mailto:|tel:|\/)/i.test(href) ? href : '#'; + return ``; + } + if (t === 'br') return '
    '; + return `<${t}>`; + }) + // Strip empty tags that were only used for spacing + .replace(/<([a-z][a-z0-9]*)\s*>\s*( | )?\s*<\/\1>/gi, '') + .trim(); +}