Skip to content

Commit 800b282

Browse files
jaydencarvajal511jaydencarvajalthaninbew
authored
35 migrate dono step1 3 (#68)
* step1 component migrated * finished step3 component * forgot to add the font to step 1 * fixing build * fix: Source sans pro for steps 1 and 3, boldness * fix: USD suffix in input * fix: button to match figma * fix: button and other minor adjustments to match figma --------- Co-authored-by: Jayden Carvajal <carvajal.ja@northeastern.edu> Co-authored-by: thaninbew <kongkiatsophon.t@northeastern.edu>
1 parent 79aeb70 commit 800b282

13 files changed

Lines changed: 1498 additions & 434 deletions

File tree

apps/frontend/src/components/ui/button.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const buttonVariants = cva(
1717
destructive:
1818
'bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30',
1919
link: 'text-primary underline-offset-4 hover:underline',
20+
unstyled: '',
2021
},
2122
size: {
2223
default:
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@lib/utils';
4+
5+
function Card({
6+
className,
7+
size = 'default',
8+
...props
9+
}: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) {
10+
return (
11+
<div
12+
data-slot="card"
13+
data-size={size}
14+
className={cn(
15+
'ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col',
16+
className,
17+
)}
18+
{...props}
19+
/>
20+
);
21+
}
22+
23+
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
24+
return (
25+
<div
26+
data-slot="card-header"
27+
className={cn(
28+
'gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]',
29+
className,
30+
)}
31+
{...props}
32+
/>
33+
);
34+
}
35+
36+
function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
37+
return (
38+
<div
39+
data-slot="card-title"
40+
className={cn(
41+
'text-base leading-snug font-medium group-data-[size=sm]/card:text-sm',
42+
className,
43+
)}
44+
{...props}
45+
/>
46+
);
47+
}
48+
49+
function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
50+
return (
51+
<div
52+
data-slot="card-description"
53+
className={cn('text-muted-foreground text-sm', className)}
54+
{...props}
55+
/>
56+
);
57+
}
58+
59+
function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
60+
return (
61+
<div
62+
data-slot="card-action"
63+
className={cn(
64+
'col-start-2 row-span-2 row-start-1 self-start justify-self-end',
65+
className,
66+
)}
67+
{...props}
68+
/>
69+
);
70+
}
71+
72+
function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
73+
return (
74+
<div
75+
data-slot="card-content"
76+
className={cn('px-4 group-data-[size=sm]/card:px-3', className)}
77+
{...props}
78+
/>
79+
);
80+
}
81+
82+
function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
83+
return (
84+
<div
85+
data-slot="card-footer"
86+
className={cn(
87+
'bg-muted/50 rounded-b-xl border-t p-4 group-data-[size=sm]/card:p-3 flex items-center',
88+
className,
89+
)}
90+
{...props}
91+
/>
92+
);
93+
}
94+
95+
export {
96+
Card,
97+
CardHeader,
98+
CardFooter,
99+
CardTitle,
100+
CardAction,
101+
CardDescription,
102+
CardContent,
103+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use client';
2+
3+
import * as React from 'react';
4+
import { Checkbox as CheckboxPrimitive } from 'radix-ui';
5+
6+
import { cn } from '@lib/utils';
7+
import { CheckIcon } from 'lucide-react';
8+
9+
function Checkbox({
10+
className,
11+
...props
12+
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
13+
return (
14+
<CheckboxPrimitive.Root
15+
data-slot="checkbox"
16+
className={cn(
17+
'border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-[4px] border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-[3px] aria-invalid:ring-[3px] peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50',
18+
className,
19+
)}
20+
{...props}
21+
>
22+
<CheckboxPrimitive.Indicator
23+
data-slot="checkbox-indicator"
24+
className="[&>svg]:size-3.5 grid place-content-center text-current transition-none"
25+
>
26+
<CheckIcon />
27+
</CheckboxPrimitive.Indicator>
28+
</CheckboxPrimitive.Root>
29+
);
30+
}
31+
32+
export { Checkbox };
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
3+
import { cn } from '@lib/utils';
4+
5+
function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
6+
return (
7+
<input
8+
type={type}
9+
data-slot="input"
10+
className={cn(
11+
'dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
12+
className,
13+
)}
14+
{...props}
15+
/>
16+
);
17+
}
18+
19+
export { Input };
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use client';
2+
import * as React from 'react';
3+
import { Label as LabelPrimitive } from 'radix-ui';
4+
import { cn } from '@lib/utils';
5+
function Label({
6+
className,
7+
...props
8+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
9+
return (
10+
<LabelPrimitive.Root
11+
data-slot="label"
12+
className={cn(
13+
'gap-2 text-sm leading-none font-medium group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed',
14+
className,
15+
)}
16+
{...props}
17+
/>
18+
);
19+
}
20+
export { Label };
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as React from 'react';
2+
import { cn } from '@lib/utils';
3+
function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {
4+
return (
5+
<textarea
6+
data-slot="textarea"
7+
className={cn(
8+
'border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 rounded-lg border bg-transparent px-2.5 py-2 text-base transition-colors focus-visible:ring-[3px] aria-invalid:ring-[3px] md:text-sm placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full outline-none disabled:cursor-not-allowed disabled:opacity-50',
9+
className,
10+
)}
11+
{...props}
12+
/>
13+
);
14+
}
15+
export { Textarea };

apps/frontend/src/containers/donations/DonationForm.tsx

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Step1Amount } from './steps/Step1Amount';
1414
import { Step2Details } from './steps/Step2Details';
1515
import { Step3Confirm } from './steps/Step3Confirm';
1616
import { Step4Receipt } from './steps/Step4Receipt';
17+
import { Button } from '@components/ui/button';
1718

1819
export const DonationForm: React.FC<DonationFormProps> = ({
1920
onSuccess,
@@ -272,25 +273,27 @@ export const DonationForm: React.FC<DonationFormProps> = ({
272273
return (
273274
<div className="donation-form-container">
274275
<form
275-
className="donation-form"
276+
className="donation-form flex flex-col p-[5%] box-border min-h-fit"
276277
onSubmit={(e) => e.preventDefault()}
277278
noValidate
278279
>
279-
<div className="progress-bar-container">
280+
<div
281+
className={`flex w-full flex-row justify-center items-center gap-[3%] mb-[8%] ${currentStep === 1 || currentStep === 3 ? 'font-sans' : ''}`}
282+
>
280283
<div
281-
className={
282-
currentStep === 1 ? 'progress-bar-purple' : 'progress-bar-grey'
283-
}
284+
className={`w-[31%] aspect-[14/1] rounded-[10px] ${
285+
currentStep === 1 ? 'bg-[#650d77]' : 'bg-[#b3b3b3]'
286+
}`}
284287
></div>
285288
<div
286-
className={
287-
currentStep === 2 ? 'progress-bar-purple' : 'progress-bar-grey'
288-
}
289+
className={`w-[31%] aspect-[14/1] rounded-[10px] ${
290+
currentStep === 2 ? 'bg-[#650d77]' : 'bg-[#b3b3b3]'
291+
}`}
289292
></div>
290293
<div
291-
className={
292-
currentStep === 3 ? 'progress-bar-purple' : 'progress-bar-grey'
293-
}
294+
className={`w-[31%] aspect-[14/1] rounded-[10px] ${
295+
currentStep === 3 ? 'bg-[#650d77]' : 'bg-[#b3b3b3]'
296+
}`}
294297
></div>
295298
</div>
296299
{submitError && (
@@ -301,42 +304,52 @@ export const DonationForm: React.FC<DonationFormProps> = ({
301304

302305
{renderStep()}
303306

304-
<div className="step-actions">
307+
<div
308+
className={`flex flex-row items-center justify-center w-full gap-[7%] pt-6 mt-auto ${currentStep === 1 || currentStep === 3 ? 'font-sans' : ''}`}
309+
>
305310
{showBackButton && (
306-
<button
311+
<Button
312+
variant="unstyled"
307313
type="button"
308-
className="action-button"
314+
className="flex-1 rounded-[2cqh] border-[3px] border-[#007b64] bg-white text-[#007b64] font-semibold h-[2.5rem] flex justify-center items-center text-center text-[2.5cqh] hover:bg-[#f0fffb]"
309315
onClick={handleBack}
310316
>
311-
BACK
312-
</button>
317+
Back
318+
</Button>
313319
)}
314320

315321
{showNextButton && (
316-
<button
322+
<Button
323+
variant="unstyled"
317324
type="button"
318-
className="action-button"
325+
className="flex-1 rounded-[2cqh] bg-[#007b64] text-white font-semibold h-[2.5rem] flex justify-center items-center text-center text-[2.5cqh] hover:bg-[#006b54]"
319326
onClick={handleNext}
320327
>
321-
NEXT
322-
</button>
328+
Next
329+
</Button>
323330
)}
324331

325332
{currentStep === 3 && (
326-
<button
333+
<Button
334+
variant="unstyled"
327335
type="button"
328-
className="submit-button"
336+
className="flex-1 rounded-[4px] bg-[#007b64] hover:bg-[#006b54] text-white h-[2.5rem] px-3 text-base font-semibold disabled:bg-[#aaa]"
329337
onClick={handleSubmit}
330338
disabled={isSubmitting}
331339
>
332-
{isSubmitting ? 'Processing...' : 'Confirm Donation'}
333-
</button>
340+
{isSubmitting ? 'Processing...' : 'Donate'}
341+
</Button>
334342
)}
335343

336344
{currentStep === 4 && (
337-
<button type="button" className="primary" onClick={resetForm}>
345+
<Button
346+
variant="default"
347+
type="button"
348+
className="primary font-semibold"
349+
onClick={resetForm}
350+
>
338351
Make another donation
339-
</button>
352+
</Button>
340353
)}
341354
</div>
342355
</form>

0 commit comments

Comments
 (0)