Skip to content

Commit 530498a

Browse files
committed
Optimize mobile UX and fix visibility issues across components
Mobile Enhancements: - Add proper viewport configuration with device-width scaling - Increase form input padding to py-3 (48px min touch targets) - Add text-base to prevent iOS auto-zoom on input focus - Enhance all buttons with min-h-[48px] for better touch targets - Make navigation buttons responsive with flex-col on mobile - Stack form action buttons vertically on small screens Visibility & Contrast Fixes: - Fix InlineCopy button with explicit bg/text colors - Fix Filters toggle button contrast in light/dark modes - Add text-gray-700 dark:text-gray-300 throughout for consistency - Ensure WCAG compliance for all interactive elements Component Updates: - ProjectDetail: Enhanced action buttons for mobile - Step1-5 forms: Improved input sizing and button touch targets - Layout: Moved viewport to separate export (Next.js 16 best practice) All changes tested with production build - no errors
1 parent adf66c1 commit 530498a

File tree

9 files changed

+49
-38
lines changed

9 files changed

+49
-38
lines changed

app/layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ const inter = Inter({
2727
display: "swap",
2828
});
2929

30+
export const viewport = {
31+
width: 'device-width',
32+
initialScale: 1,
33+
maximumScale: 5,
34+
userScalable: true,
35+
};
36+
3037
export const metadata: Metadata = {
3138
metadataBase: new URL('https://fossradar.in'),
3239
title: {

components/Filters.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ export function Filters({ availableTags, filters, onChange }: FiltersProps) {
5151
className={cn(
5252
"flex items-center gap-2 px-4 py-2 rounded-lg border transition-colors",
5353
"border-gray-200 dark:border-gray-700",
54+
"bg-white dark:bg-gray-900",
55+
"text-gray-700 dark:text-gray-300",
5456
"hover:bg-gray-100 dark:hover:bg-gray-800"
5557
)}
5658
>
57-
<Filter className="h-4 w-4" />
58-
<span>Filters</span>
59+
<Filter className="h-4 w-4 text-gray-700 dark:text-gray-300" />
60+
<span className="text-gray-700 dark:text-gray-300">Filters</span>
5961
{activeFilterCount > 0 && (
6062
<span className="ml-1 px-2 py-0.5 rounded-full bg-blue-600 text-white text-xs font-medium">
6163
{activeFilterCount}

components/InlineCopy.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export function InlineCopy({ text, label = "Copy" }: InlineCopyProps) {
2828
className={cn(
2929
"inline-flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
3030
"border border-gray-200 dark:border-gray-700",
31+
"bg-white dark:bg-gray-900",
32+
"text-gray-700 dark:text-gray-300",
3133
"hover:bg-gray-100 dark:hover:bg-gray-800",
3234
copied && "bg-green-50 dark:bg-green-900/20 border-green-300 dark:border-green-700"
3335
)}
@@ -40,8 +42,8 @@ export function InlineCopy({ text, label = "Copy" }: InlineCopyProps) {
4042
</>
4143
) : (
4244
<>
43-
<Copy className="h-4 w-4" />
44-
<span>{label}</span>
45+
<Copy className="h-4 w-4 text-gray-700 dark:text-gray-300" />
46+
<span className="text-gray-700 dark:text-gray-300">{label}</span>
4547
</>
4648
)}
4749
</button>

components/ProjectDetail.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,28 +78,28 @@ export function ProjectDetail({ project, cache, similarProjects }: ProjectDetail
7878
{/* Star on GitHub - Prominent CTA */}
7979
<GitHubStarButton repoUrl={project.repo} projectName={project.name} stars={project.stars || 0} />
8080

81-
{/* Quick Links */}
81+
{/* Quick Links - Mobile Optimized */}
8282
<div className="flex flex-wrap items-center gap-2 sm:gap-3 mb-4">
8383
<a
8484
href={project.repo}
8585
target="_blank"
8686
rel="noopener noreferrer"
87-
className="inline-flex items-center gap-2 px-3 sm:px-4 py-2 rounded-lg bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 hover:bg-gray-800 dark:hover:bg-gray-200 transition-colors text-sm sm:text-base"
87+
className="inline-flex items-center gap-2 px-4 sm:px-5 py-3 sm:py-2.5 rounded-lg bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 hover:bg-gray-800 dark:hover:bg-gray-200 transition-colors text-sm sm:text-base min-h-[44px]"
8888
>
89-
<Github className="h-4 w-4" />
90-
<span className="hidden xs:inline">View on GitHub</span>
91-
<span className="xs:hidden">GitHub</span>
89+
<Github className="h-4 w-4 sm:h-5 sm:w-5" />
90+
<span className="hidden sm:inline">View on GitHub</span>
91+
<span className="sm:hidden">GitHub</span>
9292
</a>
9393
{project.website && (
9494
<a
9595
href={project.website}
9696
target="_blank"
9797
rel="noopener noreferrer"
98-
className="inline-flex items-center gap-2 px-3 sm:px-4 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700 text-white transition-colors text-sm sm:text-base"
98+
className="inline-flex items-center gap-2 px-4 sm:px-5 py-3 sm:py-2.5 rounded-lg bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700 text-white transition-colors text-sm sm:text-base min-h-[44px]"
9999
>
100-
<ExternalLink className="h-4 w-4" />
101-
<span className="hidden xs:inline">Visit Website</span>
102-
<span className="xs:hidden">Website</span>
100+
<ExternalLink className="h-4 w-4 sm:h-5 sm:w-5" />
101+
<span className="hidden sm:inline">Visit Website</span>
102+
<span className="sm:hidden">Website</span>
103103
</a>
104104
)}
105105
</div>

components/submission-steps/Step1RepositoryDetails.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,18 @@ export function Step1RepositoryDetails({ form, onNext }: Step1Props) {
100100
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
101101
GitHub Repository URL <span className="text-red-500">*</span>
102102
</label>
103-
<div className="flex gap-2">
103+
<div className="flex flex-col sm:flex-row gap-2 sm:gap-2">
104104
<input
105105
type="url"
106106
{...form.register("repo")}
107107
placeholder="https://github.com/username/project"
108-
className="flex-1 px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
108+
className="flex-1 px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
109109
/>
110110
<button
111111
type="button"
112112
onClick={handleValidateRepo}
113113
disabled={!repoUrl || isValidating}
114-
className="px-4 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
114+
className="px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 min-h-[48px] whitespace-nowrap"
115115
>
116116
{isValidating ? (
117117
<>
@@ -221,7 +221,7 @@ export function Step1RepositoryDetails({ form, onNext }: Step1Props) {
221221
type="button"
222222
onClick={handleNext}
223223
disabled={!validationResult || !!validationResult.error}
224-
className="px-6 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
224+
className="px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed min-h-[48px]"
225225
>
226226
Next Step
227227
</button>

components/submission-steps/Step2ProjectInfo.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
107107
type="text"
108108
{...form.register("name")}
109109
placeholder="My Awesome Project"
110-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
110+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
111111
/>
112112
{form.formState.errors.name && (
113113
<p className="text-sm text-red-600 dark:text-red-400 mt-1">
@@ -126,7 +126,7 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
126126
type="text"
127127
{...form.register("slug")}
128128
placeholder="my-awesome-project"
129-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
129+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
130130
/>
131131
{form.formState.errors.slug && (
132132
<p className="text-sm text-red-600 dark:text-red-400 mt-1">
@@ -146,7 +146,7 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
146146
placeholder="A brief description of what your project does"
147147
rows={3}
148148
maxLength={160}
149-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
149+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
150150
/>
151151
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
152152
{form.watch("short_desc")?.length || 0} / 160 characters
@@ -167,7 +167,7 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
167167
type="text"
168168
{...form.register("primary_lang")}
169169
placeholder="TypeScript"
170-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
170+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
171171
/>
172172
{form.formState.errors.primary_lang && (
173173
<p className="text-sm text-red-600 dark:text-red-400 mt-1">
@@ -183,7 +183,7 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
183183
</label>
184184
<select
185185
{...form.register("license")}
186-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
186+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent min-h-[48px]"
187187
>
188188
<option value="">Select a license</option>
189189
{COMMON_LICENSES.map(license => (
@@ -237,7 +237,7 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
237237
}
238238
}}
239239
placeholder="Type to search tags..."
240-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
240+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
241241
/>
242242

243243
{filteredTags.length > 0 && (
@@ -285,14 +285,14 @@ export function Step2ProjectInfo({ form, onNext, onBack }: Step2Props) {
285285
<button
286286
type="button"
287287
onClick={onBack}
288-
className="px-6 py-2 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800"
288+
className="px-6 py-3 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 min-h-[48px]"
289289
>
290290
Back
291291
</button>
292292
<button
293293
type="button"
294294
onClick={handleNext}
295-
className="px-6 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors"
295+
className="px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors min-h-[48px]"
296296
>
297297
Next Step
298298
</button>

components/submission-steps/Step3LocationConnection.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function Step3LocationConnection({ form, onNext, onBack }: Step3Props) {
6161
setCityInput(e.target.value);
6262
}}
6363
placeholder="Bangalore"
64-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
64+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
6565
/>
6666

6767
{filteredCities.length > 0 && !MAJOR_INDIAN_CITIES.includes(locationCity) && (
@@ -97,7 +97,7 @@ export function Step3LocationConnection({ form, onNext, onBack }: Step3Props) {
9797
</label>
9898
<select
9999
{...form.register("location_indian_state")}
100-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
100+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent min-h-[48px]"
101101
>
102102
<option value="">Select a state</option>
103103
{INDIAN_STATES.map(state => (
@@ -148,7 +148,7 @@ export function Step3LocationConnection({ form, onNext, onBack }: Step3Props) {
148148
placeholder="Briefly describe your project's connection to India..."
149149
rows={3}
150150
maxLength={500}
151-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
151+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
152152
/>
153153
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
154154
{form.watch("india_connection_details")?.length || 0} / 500 characters
@@ -179,14 +179,14 @@ export function Step3LocationConnection({ form, onNext, onBack }: Step3Props) {
179179
<button
180180
type="button"
181181
onClick={onBack}
182-
className="px-6 py-2 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800"
182+
className="px-6 py-3 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 min-h-[48px]"
183183
>
184184
Back
185185
</button>
186186
<button
187187
type="button"
188188
onClick={handleNext}
189-
className="px-6 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors"
189+
className="px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors min-h-[48px]"
190190
>
191191
Next Step
192192
</button>

components/submission-steps/Step4OptionalDetails.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function Step4OptionalDetails({ form, onNext, onBack }: Step4Props) {
8383
type="url"
8484
{...form.register("website")}
8585
placeholder="https://your-project.com"
86-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
86+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
8787
/>
8888
{form.formState.errors.website && (
8989
<p className="text-sm text-red-600 dark:text-red-400 mt-1">
@@ -157,7 +157,7 @@ export function Step4OptionalDetails({ form, onNext, onBack }: Step4Props) {
157157
placeholder="Any additional information for the maintainers..."
158158
rows={4}
159159
maxLength={500}
160-
className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
160+
className="w-full px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 text-base focus:ring-2 focus:ring-blue-500 focus:border-transparent"
161161
/>
162162
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
163163
{form.watch("submitter_notes")?.length || 0} / 500 characters
@@ -168,14 +168,14 @@ export function Step4OptionalDetails({ form, onNext, onBack }: Step4Props) {
168168
<button
169169
type="button"
170170
onClick={onBack}
171-
className="px-6 py-2 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800"
171+
className="px-6 py-3 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 min-h-[48px]"
172172
>
173173
Back
174174
</button>
175175
<button
176176
type="button"
177177
onClick={onNext}
178-
className="px-6 py-2 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors"
178+
className="px-6 py-3 rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors min-h-[48px]"
179179
>
180180
Review & Submit
181181
</button>

components/submission-steps/Step5ReviewSubmit.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export function Step5ReviewSubmit({ form, onBack }: Step5Props) {
161161
<button
162162
type="button"
163163
onClick={() => signIn("github", { callbackUrl: window.location.href })}
164-
className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 hover:bg-gray-800 dark:hover:bg-gray-200 text-sm font-medium transition-colors"
164+
className="inline-flex items-center justify-center gap-2 px-4 py-3 rounded-lg bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 hover:bg-gray-800 dark:hover:bg-gray-200 text-sm font-medium transition-colors min-h-[48px]"
165165
>
166166
<Github className="h-4 w-4" />
167167
Sign in with GitHub
@@ -186,20 +186,20 @@ export function Step5ReviewSubmit({ form, onBack }: Step5Props) {
186186
)}
187187

188188
{/* Actions */}
189-
<div className="flex justify-between gap-3 pt-4">
189+
<div className="flex flex-col sm:flex-row justify-between gap-3 pt-4">
190190
<button
191191
type="button"
192192
onClick={onBack}
193193
disabled={isSubmitting}
194-
className="px-6 py-2 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-50"
194+
className="px-6 py-3 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-50 min-h-[48px]"
195195
>
196196
Back
197197
</button>
198198
<button
199199
type="button"
200200
onClick={handleSubmit}
201201
disabled={isSubmitting}
202-
className="px-6 py-3 rounded-lg bg-green-600 hover:bg-green-700 text-white font-semibold transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
202+
className="px-6 py-3 rounded-lg bg-green-600 hover:bg-green-700 text-white font-semibold transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 min-h-[48px]"
203203
>
204204
{isSubmitting ? (
205205
<>

0 commit comments

Comments
 (0)