Skip to content

Commit 44fdf5a

Browse files
committed
Refactor components for improved usability and feature addition
Enhanced `UniversalAccess` and `OpenTrialPlatform` components with new headers and descriptive text to better convey purpose and functions. Refactored `WishingWellForm` by integrating custom input and textarea components for error handling, and improved the `ImageUpload` component for better image management functionality, including optional label handling and an additional `onRemove` function. Took 13 minutes
1 parent 0d1cf77 commit 44fdf5a

File tree

6 files changed

+113
-27
lines changed

6 files changed

+113
-27
lines changed

app/dfda/cure-acceleration-act/components/OpenTrialPlatform.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ export default function OpenTrialPlatform() {
7272
className="rounded-lg border-4 border-black bg-white p-6 shadow-[8px_8px_0px_0px_rgba(0,0,0,1)]"
7373
>
7474
<h2 className="mb-6 text-3xl font-black">
75-
Open Source Global Decentralized Trial Platform 🌐💻
75+
Decentralized FDA 🌐💻
7676
</h2>
77+
<p className="mb-6 text-xl">
78+
Global, Open, Decentralized, & Automated Clinical Trials
79+
</p>
7780
<div className="space-y-6">
7881
{sections.map((section, index) => (
7982
<ListCard

app/dfda/cure-acceleration-act/components/UniversalAccess.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,15 @@ export default function UniversalAccess() {
5858
transition={{ duration: 0.5 }}
5959
className="rounded-lg border-4 border-black bg-white p-6 shadow-[8px_8px_0px_0px_rgba(0,0,0,1)]"
6060
>
61-
<h2 className="mb-4 text-3xl font-black">Medical Freedom 🚪</h2>
61+
<h2 className="mb-4 text-3xl font-black">
62+
⚖️ Right to Trial ✊
63+
</h2>
64+
<p className="mb-6 text-xl">
65+
The right of patients to participate in clinical trials and access treatments should be a human right.
66+
</p>
67+
<p className="mb-6 text-xl">
68+
This provision garuntees:
69+
</p>
6270
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
6371
{sections.map((section, i) => (
6472
<motion.div

app/loading.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,37 @@ const insights = [
1212
text: `It's sad that a family can be torn apart by something as simple as wild dogs.`,
1313
},
1414
{
15-
text: "War is stupid.",
15+
text: "The US spends 20X more on war and the military than on clinical research",
1616
},
17+
{
18+
text: "There is nearly 0 correlation between public support for a bill and its likelihood of passage.",
19+
},
20+
{
21+
text: "For every $1 spent on prevention, we save $5.60 in treatment costs. Yet only 3% of healthcare spending goes to prevention.",
22+
},
23+
{
24+
text: "The U.S. spends twice as much on healthcare as other developed nations, but ranks 38th in health outcomes globally.",
25+
},
26+
{
27+
text: "Fossil fuel subsidies globally amount to $5.9 trillion annually.",
28+
},
29+
{
30+
text: "The U.S. has 5% of the world's population, but 25% of the world's prisoners.",
31+
},
32+
{
33+
text: "In the U.S., $6 in corporate welfare is spent for every $1 spent on food assistance.",
34+
}
1735
]
1836

1937
export default function Loading() {
2038
const randomQuote = insights[Math.floor(Math.random() * insights.length)]
2139

2240
return (
23-
<div className="flex min-h-screen items-center justify-center bg-gradient-to-b from-slate-900 to-slate-800 p-4">
41+
<div className="flex min-h-screen items-center justify-center p-4">
2442
<div className="flex max-w-xl flex-col items-center gap-8 text-center">
25-
<div className="h-12 w-12 animate-spin rounded-full border-4 border-indigo-500 border-t-transparent" />
43+
<div className="h-12 w-12 animate-spin rounded-full border-4 border-t-transparent" />
2644
<div className="space-y-3">
27-
<p className="font-serif text-xl italic text-slate-100">
45+
<p className="text-3xl">
2846
{randomQuote.text}
2947
</p>
3048
</div>

components/ui/image-upload.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import * as React from "react"
44

55
export interface ImageUploadProps {
6-
label: string
76
value: string | string[]
8-
multiple?: boolean
97
onChange: (value: string | string[]) => void
8+
onRemove?: (index?: number) => void
9+
multiple?: boolean
10+
label?: string
1011
}
1112

12-
export function ImageUpload({ label, value, multiple, onChange }: ImageUploadProps) {
13+
export function ImageUpload({ label, value, multiple, onChange, onRemove }: ImageUploadProps) {
1314
const inputId = React.useId()
1415

1516
return (

components/wishingWell/wishing-well-form.tsx

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import { useRouter } from "next/navigation"
55
import { zodResolver } from "@hookform/resolvers/zod"
66
import { useForm } from "react-hook-form"
77
import * as z from "zod"
8+
import { cn } from "@/lib/utils"
89

910
import { Button } from "@/components/ui/button"
10-
import { Input } from "@/components/ui/input"
11-
import { Textarea } from "@/components/ui/textarea"
1211
import { toast } from "@/components/ui/use-toast"
1312
import { ImageUpload } from "@/components/ui/image-upload"
1413
import type { WishingWell } from "@prisma/client"
@@ -27,6 +26,56 @@ interface WishingWellFormProps {
2726
wishingWell: WishingWell
2827
}
2928

29+
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
30+
error?: string;
31+
}
32+
33+
interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
34+
error?: string;
35+
}
36+
37+
const CustomTextarea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
38+
({ error, className, ...props }, ref) => {
39+
return (
40+
<div className="w-full">
41+
<textarea
42+
ref={ref}
43+
className={cn(
44+
"w-full rounded border px-3 py-2",
45+
error ? "border-red-500" : "border-gray-300",
46+
className
47+
)}
48+
{...props}
49+
/>
50+
{error && <p className="mt-1 text-sm text-red-500">{error}</p>}
51+
</div>
52+
);
53+
}
54+
);
55+
56+
CustomTextarea.displayName = "CustomTextarea";
57+
58+
const Input = React.forwardRef<HTMLInputElement, InputProps>(
59+
({ error, className, ...props }, ref) => {
60+
return (
61+
<div className="w-full">
62+
<input
63+
ref={ref}
64+
className={cn(
65+
"w-full rounded border px-3 py-2",
66+
error ? "border-red-500" : "border-gray-300",
67+
className
68+
)}
69+
{...props}
70+
/>
71+
{error && <p className="mt-1 text-sm text-red-500">{error}</p>}
72+
</div>
73+
);
74+
}
75+
);
76+
77+
Input.displayName = "Input";
78+
3079
export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
3180
const router = useRouter()
3281
const {
@@ -41,7 +90,7 @@ export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
4190
name: wishingWell.name,
4291
description: wishingWell.description || "",
4392
content: wishingWell.content || "",
44-
images: wishingWell.images,
93+
images: wishingWell.images || [],
4594
featuredImage: wishingWell.featuredImage || "",
4695
},
4796
})
@@ -83,7 +132,6 @@ export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
83132
<Input
84133
id="name"
85134
{...register("name")}
86-
className="w-full"
87135
error={errors.name?.message}
88136
/>
89137
</div>
@@ -92,7 +140,7 @@ export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
92140
<label htmlFor="description" className="text-sm font-medium">
93141
Description
94142
</label>
95-
<Textarea
143+
<CustomTextarea
96144
id="description"
97145
{...register("description")}
98146
className="min-h-[100px]"
@@ -104,7 +152,7 @@ export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
104152
<label htmlFor="content" className="text-sm font-medium">
105153
Content
106154
</label>
107-
<Textarea
155+
<CustomTextarea
108156
id="content"
109157
{...register("content")}
110158
className="min-h-[200px]"
@@ -115,8 +163,11 @@ export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
115163
<div className="space-y-2">
116164
<label className="text-sm font-medium">Featured Image</label>
117165
<ImageUpload
118-
value={watch("featuredImage")}
119-
onChange={(url) => setValue("featuredImage", url)}
166+
value={watch("featuredImage") ?? ""}
167+
onChange={(url: string | string[]) => {
168+
const finalUrl = Array.isArray(url) ? url[0] : url
169+
setValue("featuredImage", finalUrl)
170+
}}
120171
onRemove={() => setValue("featuredImage", "")}
121172
/>
122173
</div>
@@ -125,14 +176,19 @@ export function WishingWellForm({ wishingWell }: WishingWellFormProps) {
125176
<label className="text-sm font-medium">Additional Images</label>
126177
<ImageUpload
127178
multiple
128-
value={watch("images")}
129-
onChange={(urls) => setValue("images", urls)}
130-
onRemove={(index) => {
131-
const currentImages = watch("images") || []
132-
setValue(
133-
"images",
134-
currentImages.filter((_, i) => i !== index)
135-
)
179+
value={watch("images") ?? []}
180+
onChange={(urls: string | string[]) => {
181+
const finalUrls = Array.isArray(urls) ? urls : [urls]
182+
setValue("images", finalUrls)
183+
}}
184+
onRemove={(index?: number) => {
185+
if (typeof index !== 'undefined') {
186+
const currentImages = watch("images") ?? []
187+
setValue(
188+
"images",
189+
currentImages.filter((_, i) => i !== index)
190+
)
191+
}
136192
}}
137193
/>
138194
</div>

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"scripts": {
66
"dev": "next dev",
77
"build": "next build",
8+
"type-check": "tsc --noEmit",
89
"turbo": "next dev --turbo",
910
"start": "next start",
1011
"lint": "next lint",
@@ -30,8 +31,7 @@
3031
"deps:check": "depcheck",
3132
"deps:check:size": "npm-check",
3233
"deps:check:comprehensive": "cost-of-modules",
33-
"deps:unused-exports": "ts-prune",
34-
"type-check": "tsc --noEmit"
34+
"deps:unused-exports": "ts-prune"
3535
},
3636
"prisma": {
3737
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"

0 commit comments

Comments
 (0)