From 03e6430641fb1e85598f7380f7d29b2793ea7dcb Mon Sep 17 00:00:00 2001 From: Gauri Rajesh Date: Fri, 28 Nov 2025 21:32:58 -0500 Subject: [PATCH 1/2] growing goal component new branch --- .../GrowingGoal/GrowingGoal.module.css | 158 +++++++++++++ .../components/GrowingGoal/GrowingGoal.tsx | 145 ++++++++++++ .../src/components/GrowingGoal/Plant.tsx | 223 ++++++++++++++++++ 3 files changed, 526 insertions(+) create mode 100644 apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css create mode 100644 apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx create mode 100644 apps/frontend/src/components/GrowingGoal/Plant.tsx diff --git a/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css b/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css new file mode 100644 index 0000000..f7598b3 --- /dev/null +++ b/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css @@ -0,0 +1,158 @@ +.goal-container { + aspect-ratio: 7 / 10; + overflow: hidden; + display: flex; + flex-direction: column; + border-radius: 3%; + border: 2% solid #cecece; + background: #f2f2f2; + text-align: center; + justify-content: start; + container-type: inline-size; + gap: 4%; +} + +.description-label { + border-top-left-radius: 5%; + border-top-right-radius: 5%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + flex-shrink: 0; + color: #fff; + font-family: Helvetica; + font-weight: 700; + white-space: nowrap; + height: 12%; + padding: 2%; + background-color: #127a64; + font-size: 5cqw; +} + +.growth-container { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + position: relative; +} + +.growth-container-solid-grey { + position: relative; + width: 73%; + aspect-ratio: 1 / 1; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + background: #cecece; +} + +.total-donation-label { + color: #000; + text-align: center; + font-family: Helvetica; + font-size: 5cqw; + font-weight: 400; +} + +.sample-donor-container { + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; +} + +.sample-donor-label { + width: 65%; + aspect-ratio: 9 / 2; + overflow: hidden; + border-radius: 4px; + padding: 2%; + background: #127a64; + display: flex; + align-items: center; + justify-content: center; +} + +.sample-donor-amount { + color: #fff; + font-family: Helvetica; + font-size: 4cqw; + overflow: hidden; +} + +.growth-container-solid-white { + z-index: 10; + display: flex; + justify-content: center; + align-items: center; + width: 90%; + aspect-ratio: 1 / 1; + border-radius: 50%; + background: #ffffff; +} + +.growth-container-solid-grey-inner { + z-index: 11; + display: flex; + justify-content: center; + align-items: center; + width: 90%; + aspect-ratio: 1 / 1; + border-radius: 50%; + background: #55565a; +} + +.growth-container-solid-teal { + position: relative; + aspect-ratio: 1 / 1; + width: 90%; + border-radius: 50%; + background: #0c7962; +} + +.growth-container-gradient { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + border-radius: 50%; + background: conic-gradient( + from 180deg at 50% 50%, + #c6be3b 0deg, + #863b27 90deg, + #650d77 180deg, + #0c7962 270deg, + #c6be3b 360deg, + transparent 180deg 360deg + ); +} + +.soil-base { + background-color: #211504; + width: 100%; + aspect-ratio: 1 / 1; + border-radius: 50%; +} + +.soil-top { + position: absolute; + background-color: #332308; + width: 90%; + left: 5%; + height: 18%; + border-radius: 50%; + bottom: 20%; +} + +.progress-bar-handle { + position: absolute; + width: 5%; + aspect-ratio: 1 / 1; + border-radius: 50%; + background-color: #ffffff; +} diff --git a/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx b/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx new file mode 100644 index 0000000..608c59e --- /dev/null +++ b/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx @@ -0,0 +1,145 @@ +import { useEffect, useRef, useState } from 'react'; +import styles from './GrowingGoal.module.css'; +import Plant from './Plant'; + +export type SampleDonation = { + name: string; + amount: number; +}; + +export type GrowingGoalProps = { + message: string; + total: number; + goal: number; + sampleDonation?: SampleDonation; +}; + +export const GrowingGoal = (props: GrowingGoalProps) => { + const { message, total, goal } = props; + const growthContainerRef = useRef(null); + const [radius, setRadius] = useState(0); + const [endHandle, setEndHandle] = useState({ + top: 0, + left: 0, + }); + const progress = Math.floor((total / goal) * 360); + + // calculate gradient color of growth container handles + const getGradientColor = (degree: number): string => { + const gradientAngle = (degree + 180) % 360; + + const stops = [ + { angle: 0, color: { r: 198, g: 190, b: 59 } }, + { angle: 90, color: { r: 134, g: 59, b: 39 } }, + { angle: 180, color: { r: 101, g: 13, b: 119 } }, + { angle: 270, color: { r: 12, g: 121, b: 98 } }, + { angle: 360, color: { r: 198, g: 190, b: 59 } }, + ]; + + let startStop = stops[stops.length - 1]; + let endStop = stops[0]; + + for (let i = 0; i < stops.length - 1; i++) { + if ( + gradientAngle >= stops[i].angle && + gradientAngle <= stops[i + 1].angle + ) { + startStop = stops[i]; + endStop = stops[i + 1]; + break; + } + } + const range = endStop.angle - startStop.angle; + const factor = (gradientAngle - startStop.angle) / range; + const r = Math.round( + startStop.color.r + (endStop.color.r - startStop.color.r) * factor, + ); + const g = Math.round( + startStop.color.g + (endStop.color.g - startStop.color.g) * factor, + ); + const b = Math.round( + startStop.color.b + (endStop.color.b - startStop.color.b) * factor, + ); + + return `rgb(${r}, ${g}, ${b})`; + }; + + // calculate growth container end handle position + useEffect(() => { + if (growthContainerRef.current) { + setRadius(growthContainerRef.current.offsetWidth / 2); + const handleSize = radius * 0.05; + const progressRadians = ((90 - progress) * Math.PI) / 180; + const topOffset = (radius - handleSize) * Math.sin(progressRadians); + const leftOffset = (radius - handleSize) * Math.cos(progressRadians); + + const top = radius - topOffset - handleSize; + const left = radius + leftOffset - handleSize; + + setEndHandle({ + top: top, + left: left, + }); + } + }, [growthContainerRef, progress, radius]); + + const startHandleStyle: React.CSSProperties = { + top: '0%', + left: `47.5%`, + }; + + const endHandleStyle: React.CSSProperties = { + top: `${endHandle.top}px`, + left: `${endHandle.left}px`, + }; + + return ( +
+
{message}
+
+
+
+ +
+
+
+
+
+ ${total.toFixed(0)} raised of{' '} + ${goal.toFixed(0)} +
+
+ {props.sampleDonation && ( +
+
+ + {props.sampleDonation.name.length > 10 + ? props.sampleDonation.name.slice(0, 10) + '...' + : props.sampleDonation.name} + + {' donated $'} + {props.sampleDonation.amount.toFixed(2)}! +
+
+ )} +
+
+ ); +}; \ No newline at end of file diff --git a/apps/frontend/src/components/GrowingGoal/Plant.tsx b/apps/frontend/src/components/GrowingGoal/Plant.tsx new file mode 100644 index 0000000..29ee89b --- /dev/null +++ b/apps/frontend/src/components/GrowingGoal/Plant.tsx @@ -0,0 +1,223 @@ +import styles from './GrowingGoal.module.css'; +import React from 'react'; + +const Plant: React.FC = () => { + return ( +
+
+
+
+
+
+
+ + +
+
+
+ ); +}; + +const Shine: React.FC = () => { + return ( +
+ + + + + + + + + + + +
+ ); +}; + +const Sprout: React.FC = () => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +}; + +export default Plant; \ No newline at end of file From 239b5ebe347c73252b867fd67b3e864f2c00def8 Mon Sep 17 00:00:00 2001 From: Gauri Rajesh Date: Tue, 2 Dec 2025 16:39:29 -0500 Subject: [PATCH 2/2] fix design to match hifi --- .../GrowingGoal/GrowingGoal.module.css | 28 ++++++++++++---- .../components/GrowingGoal/GrowingGoal.tsx | 22 ++++++++++--- apps/frontend/src/containers/root.tsx | 32 +++++++++++++------ 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css b/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css index f7598b3..78db2ab 100644 --- a/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css +++ b/apps/frontend/src/components/GrowingGoal/GrowingGoal.module.css @@ -26,7 +26,7 @@ white-space: nowrap; height: 12%; padding: 2%; - background-color: #127a64; + background-color: #3d3e6e; font-size: 5cqw; } @@ -40,7 +40,7 @@ .growth-container-solid-grey { position: relative; - width: 73%; + width: 70%; aspect-ratio: 1 / 1; border-radius: 50%; display: flex; @@ -53,27 +53,41 @@ color: #000; text-align: center; font-family: Helvetica; - font-size: 5cqw; + font-size: 6cqw; font-weight: 400; } .sample-donor-container { + width: 100%; + aspect-ratio: 5 / 1; overflow: hidden; display: flex; align-items: center; justify-content: center; + align-self: center; +} + +.sample-donor-profile { + display: flex; + width: 12%; + border-radius: 50%; + aspect-ratio: 1 / 1; + justify-content: center; + align-items: center; + background: #d9d9d9; } .sample-donor-label { - width: 65%; - aspect-ratio: 9 / 2; + width: 70%; overflow: hidden; border-radius: 4px; padding: 2%; - background: #127a64; + background: #3d3e6e; display: flex; align-items: center; - justify-content: center; + justify-content: start; + gap: 6%; + padding: 4%; } .sample-donor-amount { diff --git a/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx b/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx index 608c59e..b3156d4 100644 --- a/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx +++ b/apps/frontend/src/components/GrowingGoal/GrowingGoal.tsx @@ -5,6 +5,7 @@ import Plant from './Plant'; export type SampleDonation = { name: string; amount: number; + profile?: string; //base64 string }; export type GrowingGoalProps = { @@ -122,16 +123,27 @@ export const GrowingGoal = (props: GrowingGoalProps) => {
- ${total.toFixed(0)} raised of{' '} - ${goal.toFixed(0)} + ${total.toFixed(0)}{' '} + raised of ${goal.toFixed(0)}
{props.sampleDonation && (
+ {props.sampleDonation.profile ? ( +
+ ) : ( +
+ )}
- {props.sampleDonation.name.length > 10 - ? props.sampleDonation.name.slice(0, 10) + '...' + {props.sampleDonation.name.length > 8 + ? props.sampleDonation.name.slice(0,8) + '...' : props.sampleDonation.name} {' donated $'} @@ -142,4 +154,4 @@ export const GrowingGoal = (props: GrowingGoalProps) => {
); -}; \ No newline at end of file +}; diff --git a/apps/frontend/src/containers/root.tsx b/apps/frontend/src/containers/root.tsx index 1f62113..70845d3 100644 --- a/apps/frontend/src/containers/root.tsx +++ b/apps/frontend/src/containers/root.tsx @@ -1,18 +1,30 @@ import { DonationSummary } from '@containers/donations/DonationSummary'; import { DonationForm } from './donations/DonationForm'; +import { GrowingGoal } from '@components/GrowingGoal/GrowingGoal'; const Root: React.FC = () => { + const base64Profile = + 'data:image/jpeg;base64,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'; + return ( - <> - - +
+
+ +
+
+ +
+
); };