Skip to content
Merged
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
Binary file added public/figma-home/downloaded-node-2800-19876.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/figma-home/downloaded-node-2800-19884.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/figma-home/downloaded-node-2800-19886.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/figma-home/downloaded-node-2800-19890.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/figma-home/downloaded-node-2800-19892.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/figma-home/downloaded-node-2863-17140.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 28 additions & 33 deletions src/features/marketing/components/donation-hero-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,51 @@ export function DonationHeroSection() {
</p>

<h1 className="mt-5 font-sans text-[28px]/[100%] leading-[1.16] font-extrabold text-balance text-primary sm:leading-[70px] lg:mt-7.5 lg:text-[60px]/[70px] lg:tracking-tight-xl">
Your Support Keeps Someone in the Game
Changing Lives Through Education, Advocacy & Hope{" "}
</h1>

<p className="mt-5 text-base leading-normal text-ma-text lg:mt-10 lg:text-lg">
When AI changes the rules, not everyone gets the manual.
ModernAdvocates Inc. makes sure the people who need it most
don&apos;t get left behind.
<p className="mt-5 text-base leading-normal text-ma-text sm:mt-10 sm:text-lg">
Modern Advocates equips people facing life’s unexpected challenges
with the knowledge, technology, and support needed to move forward
with confidence.
</p>
</div>

<div className="mt-16 grid gap-5 lg:grid-cols-2">
<div className="relative min-h-[424px] overflow-hidden rounded-card-2 bg-ma-bg lg:min-h-[420px]">
<Image
src="/figma-about/founder.png"
alt="Melanie Reyes, founder of ModernAdvocates Inc."
fill
priority
sizes="(min-width: 1024px) 510px, calc(100vw - 48px)"
className="object-cover object-[center_42%]"
/>
</div>
<Image
src="/figma-home/melanie-and-will.png"
alt="Melanie Reyes, founder of ModernAdvocates Inc."
priority
className="rounded-card-2 object-cover sm:h-full"
width={510}
height={560}
/>
Comment on lines +24 to +31

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update the alt text to match the new image.

The image now shows both founders, and the card below reads "Melanie And Will" / "Founders". The alt text still names only Melanie Reyes as the founder. Screen reader users receive incorrect information.

♿ Proposed fix for the alt text
           <Image
             src="/figma-home/melanie-and-will.png"
-            alt="Melanie Reyes, founder of ModernAdvocates Inc."
+            alt="Melanie and Will, founders of ModernAdvocates Inc."
             priority
📝 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
<Image
src="/figma-home/melanie-and-will.png"
alt="Melanie Reyes, founder of ModernAdvocates Inc."
priority
className="rounded-card-2 object-cover sm:h-full"
width={510}
height={560}
/>
<Image
src="/figma-home/melanie-and-will.png"
alt="Melanie and Will, founders of ModernAdvocates Inc."
priority
className="rounded-card-2 object-cover sm:h-full"
width={510}
height={560}
/>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/marketing/components/donation-hero-section.tsx` around lines 24
- 31, Update the alt text on the Image displaying melanie-and-will.png to
accurately describe both founders, matching the card’s “Melanie And Will” /
“Founders” content instead of naming only Melanie Reyes.


<article className="flex flex-col rounded-card-2 bg-ma-surface-2 px-4 py-7.5 lg:min-h-[550px] lg:p-7">
<div>
<h2 className="text-[30px] leading-normal font-semibold text-ma-text sm:text-4xl lg:text-[32px]">
Melanie Reyes
<h2 className="text-3xl leading-normal font-semibold text-ma-text sm:text-4xl">
Melanie And Will
</h2>
<p className="text-base leading-normal text-black">Founder</p>
<p className="text-base leading-normal">Founders</p>
</div>

<div className="mt-[31px] space-y-5 text-base leading-normal text-ma-text sm:text-lg">
<p>
I built this organization because I lived the gap it&apos;s
filling. Every dollar you give goes directly to someone
navigating what I once navigated alone.
</p>
<p>
Interested in partnering, granting, or investing? Reach out
here.
</p>
<p>
We know what it’s like when illness changes everything.
<br /> <br /> Our journey with endometriosis affected nearly
every part of our lives—our health, careers, finances,
relationships, and future. Along the way, Jehovah answered our
prayers through the kindness and generosity of others. <br />{" "}
<br /> Modern Advocates was created to extend that same hope.{" "}
<br /> <br />
Today, we help people facing chronic illness, disability, and
financial hardship discover practical pathways forward through
education, AI, health advocacy, and community support. <br />
<br />
ModernAdvocates Inc. is a 501(c)(3) nonprofit organization. EIN:
[insert]. All donations are tax-deductible to the full extent
42-3785190. All donations are tax-deductible to the full extent
permitted by law.
</p>
<p>
<strong>Melanie Reyes,</strong>
<br />
Founder
</p>
</div>
</article>
</div>
Expand Down
236 changes: 22 additions & 214 deletions src/features/marketing/components/donation-support-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ import { Field, FieldError, FieldLabel } from "@/shared/ui/field"
import { MarketingButton } from "@/shared/ui/marketing-button"
import { Input } from "@/shared/ui/input"
import { apiFetch } from "@/shared/lib/api-fetch"
import DonationForm from "./donation-form"

const donationTypes = ["Fixed Donation", "Tier Donation", "Monthly Pay"] as const
const donationTypes = [
"Fixed Donation",
"Tier Donation",
"Monthly Pay",
] as const
const donationAmounts = [100, 200, 1000]

const donationFormSchema = z.object({
Expand Down Expand Up @@ -46,7 +51,8 @@ export function DonationSupportSection() {

const watchedDonationType = form.watch("donationType")
const showAmountSelector =
watchedDonationType === "Tier Donation" || watchedDonationType === "Monthly Pay"
watchedDonationType === "Tier Donation" ||
watchedDonationType === "Monthly Pay"

async function onSubmit(data: z.infer<typeof donationFormSchema>) {
setSubmitting(true)
Expand All @@ -63,229 +69,31 @@ export function DonationSupportSection() {

window.location.href = result.url
} catch (err) {
toast.error(err instanceof Error ? err.message : "Something went wrong. Please try again.")
toast.error(
err instanceof Error
? err.message
: "Something went wrong. Please try again."
)
setSubmitting(false)
}
}

return (
<section className="bg-white py-12.5 text-ma-text lg:py-25">
<div className="mx-auto grid items-start gap-12 px-4 lg:max-w-7xl lg:grid-cols-2 lg:gap-6 lg:px-25 2xl:max-w-360 2xl:px-50">
<section className="bg-[#ECE8FF] py-12.5 text-ma-text lg:py-25">
<div className="mx-auto grid items-center gap-12 px-4 lg:max-w-7xl lg:grid-cols-2 lg:gap-6 lg:px-25 2xl:max-w-360 2xl:px-50">
<div className="pt-0 lg:pt-2">
<h2 className="font-sans text-[28px]/[100%] leading-[1.12] font-extrabold text-balance text-primary lg:text-[60px]/[70px] lg:tracking-tight-xl">
Support us and make a difference for the future!
<h2 className="font-sans text-3xl leading-[1.12] font-extrabold text-balance text-primary sm:text-5xl sm:tracking-tight-xl">
Invest in Hope
</h2>
<p className="mt-[30px] max-w-[506px] text-base leading-normal text-primary lg:text-lg">
Together, we can make a real impact in communities around the world.
Help us bring hope and support.
Your gift helps fund: <br /> <br />
AI & Digital Skills Education, Health Advocacy, Patient Resource
Navigation, Workforce Readiness, Chronic Illness Support, and
Endometriosis Education.
</p>
</div>

<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex w-full flex-col gap-[30px] rounded-card-2 border border-ma-border-light bg-ma-surface-2 px-4 pt-[30px] pb-7 sm:px-[30px] lg:px-7"
>
<div className="border-b border-ma-border-light pb-2.5">
<h3 className="text-2xl leading-normal font-bold text-black">
Make Your Donation
</h3>
</div>

<Controller
control={form.control}
name="donationType"
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid}>
<legend className="text-xl leading-normal font-semibold text-black">
Type of Donation
</legend>

<div className="grid gap-3 sm:grid-cols-3">
{donationTypes.map((type) => (
<label
key={type}
className="flex min-w-0 items-start gap-2 text-base leading-normal text-muted-foreground"
>
<input
type="radio"
name={field.name}
value={type}
checked={field.value === type}
onChange={() => field.onChange(type)}
aria-invalid={fieldState.invalid}
className="mt-0.5 size-5 shrink-0 accent-ma-glow-violet"
/>
<span>{type}</span>
</label>
))}
</div>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
</Field>
)}
/>

{showAmountSelector ? (
<Controller
control={form.control}
name="amount"
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid}>
<label className="text-xl leading-normal font-semibold text-black">
Select Donation Amount
</label>
<div className="flex flex-col gap-2">
{donationAmounts.map((amount) => (
<label
key={amount}
className={`relative cursor-pointer rounded-[6px] ${
field.value === amount
? "bg-linear-[90deg] from-[#4F7CF7] from-[0%] to-[#7B5CFF] to-[68.27%] p-[1.1px] pb-[1.3px]"
: "border border-border"
}`}
>
<div
className={`flex items-center justify-between rounded-[5px] bg-white px-4 py-2.5 text-base/[100%] font-medium ${
field.value === amount
? "text-ma-text"
: "text-ma-text"
}`}
>
<span>${amount}</span>
<input
type="radio"
name={field.name}
value={amount}
checked={field.value === amount}
onChange={() => field.onChange(amount)}
aria-invalid={fieldState.invalid}
className="size-5 accent-ma-glow-violet"
/>
</div>
</label>
))}
</div>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
</Field>
)}
/>
) : (
<Controller
control={form.control}
name="amount"
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid}>
<label htmlFor={field.name} className="sr-only">
Donation amount
</label>
<div className="relative">
<Input
id={field.name}
type="number"
inputMode="decimal"
placeholder="Enter Amount"
value={field.value || ""}
onChange={(e) => field.onChange(parseFloat(e.target.value) || 0)}
aria-invalid={fieldState.invalid}
className="h-10 rounded-[6px] border-border bg-white px-4 py-2.5 pr-10 text-base placeholder:text-muted-foreground"
/>
<span
className="pointer-events-none absolute top-1/2 right-4 -translate-y-1/2 text-xl leading-none font-bold text-ma-text"
aria-hidden="true"
>
$
</span>
</div>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
</Field>
)}
/>
)}

<div className="flex flex-col gap-4">
<h3 className="text-xl leading-normal font-semibold text-black">
Personal Info
</h3>

<Controller
control={form.control}
name="donorName"
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid}>
<FieldLabel htmlFor={field.name}>
Full Name
</FieldLabel>
<Input
{...field}
id={field.name}
autoComplete="name"
placeholder="Enter full name"
aria-invalid={fieldState.invalid}
className="h-10 rounded-md border-border bg-white px-4 py-2.5 text-base placeholder:text-muted-foreground"
/>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
</Field>
)}
/>

<Controller
control={form.control}
name="donorEmail"
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid}>
<FieldLabel htmlFor={field.name}>
Email
</FieldLabel>
<Input
{...field}
id={field.name}
type="email"
autoComplete="email"
placeholder="Enter email"
aria-invalid={fieldState.invalid}
className="h-10 rounded-md border-border bg-white px-4 py-2.5 text-base placeholder:text-muted-foreground"
/>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
</Field>
)}
/>
</div>

<Controller
control={form.control}
name="confirmation"
render={({ field, fieldState }) => (
<Field data-invalid={fieldState.invalid} orientation="horizontal">
<input
type="checkbox"
id={field.name}
name={field.name}
checked={field.value === true}
onChange={(e) => field.onChange(e.target.checked)}
aria-invalid={fieldState.invalid}
className="mt-1 size-[18px] shrink-0 rounded border-border bg-white accent-ma-text"
/>
<label htmlFor={field.name} className="text-base leading-normal text-muted-foreground">
By submitting this form, you confirm the accuracy of the donation
amount and authorize the payment processing via the checkout page.
</label>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
</Field>
)}
/>

<MarketingButton
type="submit"
disabled={submitting}
className="w-full"
>
{submitting && <LoaderCircle className="size-4 animate-spin" aria-hidden="true" />}
Donate Now
<ArrowRight
className="size-5 transition-transform duration-300 group-hover:rotate-[-30deg]"
aria-hidden="true"
/>
</MarketingButton>
</form>
<DonationForm />
Comment on lines 81 to +96

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify DonationForm props/usage and confirm /api/donations callers.
set -euo pipefail

echo "=== DonationForm definition and props ==="
fd -t f 'donation-form.tsx' --exec cat -n {}

echo "=== All DonationForm usages ==="
rg -nP --type=tsx --type=ts -C4 '<DonationForm\b|from ["'"'"'].*donation-form["'"'"']'

echo "=== Callers of /api/donations ==="
rg -nP -C6 "['\"\`]/api/donations"

echo "=== Any <form> element in the donation feature ==="
rg -nP -C3 '<form\b' --glob '**/donation*'

Repository: Smartlify07/Modern-Advocates

Length of output: 5446


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== donation-support-section outline ==="
ast-grep outline src/features/marketing/components/donation-support-section.tsx || true

echo "=== donation-support-section relevant source ==="
cat -n src/features/marketing/components/donation-support-section.tsx | sed -n '1,130p'

echo "=== DonationForm usage and donationForm import search ==="
rg -n --glob '**/*.{ts,tsx}' -C3 '<DonationForm\b|donation-form|donationTypes|donationFormSchema|useForm|api/donations|authorize-checkbox|custom-amount' src

echo "=== form/button submit wiring in donation-related files ==="
rg -n --glob '**/*.{ts,tsx}' -C2 '<form\b|type="submit"|onClick=|onSubmit=|donation.*submit|Donate Now|authorize-checkbox|custom-amount' src/features/marketing/components src/features --glob '!**/node_modules/**'

Repository: Smartlify07/Modern-Advocates

Length of output: 50384


Wire the donation form to its submission handler.

DonationForm renders standalone fields and a Donate Now button, but that button is not inside a <form>, has no type="submit", and has no onClick. DonationSupportSection creates form, onSubmit, and submitting, but only renders <DonationForm /> with no props. As a result, users cannot submit, onSubmit is unreachable, and /api/donations is not invoked from either donation page.

Move the form contract into DonationForm, or pass form, onSubmit, and submitting as props and render the controls inside <form onSubmit={form.handleSubmit(onSubmit)}>, with the submit button bound as type="submit".

[high_effort_and_HIGH_reward]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/marketing/components/donation-support-section.tsx` around lines
81 - 96, Connect DonationSupportSection’s existing form, onSubmit, and
submitting state to DonationForm by passing the required props and rendering its
controls inside a form using form.handleSubmit(onSubmit). Make the Donate Now
button type="submit" and reflect submitting state, ensuring the donation
submission invokes /api/donations.

</div>
</section>
)
Expand Down
4 changes: 2 additions & 2 deletions src/features/marketing/components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function Footer() {
return (
<footer className="overflow-hidden bg-white text-ma-text">
<div className="relative mx-auto min-h-125 px-4 pt-12.5 lg:max-w-7xl lg:px-25 lg:pt-17.5 2xl:max-w-360">
<div className="grid gap-10 md:grid-cols-[0.9fr_0.6fr_1.5fr] lg:gap-10 xl:grid-cols-[254px_180px_1fr] xl:justify-between xl:gap-[154px] 2xl:gap-50">
<div className="grid gap-10 md:grid-cols-[0.9fr_0.6fr_1.5fr] lg:gap-10 xl:grid-cols-[254px_180px_1fr] xl:justify-between xl:gap-[140px] 2xl:gap-50">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use a spacing token instead of gap-[140px].

This class introduces an arbitrary spacing value. The repository guidelines prohibit arbitrary spacing. Reuse an existing spacing token. If 140px is required, define a semantic theme token and reference it here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/marketing/components/footer.tsx` at line 16, Update the footer
grid classes in the component containing this div to remove the arbitrary
gap-[140px] value. Replace it with an existing spacing token, or define and use
a semantic theme token if the 140px spacing is required.

Source: Coding guidelines

<section className="">
<h2 className="font-sans text-lg font-extrabold lg:text-2xl">
Get in Touch
Expand Down Expand Up @@ -80,7 +80,7 @@ export function Footer() {
/>
<button
type="submit"
className="group relative inline-flex items-center justify-center gap-2 overflow-hidden rounded-pill bg-ma-text px-[15px] py-3 text-[12.31px] font-semibold text-white transition-transform duration-300 hover:scale-[1.1]"
className="group relative inline-flex items-center justify-center gap-2 overflow-hidden rounded-pill bg-ma-admin-primary px-[15px] py-3 text-[12.31px] font-semibold text-white transition-transform duration-300 hover:scale-[1.1]"
>
<span className="relative z-10 inline-flex items-center gap-2">
Join
Expand Down