feat: add doctor avatars and image to empowerment section - #141
Conversation
…into ch/donation-page-ui-updtes
# Conflicts: # src/features/marketing/components/donation-support-section.tsx
… to remaining pages
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (37)
📝 WalkthroughWalkthroughThe PR adds fee-inclusive donation pricing and a validated checkout form. It also centralizes marketing layout rules, updates responsive presentation across marketing and course pages, adjusts dashboard layouts, and adds API error logging. ChangesDonation checkout flow
Shared marketing layout
Presentation and course updates
API diagnostics
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Donor
participant DonationForm
participant DonationsAPI
participant Stripe
participant DonationSuccessPage
Donor->>DonationForm: Submit donation details
DonationForm->>DonationsAPI: Send validated donation data
DonationsAPI->>Stripe: Create checkout with fee-inclusive amount
Stripe-->>DonationsAPI: Return checkout URL
DonationsAPI-->>DonationForm: Return checkout URL
DonationForm->>Stripe: Redirect to checkout
Stripe-->>DonationSuccessPage: Return donation amount
DonationSuccessPage->>DonationSuccessPage: Compute and format total
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
⚔️ Resolve merge conflicts 💡
🧪 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 |
…mations # Conflicts: # src/features/marketing/components/about-support-mission-section.tsx
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with 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.
Inline comments:
In `@src/app/`(user)/dashboard/page.tsx:
- Around line 76-80: Update the loading skeleton container in the dashboard card
map to use the same sm breakpoint maximum width as CourseCard.Root, changing the
current 300px constraint to the shared 400px width so the loading and loaded
layouts remain aligned.
In `@src/features/marketing/components/course-detail-content-section.tsx`:
- Around line 25-42: Extract the complete CourseContentData type from
course-detail-content-section.tsx into a shared module, then import and reuse it
in both the section component and CourseInformationCard. Ensure the shared
definition includes the full modules/topics and reviews shapes so the two
components cannot drift.
In `@src/features/marketing/components/donation-form.tsx`:
- Around line 100-102: Update the donation copy in the paragraph rendered by the
donation form to replace the period after “hope” with a comma, preserving the
rest of the sentence.
- Line 46: Update the donation form schema around confirmation to require a true
value, include confirmation in the onSubmit request body, and add matching
validation in the POST handler for /api/donations so missing or false
confirmation is rejected before creating a pending donation.
In `@src/features/marketing/components/empowerment-section.tsx`:
- Line 28: Add w-full to the three text wrapper elements in the empowerment
section, including the corresponding wrappers near the referenced locations, so
headings and descriptions span the card width and wrap correctly while
preserving the existing centered layout.
- Around line 69-72: Add alternative text to both AvatarImage instances in the
empowerment section: use alt="" because the adjacent doctor names already
identify the portraits, keeping the avatars decorative.
- Line 153: Update the overlay div in the empowerment section to replace the
arbitrary top-[14%] offset with an existing spacing design token or named layout
utility. Preserve the current positioning and styling while avoiding arbitrary
spacing values.
In `@src/features/marketing/lib/donation-pricing.ts`:
- Around line 3-9: Update computeAdminFee to convert the amount to integer cents
and calculate the fee using integer basis-point arithmetic before converting
back to dollars, ensuring half-cent values round correctly. Keep
computeDonationTotal using the corrected fee result and preserve its existing
cent-based total rounding.
In `@src/shared/lib/api-handler.ts`:
- Line 42: Replace the raw console.error(error) call in the API handler with the
project’s trusted redacting production logger, ensuring caught errors are logged
without exposing sensitive API, payment, email, enrollment, session, or Stripe
transaction fields.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 16a6029e-7bd9-446b-b5cb-0499ae736563
⛔ Files ignored due to path filters (3)
public/figma-home/A-Rivera.pngis excluded by!**/*.pngpublic/figma-home/M-Anderson.pngis excluded by!**/*.pngpublic/figma-home/girl-with-phone.pngis excluded by!**/*.png
📒 Files selected for processing (37)
src/app/(marketing)/donation/success/page.tsxsrc/app/(user)/dashboard/page.tsxsrc/app/api/donations/route.tssrc/app/globals.csssrc/features/courses/components/course-card.tsxsrc/features/courses/components/enroll-now-button.tsxsrc/features/marketing/components/about-hero-section.tsxsrc/features/marketing/components/about-our-values-section.tsxsrc/features/marketing/components/about-support-mission-section.tsxsrc/features/marketing/components/community-section.tsxsrc/features/marketing/components/contact-hero-section.tsxsrc/features/marketing/components/course-detail-content-section.tsxsrc/features/marketing/components/course-detail-hero-section.tsxsrc/features/marketing/components/course-information-card.tsxsrc/features/marketing/components/courses-hero-section.tsxsrc/features/marketing/components/cta-section.tsxsrc/features/marketing/components/donation-cta-section.tsxsrc/features/marketing/components/donation-form.tsxsrc/features/marketing/components/donation-hero-section.tsxsrc/features/marketing/components/donation-support-section.tsxsrc/features/marketing/components/empowerment-section.tsxsrc/features/marketing/components/faq.tsxsrc/features/marketing/components/footer.tsxsrc/features/marketing/components/how-can-we-help.tsxsrc/features/marketing/components/how-can-we-support.tsxsrc/features/marketing/components/invest-in-hope-section.tsxsrc/features/marketing/components/mission-sections.tsxsrc/features/marketing/components/our-vision-section.tsxsrc/features/marketing/components/practical-pathways-section.tsxsrc/features/marketing/components/stories-from-our-community-section.tsxsrc/features/marketing/components/testimonials.tsxsrc/features/marketing/lib/donation-pricing.tssrc/features/user-dashboard/components/course-player-navbar.tsxsrc/features/user-dashboard/components/dashboard-navbar.tsxsrc/shared/lib/api-handler.tssrc/shared/ui/marketing-button.tsxsrc/shared/ui/marketing-container.tsx
| export function RestoreHopeCard() { | ||
| return ( | ||
| <div className="relative flex h-120 w-full flex-col justify-between overflow-hidden rounded-2xl bg-[#ECE8FF] px-7.5 py-10"> | ||
| <div className="relative flex h-120 w-full flex-col items-center justify-between overflow-hidden rounded-2xl bg-[#ECE8FF] px-7.5 py-10"> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Keep the card text wrappers at full width.
items-center applies to every direct child. The heading and description wrappers have no width class. They can shrink to max-content width instead of wrapping to the card width. Long descriptions can be clipped by overflow-hidden.
Add w-full to the three text wrappers, or center only the preview panels.
Also applies to: 53-53, 134-134
🤖 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/empowerment-section.tsx` at line 28, Add
w-full to the three text wrapper elements in the empowerment section, including
the corresponding wrappers near the referenced locations, so headings and
descriptions span the card width and wrap correctly while preserving the
existing centered layout.
| <Avatar className="size-12 shrink-0"> | ||
| <AvatarImage src="/figma-home/M-Anderson.png" /> | ||
| <AvatarFallback>MA</AvatarFallback> | ||
| </Avatar> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Add alternative text handling for the avatar images.
AvatarImage renders an image element, but neither image supplies alt. Because each doctor name is already rendered beside the image, use alt="" for a decorative portrait or provide a meaningful description.
Also applies to: 98-101
🤖 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/empowerment-section.tsx` around lines 69 -
72, Add alternative text to both AvatarImage instances in the empowerment
section: use alt="" because the adjacent doctor names already identify the
portraits, keeping the avatars decorative.
| Week 2: AI Productivity and Prompting | ||
| </h3> | ||
| <p className="text-[6px] text-primary">0/9 | 1 hr 30mins</p>{" "} | ||
| <div className="absolute top-[14%] -right-4 flex h-14 w-[174px] justify-between rounded-sm bg-white p-2.5"> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Replace the arbitrary overlay offset with a design token.
top-[14%] introduces an arbitrary spacing value in the changed layout. Use an existing spacing token or a named layout utility.
As per coding guidelines, do not use arbitrary hex colors or spacing; use the repository's design tokens.
🤖 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/empowerment-section.tsx` at line 153,
Update the overlay div in the empowerment section to replace the arbitrary
top-[14%] offset with an existing spacing design token or named layout utility.
Preserve the current positioning and styling while avoiding arbitrary spacing
values.
Source: Coding guidelines
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 9
🤖 Prompt for all review comments with 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.
Inline comments:
In `@src/app/`(user)/dashboard/page.tsx:
- Around line 76-80: Update the loading skeleton container in the dashboard card
map to use the same sm breakpoint maximum width as CourseCard.Root, changing the
current 300px constraint to the shared 400px width so the loading and loaded
layouts remain aligned.
In `@src/features/marketing/components/course-detail-content-section.tsx`:
- Around line 25-42: Extract the complete CourseContentData type from
course-detail-content-section.tsx into a shared module, then import and reuse it
in both the section component and CourseInformationCard. Ensure the shared
definition includes the full modules/topics and reviews shapes so the two
components cannot drift.
In `@src/features/marketing/components/donation-form.tsx`:
- Around line 100-102: Update the donation copy in the paragraph rendered by the
donation form to replace the period after “hope” with a comma, preserving the
rest of the sentence.
- Line 46: Update the donation form schema around confirmation to require a true
value, include confirmation in the onSubmit request body, and add matching
validation in the POST handler for /api/donations so missing or false
confirmation is rejected before creating a pending donation.
In `@src/features/marketing/components/empowerment-section.tsx`:
- Line 28: Add w-full to the three text wrapper elements in the empowerment
section, including the corresponding wrappers near the referenced locations, so
headings and descriptions span the card width and wrap correctly while
preserving the existing centered layout.
- Around line 69-72: Add alternative text to both AvatarImage instances in the
empowerment section: use alt="" because the adjacent doctor names already
identify the portraits, keeping the avatars decorative.
- Line 153: Update the overlay div in the empowerment section to replace the
arbitrary top-[14%] offset with an existing spacing design token or named layout
utility. Preserve the current positioning and styling while avoiding arbitrary
spacing values.
In `@src/features/marketing/lib/donation-pricing.ts`:
- Around line 3-9: Update computeAdminFee to convert the amount to integer cents
and calculate the fee using integer basis-point arithmetic before converting
back to dollars, ensuring half-cent values round correctly. Keep
computeDonationTotal using the corrected fee result and preserve its existing
cent-based total rounding.
In `@src/shared/lib/api-handler.ts`:
- Line 42: Replace the raw console.error(error) call in the API handler with the
project’s trusted redacting production logger, ensuring caught errors are logged
without exposing sensitive API, payment, email, enrollment, session, or Stripe
transaction fields.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 16a6029e-7bd9-446b-b5cb-0499ae736563
⛔ Files ignored due to path filters (3)
public/figma-home/A-Rivera.pngis excluded by!**/*.pngpublic/figma-home/M-Anderson.pngis excluded by!**/*.pngpublic/figma-home/girl-with-phone.pngis excluded by!**/*.png
📒 Files selected for processing (37)
src/app/(marketing)/donation/success/page.tsxsrc/app/(user)/dashboard/page.tsxsrc/app/api/donations/route.tssrc/app/globals.csssrc/features/courses/components/course-card.tsxsrc/features/courses/components/enroll-now-button.tsxsrc/features/marketing/components/about-hero-section.tsxsrc/features/marketing/components/about-our-values-section.tsxsrc/features/marketing/components/about-support-mission-section.tsxsrc/features/marketing/components/community-section.tsxsrc/features/marketing/components/contact-hero-section.tsxsrc/features/marketing/components/course-detail-content-section.tsxsrc/features/marketing/components/course-detail-hero-section.tsxsrc/features/marketing/components/course-information-card.tsxsrc/features/marketing/components/courses-hero-section.tsxsrc/features/marketing/components/cta-section.tsxsrc/features/marketing/components/donation-cta-section.tsxsrc/features/marketing/components/donation-form.tsxsrc/features/marketing/components/donation-hero-section.tsxsrc/features/marketing/components/donation-support-section.tsxsrc/features/marketing/components/empowerment-section.tsxsrc/features/marketing/components/faq.tsxsrc/features/marketing/components/footer.tsxsrc/features/marketing/components/how-can-we-help.tsxsrc/features/marketing/components/how-can-we-support.tsxsrc/features/marketing/components/invest-in-hope-section.tsxsrc/features/marketing/components/mission-sections.tsxsrc/features/marketing/components/our-vision-section.tsxsrc/features/marketing/components/practical-pathways-section.tsxsrc/features/marketing/components/stories-from-our-community-section.tsxsrc/features/marketing/components/testimonials.tsxsrc/features/marketing/lib/donation-pricing.tssrc/features/user-dashboard/components/course-player-navbar.tsxsrc/features/user-dashboard/components/dashboard-navbar.tsxsrc/shared/lib/api-handler.tssrc/shared/ui/marketing-button.tsxsrc/shared/ui/marketing-container.tsx
🛑 Comments failed to post (6)
src/app/(user)/dashboard/page.tsx (1)
76-80: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== locate files ==" fd -a 'page\.tsx$|course-card\.tsx$' . | sed 's#^\./##' | head -100 echo "== referenced dashboard file excerpt if present ==" if [ -f 'src/app/(user)/dashboard/page.tsx' ]; then nl -ba 'src/app/(user)/dashboard/page.tsx' | sed -n '60,95p' fi echo "== course card relevant excerpt if present ==" if [ -f 'src/features/courses/components/course-card.tsx' ]; then ast-grep outline 'src/features/courses/components/course-card.tsx' --view compact || true nl -ba 'src/features/courses/components/course-card.tsx' | sed -n '1,180p' fiRepository: Smartlify07/Modern-Advocates
Length of output: 2790
🏁 Script executed:
#!/bin/bash set -euo pipefail # Use awk because nl is unavailable in this sandbox. awk='awk' dashboard='src/app/(user)/dashboard/page.tsx' coursecard='src/features/courses/components/course-card.tsx' echo "== dashboard excerpt ==" if [ -f "$dashboard" ]; then $awk 'NR>=60 && NR<=95 { printf "%6d: %s\n", NR, $0 }' "$dashboard" else echo "missing $dashboard" fi echo "== course-card excerpt ==" if [ -f "$coursecard" ]; then $awk 'NR>=1 && NR<=220 { printf "%6d: %s\n", NR, $0 }' "$coursecard" else echo "missing $coursecard" fi echo "== max-width occurrences in relevant snippets ==" $awk '$0 ~ /max-w\[/ { printf "%s:%d: %s\n", FILENAME, NR, $0 }' "$dashboard" "$coursecard" 2>/dev/nullRepository: Smartlify07/Modern-Advocates
Length of output: 8021
Match the loading card width to the loaded card width.
The loading skeleton uses
sm:max-w-[300px], whileCourseCard.Rootrenders withsm:max-w-[400px]. If the grid grows wider than 300px, cards expand after the loading state, shifting the layout. Use the shared400pxmaximum, or mark the 300px loading size as intentional.🤖 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/app/`(user)/dashboard/page.tsx around lines 76 - 80, Update the loading skeleton container in the dashboard card map to use the same sm breakpoint maximum width as CourseCard.Root, changing the current 300px constraint to the shared 400px width so the loading and loaded layouts remain aligned.src/features/marketing/components/course-detail-content-section.tsx (1)
25-42: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== locate candidate files ==" git ls-files | rg '(^|/)course-(detail-content-section|information-card)\.tsx$|(\.d\.ts$|course.*\.ts$)' || true echo echo "== course-detail-content-section outline and relevant lines ==" if [ -f src/features/marketing/components/course-detail-content-section.tsx ]; then wc -l src/features/marketing/components/course-detail-content-section.tsx sed -n '1,120p' src/features/marketing/components/course-detail-content-section.tsx | cat -n fi echo echo "== course-information-card relevant definitions ==" if [ -f src/features/marketing/components/course-information-card.tsx ]; then rg -n "CourseContentData|export type|export interface|interface .*Course" src/features/marketing/components/course-information-card.tsx -C 4 fi echo echo "== CourseContentData references ==" rg -n "CourseContentData|CourseInformationData|CourseData|interface .*Course|type .*Course" src user-service shared features -S || true echo echo "== package lint/build references ==" git ls-files | rg 'package\.json$' || true for f in $(git ls-files package*.json); do echo "--- $f"; sed -n '1,220p' "$f"; doneRepository: Smartlify07/Modern-Advocates
Length of output: 15706
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== file names ==" git ls-files | rg 'src/features/marketing/components/(course-detail-content-section|course-information-card)\.tsx$' || true echo echo "== course-detail-content-section imports and CourseContentData section ==" sed -n '1,80p' src/features/marketing/components/course-detail-content-section.tsx | cat -n echo echo "== course-information-card imports and CourseContentData/I interface section ==" sed -n '1,90p' src/features/marketing/components/course-information-card.tsx | cat -n echo echo "== exact CourseContentData references ==" rg -n "\bCourseContentData\b|interface CourseInformation|type CourseInformation|interface Course|type Course" src/features/marketing/components src -S || true echo echo "== deterministic AST-ish type-shape comparison from source (read-only text extraction only) ==" python3 - <<'PY' from pathlib import Path import re files = [ Path("src/features/marketing/components/course-detail-content-section.tsx"), Path("src/features/marketing/components/course-information-card.tsx"), ] for path in files: text = path.read_text() start = text.find("export type CourseContentData") if start == -1: start = text.find("export interface CourseContentData") if start == -1: end = path.name + " has no CourseContentData" else: snippet = text[start:] brace = snippet.find("{") depth = 0 end = 0 for i, ch in enumerate(snippet): if ch == "{": depth += 1 elif ch == "}": depth -= 1 if depth == 0: end = i + 1 break print(f"\n## {path}") print("\n".join(f"{idx+1}: {line}" for idx,line in enumerate(snippet[:end].splitlines()))) PYRepository: Smartlify07/Modern-Advocates
Length of output: 9164
Use one
CourseContentDatadefinition.
src/features/marketing/components/course-detail-content-section.tsxdefines the full course data shape and forwards it toCourseInformationCard, whose localCourseContentDataonly declares a smaller subset. The nestedmodules.topicstype is not identical across the two files, so this can drift.Extract
CourseContentDatato one shared module and use it consistently.🤖 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/course-detail-content-section.tsx` around lines 25 - 42, Extract the complete CourseContentData type from course-detail-content-section.tsx into a shared module, then import and reuse it in both the section component and CourseInformationCard. Ensure the shared definition includes the full modules/topics and reviews shapes so the two components cannot drift.Source: Coding guidelines
src/features/marketing/components/donation-form.tsx (2)
46-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== locate donation form and related files ==" fd -a 'donation-form\.tsx$|donation|route\.ts$|route\.tsx$' . | sed 's#^\./##' | head -200 echo echo "== donation-form.tsx ==" file="$(fd 'donation-form\.tsx$' . | head -1)" if [ -n "${file:-}" ]; then wc -l "$file" cat -n "$file" fi echo echo "== search donation API endpoints/usages ==" rg -n "donation|confirmation|donorName|donorEmail|donationType" -S . \ -g '!node_modules' -g '!dist' -g '!build' -g '!next' \ -g '!*.lock' | head -300Repository: Smartlify07/Modern-Advocates
Length of output: 50384
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== public donation route ==" cat -n src/app/api/donations/route.ts echo echo "== donation schema ==" cat -n src/infrastructure/database/schema/donation.ts echo echo "== package scripts ==" python3 - <<'PY' import json with open("package.json") as f: data=json.load(f) print(json.dumps(data.get("scripts", {}), indent=2)) PY echo echo "== Zod boolean literal behavior probe ==" if [ -f package.json ]; then node - <<'JS' const fs = require('fs'); const p = JSON.parse(fs.readFileSync('package.json','utf8')); console.log({ zodVersion: p.dependencies?.zod || p.devDependencies?.zod, hasZodInstalled: undefined }); JS fi echo echo "== deterministic schema validation simulation ==" python3 - <<'PY' # Simulate the two Zod validators relevant to the review claim: # z.boolean() accepts both false and true. # z.literal(true) accepts only true and fails missing/false. samples = [False, True, None, {"confirmation": False}] print({ "z.boolean": [s for s in [False, True] if True], "z.literal(true) missing false": ("missing key would not be present", False) }) print("z.boolean accepts confirmation=false:", False in [False, True]) PYRepository: Smartlify07/Modern-Advocates
Length of output: 6708
Require and transmit payment confirmation.
confirmation: z.boolean()allowsfalse, andonSubmitdoes not sendconfirmationto/api/donations.POST /api/donationsalso does not validateconfirmation, so the route creates a pending donation without enforcing the acknowledgement.Require
confirmation === truein the form schema, include it in the request body, and reject missing/false confirmation insrc/app/api/donations/route.ts.🤖 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-form.tsx` at line 46, Update the donation form schema around confirmation to require a true value, include confirmation in the onSubmit request body, and add matching validation in the POST handler for /api/donations so missing or false confirmation is rejected before creating a pending donation.
100-102: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Correct the donation copy.
Line 101 uses a period after “hope” where the sentence needs a comma.
- Help us bring hope. support, and real impact in communities + Help us bring hope, support, and real impact in communities📝 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.<p className="text-base"> Help us bring hope, support, and real impact in communities </p>🤖 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-form.tsx` around lines 100 - 102, Update the donation copy in the paragraph rendered by the donation form to replace the period after “hope” with a comma, preserving the rest of the sentence.src/features/marketing/lib/donation-pricing.ts (1)
3-9: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail node - <<'NODE' const actual = Math.round(9.5 * 0.03 * 100) / 100 if (actual !== 0.29) { console.error({ actual, expected: 0.29 }) process.exit(1) } NODERepository: Smartlify07/Modern-Advocates
Length of output: 199
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "== locate file ==" git ls-files | grep -F 'src/features/marketing/lib/donation-pricing.ts' || true echo "== file excerpt ==" if [ -f src/features/marketing/lib/donation-pricing.ts ]; then cat -n src/features/marketing/lib/donation-pricing.ts fi echo "== usages ==" rg -n "computeAdminFee|computeDonationTotal|donation-pricing" src || true echo "== relevant JS evidence ==" node - <<'NODE' const ADMIN_FEE_RATE = 0.03 function computeAdminFee(amount) { return Math.round(amount * ADMIN_FEE_RATE * 100) / 100 } function computeDonationTotal(amount) { return Math.round((amount + computeAdminFee(amount)) * 100) / 100 } for (const amount of [9.5, 16.5, 33.49, 100.00, 0.01]) { console.log(JSON.stringify({ amount, fee: computeAdminFee(amount), total: computeDonationTotal(amount) })) } const inputs = [9.5, 9.52, 9.53, 16.5, 33.49] const failures = [] for (const amount of inputs) { const fee = computeAdminFee(amount) const cents = fee * 100 const roundToEvenExpected = Math.round(Math.floor(cents + 0.5)) / 100 if (fee !== roundToEvenExpected) failures.push(JSON.stringify({ amount, fee, expected: roundToEvenExpected })) } console.log("failures=", failures.length) for (const f of failures) console.log(f) NODERepository: Smartlify07/Modern-Advocates
Length of output: 1958
Calculate fee rounding in integer cents.
JavaScript evaluates
9.50 * 0.03 * 100as28.499999999999996, so this code returns$0.28instead of$0.29. The affected donation total is shown in the form, sent to Stripe, and reused on the success page. Convert the input to cents and compute the fee with integer basis points so the half-cent decision depends on exact cent arithmetic.🤖 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/lib/donation-pricing.ts` around lines 3 - 9, Update computeAdminFee to convert the amount to integer cents and calculate the fee using integer basis-point arithmetic before converting back to dollars, ensuring half-cent values round correctly. Keep computeDonationTotal using the corrected fee result and preserve its existing cent-based total rounding.src/shared/lib/api-handler.ts (1)
42-42: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail rg -n -C 4 'console\.error|logger\.(error|warn)|redact|sanitize|request.?id|correlation' srcRepository: Smartlify07/Modern-Advocates
Length of output: 16794
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '--- api-handler.ts ---\n' cat -n src/shared/lib/api-handler.ts printf '\n--- API route usages of apiFetch/apiHandler ---\n' rg -n "apiFetch|apiHandler|NextResponse\.error|throw .*Error" src/app src/features | head -n 200 printf '\n--- error class definitions and message sources ---\n' rg -n "class .*Error|extends .*Error|new \\w+Error\\(|message:" src/shared src/app src/features src/infrastructure | head -n 250 printf '\n--- node dependency versions for logging libraries ---\n' node - <<'JS' const fs = require('fs') const pkg = JSON.parse(fs.readFileSync('package.json','utf8')) console.log(pkg.dependencies && JSON.stringify(pkg.dependencies, null, 2)) console.log(pkg.devDependencies && JSON.stringify(pkg.devDependencies, null, 2)) JSRepository: Smartlify07/Modern-Advocates
Length of output: 257
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '::group::api-handler-context\n' sed -n '1,90p' src/shared/lib/api-handler.ts | cat -n printf '::endgroup::\n' printf '::group::all-raw-console-error-calls\n' python3 - <<'PY' import pathlib, re for p in pathlib.Path('src').rglob('*'): if p.is_file() and any(p.suffix in {'.ts','.tsx'}): text=p.read_text(errors='ignore') for i,line in enumerate(text.splitlines(),1): if re.search(r'\bconsole\.error\s*\(', line): print(f'{p}:{i}:{line.strip()}') PY printf '::endgroup::\n' printf '::group::security-sensitive-data-sources\n' rg -n "password|secret|api[_-]?key|auth|stripe|donat|enroll|invoice|metadata|pii|email|stripeSecret|billing|card|token|session" src/app src/features src/infrastructure src/shared | head -n 300 printf '::endgroup::\n' printf '::group::logging-library-config\n' node - <<'JS' const fs = require('fs') const pkg = JSON.parse(fs.readFileSync('package.json','utf8')) console.log('dependencies:', pkg.dependencies) console.log('devDependencies:', pkg.devDependencies) if (fs.existsSync('src/shared/lib/logger.ts')) console.log(fs.readFileSync('src/shared/lib/logger.ts','utf8').slice(0,3000)) else console.log('src/shared/lib/logger.ts absent') if (fs.existsSync('src/shared/lib/sentry.ts')) console.log(fs.readFileSync('src/shared/lib/sentry.ts','utf8').slice(0,3000)) else console.log('src/shared/lib/sentry.ts absent') JS printf '::endgroup::\n'Repository: Smartlify07/Modern-Advocates
Length of output: 2213
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "--- api-handler.ts ---" cat -n src/shared/lib/api-handler.ts echo echo "--- all console.error calls in TypeScript under src ---" python3 - <<'PY' import pathlib, re for p in pathlib.Path('src').rglob('*'): if p.is_file() and p.suffix in {'.ts', '.tsx'}: text = p.read_text(errors='ignore') for i, line in enumerate(text.splitlines(), 1): if re.search(r'\bconsole\.error\s*\(', line): print(f'{p}:{i}:{line.strip()}') PY echo echo "--- potential sensitive/data-service error sources ---" rg -n "throw new .*Error|Error\\(|message|password|secretKey|secret |api-secret|client secret|stripe|donation|enrollment|session|email|token|metadata|pii|billing|card|cardNumber|cardExpiry" src/app src/features src/infrastructure | head -n 400 echo echo "--- logging-related config files ---" for f in package.json src/shared/lib/logger.ts src/shared/lib/sentry.ts next.config.* .env* .env.example .env.local; do if [ -e "$f" ]; then echo "### $f" sed -n '1,180p' "$f" fi done echo echo "--- api-handler callers ---" rg -n "apiHandler\\(|apiFetch\\(" src/app src/features | head -n 200Repository: Smartlify07/Modern-Advocates
Length of output: 50384
Do not log raw caught errors.
console.error(error)at line 42 writes the completeErrorobject and also sends it to Sentry. API and payment paths process email, donation, enrollment, session, and Stripe transaction data, so error details should use a redacting logger or a trusted production logger with sensitive-field handling.🤖 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/shared/lib/api-handler.ts` at line 42, Replace the raw console.error(error) call in the API handler with the project’s trusted redacting production logger, ensuring caught errors are logged without exposing sensitive API, payment, email, enrollment, session, or Stripe transaction fields.
Summary
Verification
px tsc --noEmit\ clean
Summary by CodeRabbit
New Features
UI Improvements
Bug Fixes