Skip to content

Commit 711fa28

Browse files
committed
Improve UI/UX: refactor filter pills, redesign resource cards, add GitHub stars, and remove broken link
- Refactor filter pills to use horizontal scrolling with outline style for inactive pills - Redesign resource cards: move like button to top-right, remove date, improve tag styling - Add color-coded tags (blue for css/html/layout, yellow for js/ts/react, green for testing, purple for accessibility) - Add GitHub stars display with golden star icon for social proof - Remove broken Dive Into HTML5 resource link
1 parent 79b7f2f commit 711fa28

8 files changed

Lines changed: 80 additions & 53 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060

6161
### HTML5
6262

63-
- [Dive Into HTML5](http://diveintohtml5.info/index.html) - Classic comprehensive guide to HTML5 features. Still valuable for understanding semantic HTML and modern web standards.
6463
- [HTML5 Cheat Sheet](https://websitesetup.org/html5-cheat-sheet/) - Quick reference guide for HTML5 tags and attributes. Great for daily development.
6564
- [Responsive Images Guide](http://cloudinary.com/blog/automatically_art_directed_responsive_images) - Excellent article explaining responsive images with practical examples. Essential for modern web development.
6665

src/app/components/App.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useState, useMemo } from "react";
2-
import { Github, PlusCircle } from "lucide-react";
1+
import { useState, useMemo, useEffect } from "react";
2+
import { Github, PlusCircle, Star } from "lucide-react";
33
import { SearchBar } from "./SearchBar";
44
import { ResourceCard } from "./ResourceCard";
55
import { CategoryFilter } from "./CategoryFilter";
@@ -14,6 +14,26 @@ function App() {
1414
null
1515
);
1616
const [likes, setLikes] = useState<Record<string, number>>({});
17+
const [githubStars, setGithubStars] = useState<number | null>(null);
18+
19+
useEffect(() => {
20+
// Fetch GitHub stars count
21+
const fetchGithubStars = async () => {
22+
try {
23+
const response = await fetch(
24+
"https://api.github.com/repos/codesandtags/frontend-documentation"
25+
);
26+
if (response.ok) {
27+
const data = await response.json();
28+
setGithubStars(data.stargazers_count);
29+
}
30+
} catch (error) {
31+
console.error("Failed to fetch GitHub stars:", error);
32+
}
33+
};
34+
35+
fetchGithubStars();
36+
}, []);
1737

1838
const resources = useMemo(() => getResources(), []);
1939

@@ -69,6 +89,12 @@ function App() {
6989
>
7090
<Github className="h-5 w-5" />
7191
<span className="hidden sm:inline">GitHub</span>
92+
{githubStars !== null && (
93+
<span className="flex items-center gap-1 text-sm">
94+
<Star className="h-4 w-4 fill-yellow-400 text-yellow-400" />
95+
<span>{githubStars.toLocaleString()}</span>
96+
</span>
97+
)}
7298
</a>
7399
<a
74100
href="https://github.com/codesandtags/frontend-resources/blob/main/CONTRIBUTING.md"

src/app/components/CategoryFilter.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ export function CategoryFilter({
3434
onSelect,
3535
}: CategoryFilterProps) {
3636
return (
37-
<div className="flex flex-wrap gap-2">
37+
<div className="flex overflow-x-auto gap-2 scrollbar-hide pb-2">
3838
<button
3939
onClick={() => onSelect(null)}
40-
className={`px-4 py-2 rounded-full text-sm font-medium transition-all
40+
className={`px-4 py-2 rounded-full text-sm font-medium transition-all whitespace-nowrap flex-shrink-0
4141
${
4242
!selectedCategory
4343
? "bg-blue-600 text-white"
44-
: "bg-gray-700 text-gray-300 hover:bg-gray-600"
44+
: "bg-transparent border border-gray-600 text-gray-400 hover:bg-gray-800"
4545
}`}
4646
>
4747
All
@@ -50,11 +50,11 @@ export function CategoryFilter({
5050
<button
5151
key={category}
5252
onClick={() => onSelect(category)}
53-
className={`px-4 py-2 rounded-full text-sm font-medium transition-all
53+
className={`px-4 py-2 rounded-full text-sm font-medium transition-all whitespace-nowrap flex-shrink-0
5454
${
5555
selectedCategory === category
5656
? "bg-blue-600 text-white"
57-
: "bg-gray-700 text-gray-300 hover:bg-gray-600"
57+
: "bg-transparent border border-gray-600 text-gray-400 hover:bg-gray-800"
5858
}`}
5959
>
6060
{category}

src/app/components/ResourceCard.tsx

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@ interface ResourceCardProps {
1010

1111
export function ResourceCard({ resource, onLike }: ResourceCardProps) {
1212
return (
13-
<div className="bg-gray-800 rounded-xl border border-gray-700 p-6 transition-all hover:border-gray-600 hover:shadow-lg hover:shadow-black/20">
14-
<div className="flex justify-between items-start mb-4">
13+
<div className="relative bg-gray-800 rounded-xl border border-gray-700 p-6 transition-all hover:border-gray-600 hover:shadow-lg hover:shadow-black/20">
14+
{/* Like button in top-right corner */}
15+
<button
16+
onClick={() => onLike(resource.id)}
17+
className="absolute top-4 right-4 flex items-center gap-1 bg-gray-800 rounded px-3 py-1.5 text-gray-400 hover:text-pink-400 hover:bg-gray-700 transition-colors z-10"
18+
>
19+
<Heart className="h-4 w-4" />
20+
<span className="text-sm">{resource.likes || 0}</span>
21+
</button>
22+
23+
<div className="flex justify-between items-start mb-4 pr-20">
1524
<div className="flex items-start gap-3">
1625
<div className="text-blue-400">
1726
<TechIcon category={resource.category} />
@@ -29,32 +38,19 @@ export function ResourceCard({ resource, onLike }: ResourceCardProps) {
2938
href={resource.url}
3039
target="_blank"
3140
rel="noopener noreferrer"
32-
className="text-gray-400 hover:text-blue-400 transition-colors"
41+
className="text-gray-400 hover:text-blue-400 transition-colors mt-1"
3342
>
3443
<ExternalLink className="h-5 w-5" />
3544
</a>
3645
</div>
3746

3847
<p className="text-gray-300 mb-4">{resource.description}</p>
3948

40-
<div className="flex flex-wrap gap-2 mb-4">
49+
<div className="flex flex-wrap gap-2">
4150
{resource.tags.map((tag) => (
4251
<Tag key={tag} label={tag} />
4352
))}
4453
</div>
45-
46-
<div className="flex justify-between items-center text-sm">
47-
<button
48-
onClick={() => onLike(resource.id)}
49-
className="flex items-center gap-1 text-gray-400 hover:text-pink-400 transition-colors"
50-
>
51-
<Heart className="h-4 w-4" />
52-
<span>{resource.likes || 0}</span>
53-
</button>
54-
<span className="text-gray-500">
55-
Added on {new Date(resource.addedOn).toLocaleDateString()}
56-
</span>
57-
</div>
5854
</div>
5955
);
6056
}

src/app/components/Tag.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function Tag({ label }: TagProps) {
1010

1111
return (
1212
<span
13-
className={`inline-flex items-center gap-1 px-3 py-1 rounded-full text-sm font-medium ${bg} ${text}`}
13+
className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium ${bg} ${text}`}
1414
>
1515
<TagIcon className="h-2 w-2" />
1616
{label}

src/app/globals.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,13 @@ body {
1919
background: var(--background);
2020
font-family: Arial, Helvetica, sans-serif;
2121
}
22+
23+
/* Hide scrollbar for horizontal scrolling filter pills */
24+
.scrollbar-hide {
25+
scrollbar-width: none; /* Firefox */
26+
-ms-overflow-style: none; /* IE and Edge */
27+
}
28+
29+
.scrollbar-hide::-webkit-scrollbar {
30+
display: none; /* Chrome, Safari, Opera */
31+
}

src/app/utils/tagColors.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,31 @@ interface TagColorMap {
66
}
77

88
export const getTagColors = (tag: string): { bg: string; text: string } => {
9+
const tagLower = tag.toLowerCase();
10+
911
const colorMap: TagColorMap = {
10-
react: { bg: 'bg-blue-600/20', text: 'text-blue-300' },
11-
vue: { bg: 'bg-emerald-600/20', text: 'text-emerald-300' },
12-
angular: { bg: 'bg-red-600/20', text: 'text-red-300' },
13-
typescript: { bg: 'bg-blue-600/20', text: 'text-blue-300' },
14-
javascript: { bg: 'bg-yellow-600/20', text: 'text-yellow-300' },
15-
css: { bg: 'bg-pink-600/20', text: 'text-pink-300' },
16-
html: { bg: 'bg-orange-600/20', text: 'text-orange-300' },
17-
framework: { bg: 'bg-purple-600/20', text: 'text-purple-300' },
18-
library: { bg: 'bg-indigo-600/20', text: 'text-indigo-300' },
19-
tool: { bg: 'bg-cyan-600/20', text: 'text-cyan-300' },
20-
testing: { bg: 'bg-green-600/20', text: 'text-green-300' },
21-
state: { bg: 'bg-violet-600/20', text: 'text-violet-300' },
22-
async: { bg: 'bg-fuchsia-600/20', text: 'text-fuchsia-300' },
23-
bundler: { bg: 'bg-amber-600/20', text: 'text-amber-300' },
24-
development: { bg: 'bg-teal-600/20', text: 'text-teal-300' },
12+
// Blue for css, html, layout
13+
css: { bg: 'bg-blue-900', text: 'text-blue-300' },
14+
html: { bg: 'bg-blue-900', text: 'text-blue-300' },
15+
html5: { bg: 'bg-blue-900', text: 'text-blue-300' },
16+
layout: { bg: 'bg-blue-900', text: 'text-blue-300' },
17+
18+
// Yellow for javascript, typescript, react
19+
javascript: { bg: 'bg-yellow-900', text: 'text-yellow-300' },
20+
typescript: { bg: 'bg-yellow-900', text: 'text-yellow-300' },
21+
react: { bg: 'bg-yellow-900', text: 'text-yellow-300' },
22+
23+
// Green for testing
24+
testing: { bg: 'bg-green-900', text: 'text-green-300' },
25+
test: { bg: 'bg-green-900', text: 'text-green-300' },
26+
27+
// Purple for accessibility
28+
accessibility: { bg: 'bg-purple-900', text: 'text-purple-300' },
29+
a11y: { bg: 'bg-purple-900', text: 'text-purple-300' },
2530
};
2631

27-
// Default color for tags without specific mapping
28-
const defaultColor = { bg: 'bg-gray-600/20', text: 'text-gray-300' };
32+
// Default: low-contrast gray style
33+
const defaultColor = { bg: 'bg-gray-800', text: 'text-gray-400' };
2934

30-
return colorMap[tag.toLowerCase()] || defaultColor;
35+
return colorMap[tagLower] || defaultColor;
3136
};

src/data/resources.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
11
[
2-
{
3-
"id": "dive-into-html5",
4-
"title": "Dive Into HTML5",
5-
"url": "http://diveintohtml5.info/index.html",
6-
"description": "Classic comprehensive guide to HTML5 features. Still valuable for understanding semantic HTML and modern web standards.",
7-
"category": "Learning",
8-
"tags": ["html5", "semantic", "guide"],
9-
"addedOn": "2024-01-01"
10-
},
112
{
123
"id": "responsive-images-guide",
134
"title": "Responsive Images Guide",

0 commit comments

Comments
 (0)