From da9c1a67129f3d0077f0b3d38c8f51bb54385b2c Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Thu, 19 Jun 2025 12:44:14 +0530 Subject: [PATCH 1/6] get the mvp done --- src/components/ApplicationsShowcase.astro | 308 ++++++++++++++++++ .../applications/ApplicationsShowcase.tsx | 293 +++++++++++++++++ src/components/applications/types.ts | 21 ++ .../aws/{sample-apps.md => sample-apps.mdx} | 4 + 4 files changed, 626 insertions(+) create mode 100644 src/components/ApplicationsShowcase.astro create mode 100644 src/components/applications/ApplicationsShowcase.tsx create mode 100644 src/components/applications/types.ts rename src/content/docs/aws/{sample-apps.md => sample-apps.mdx} (82%) diff --git a/src/components/ApplicationsShowcase.astro b/src/components/ApplicationsShowcase.astro new file mode 100644 index 00000000..5b8d46f2 --- /dev/null +++ b/src/components/ApplicationsShowcase.astro @@ -0,0 +1,308 @@ +--- +import applicationsData from '../data/developerhub/applications.json'; +import servicesData from '../data/developerhub/services.json'; +import platformsData from '../data/developerhub/platforms.json'; +import deploymentsData from '../data/developerhub/deployments.json'; +import complexitiesData from '../data/developerhub/complexities.json'; +import { ApplicationsShowcase } from './applications/ApplicationsShowcase'; + +const applications = applicationsData.applications; +--- + + + + \ No newline at end of file diff --git a/src/components/applications/ApplicationsShowcase.tsx b/src/components/applications/ApplicationsShowcase.tsx new file mode 100644 index 00000000..2a78b154 --- /dev/null +++ b/src/components/applications/ApplicationsShowcase.tsx @@ -0,0 +1,293 @@ +import React, { useState, useMemo } from 'react'; +import type { Application, FilterState } from './types'; + +interface ApplicationsShowcaseProps { + applications: Application[]; + services: Record; + platforms: Record; + deployments: Record; + complexities: { data: Record; order: string[] }; +} + +const ApplicationCard: React.FC<{ + app: Application; + services: Record; + platforms: Record; + deployments: Record; +}> = ({ app, services, platforms, deployments }) => { + return ( + + ); +}; + +const FilterSection: React.FC<{ + title: string; + items: string[]; + selectedItems: string[]; + onToggle: (item: string) => void; + getDisplayName: (code: string) => string; +}> = ({ title, items, selectedItems, onToggle, getDisplayName }) => { + return ( +
+

{title}

+
+ {items.map((item) => ( + + ))} +
+
+ ); +}; + +export const ApplicationsShowcase: React.FC = ({ + applications, + services, + platforms, + deployments, + complexities, +}) => { + const [filters, setFilters] = useState({ + services: [], + platforms: [], + deployments: [], + complexities: [], + showProOnly: false, + }); + + const [searchTerm, setSearchTerm] = useState(''); + + // Get unique values for filters + const uniqueServices = useMemo(() => { + const allServices = new Set(applications.flatMap(app => app.services)); + return Array.from(allServices).sort(); + }, [applications]); + + const uniquePlatforms = useMemo(() => { + const allPlatforms = new Set(applications.flatMap(app => app.platform)); + return Array.from(allPlatforms).sort(); + }, [applications]); + + const uniqueDeployments = useMemo(() => { + const allDeployments = new Set(applications.flatMap(app => app.deployment)); + return Array.from(allDeployments).sort(); + }, [applications]); + + const uniqueComplexities = useMemo(() => { + const allComplexities = new Set(applications.flatMap(app => app.complexity)); + return complexities.order.filter(complexity => allComplexities.has(complexity)); + }, [applications, complexities.order]); + + // Filter applications + const filteredApplications = useMemo(() => { + return applications.filter(app => { + // Search filter + if (searchTerm) { + const searchLower = searchTerm.toLowerCase(); + const matchesSearch = + app.title.toLowerCase().includes(searchLower) || + app.description.toLowerCase().includes(searchLower) || + app.tags.some(tag => tag.toLowerCase().includes(searchLower)); + if (!matchesSearch) return false; + } + + // Service filter + if (filters.services.length > 0) { + const hasService = filters.services.some(service => app.services.includes(service)); + if (!hasService) return false; + } + + // Platform filter + if (filters.platforms.length > 0) { + const hasPlatform = filters.platforms.some(platform => app.platform.includes(platform)); + if (!hasPlatform) return false; + } + + // Deployment filter + if (filters.deployments.length > 0) { + const hasDeployment = filters.deployments.some(deployment => app.deployment.includes(deployment)); + if (!hasDeployment) return false; + } + + // Complexity filter + if (filters.complexities.length > 0) { + const hasComplexity = filters.complexities.some(complexity => app.complexity.includes(complexity)); + if (!hasComplexity) return false; + } + + // Pro filter + if (filters.showProOnly && !app.pro) { + return false; + } + + return true; + }); + }, [applications, filters, searchTerm]); + + const toggleFilter = (filterType: keyof FilterState, item: string) => { + if (filterType === 'showProOnly') return; + + setFilters(prev => ({ + ...prev, + [filterType]: prev[filterType].includes(item) + ? prev[filterType].filter(i => i !== item) + : [...prev[filterType], item] + })); + }; + + return ( +
+
+
+ setSearchTerm(e.target.value)} + className="search-input" + /> + +
+
+ {filteredApplications.length} application{filteredApplications.length !== 1 ? 's' : ''} +
+
+ +
+ + +
+ {filteredApplications.map((app, index) => ( + + ))} + + {filteredApplications.length === 0 && ( +
+

No applications match your current filters.

+ +
+ )} +
+
+
+ ); +}; \ No newline at end of file diff --git a/src/components/applications/types.ts b/src/components/applications/types.ts new file mode 100644 index 00000000..cd476c7e --- /dev/null +++ b/src/components/applications/types.ts @@ -0,0 +1,21 @@ +export interface Application { + title: string; + description: string; + url: string; + teaser: string; + services: string[]; + deployment: string[]; + platform: string[]; + tags: string[]; + complexity: string[]; + pro: boolean; + cloudPods: boolean; +} + +export interface FilterState { + services: string[]; + platforms: string[]; + deployments: string[]; + complexities: string[]; + showProOnly: boolean; +} \ No newline at end of file diff --git a/src/content/docs/aws/sample-apps.md b/src/content/docs/aws/sample-apps.mdx similarity index 82% rename from src/content/docs/aws/sample-apps.md rename to src/content/docs/aws/sample-apps.mdx index 85ad5063..d54af2b8 100644 --- a/src/content/docs/aws/sample-apps.md +++ b/src/content/docs/aws/sample-apps.mdx @@ -6,5 +6,9 @@ sidebar: order: 4 --- +import ApplicationsShowcase from "../../../components/ApplicationsShowcase.astro"; + # Applications LocalStack Applications provide sample templates to help LocalStack users adopt real-world scenarios to rapidly and conveniently create, configure, and deploy applications locally. These sample applications help you establish your foundations in LocalStack and offer you a wide range of use cases and scenarios, all supported by LocalStack, to help you develop and test cloud applications efficiently. + + From 0d4185cefc6fade9e3cc4ca08db4ba78ca12eac1 Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Thu, 19 Jun 2025 12:52:00 +0530 Subject: [PATCH 2/6] some improvements --- src/components/ApplicationsShowcase.astro | 577 ++++++++++++++---- .../applications/ApplicationsShowcase.tsx | 384 +++++++----- 2 files changed, 691 insertions(+), 270 deletions(-) diff --git a/src/components/ApplicationsShowcase.astro b/src/components/ApplicationsShowcase.astro index 5b8d46f2..df5230af 100644 --- a/src/components/ApplicationsShowcase.astro +++ b/src/components/ApplicationsShowcase.astro @@ -19,290 +19,627 @@ const applications = applicationsData.applications; /> \ No newline at end of file diff --git a/src/components/applications/ApplicationsShowcase.tsx b/src/components/applications/ApplicationsShowcase.tsx index 2a78b154..e0ce12ed 100644 --- a/src/components/applications/ApplicationsShowcase.tsx +++ b/src/components/applications/ApplicationsShowcase.tsx @@ -17,83 +17,98 @@ const ApplicationCard: React.FC<{ }> = ({ app, services, platforms, deployments }) => { return (
- -
- {app.title} - {app.pro && Pro} +
+ {app.title} +
+
+ {app.pro && Pro} + {app.complexity[0]} +
-
-

{app.title}

-

{app.description}

- -
-
- {app.services.slice(0, 6).map((serviceCode) => ( +
+ +
+

{app.title}

+

{app.description}

+ +
+
+ {app.services.slice(0, 8).map((serviceCode) => ( +
{services[serviceCode] - ))} - {app.services.length > 6 && ( - +{app.services.length - 6} - )} -
- -
-
- {app.platform.slice(0, 2).map((platformCode) => ( - - {platforms[platformCode] || platformCode} - - ))} - {app.platform.length > 2 && ( - +{app.platform.length - 2} - )} -
-
- {app.deployment.slice(0, 2).map((deploymentCode) => ( - - {deployments[deploymentCode] || deploymentCode} - - ))} - {app.deployment.length > 2 && ( - +{app.deployment.length - 2} - )}
-
+ ))} + {app.services.length > 8 && ( +
+{app.services.length - 8}
+ )} +
+ +
+ {app.platform.slice(0, 3).map((platformCode) => ( + + {platforms[platformCode] || platformCode} + + ))} + {app.deployment.slice(0, 2).map((deploymentCode) => ( + + {deployments[deploymentCode] || deploymentCode} + + ))}
+ +
+ View Project → +
- +
); }; -const FilterSection: React.FC<{ +const FilterDropdown: React.FC<{ title: string; items: string[]; selectedItems: string[]; onToggle: (item: string) => void; getDisplayName: (code: string) => string; -}> = ({ title, items, selectedItems, onToggle, getDisplayName }) => { + isOpen: boolean; + onToggleOpen: () => void; +}> = ({ title, items, selectedItems, onToggle, getDisplayName, isOpen, onToggleOpen }) => { return ( -
-

{title}

-
- {items.map((item) => ( - - ))} -
+
+ + + {isOpen && ( +
+
+ {items.map((item) => ( + + ))} +
+
+ )}
); }; @@ -114,31 +129,33 @@ export const ApplicationsShowcase: React.FC = ({ }); const [searchTerm, setSearchTerm] = useState(''); + const [sortBy, setSortBy] = useState<'title' | 'complexity'>('title'); + const [openDropdown, setOpenDropdown] = useState(null); // Get unique values for filters const uniqueServices = useMemo(() => { const allServices = new Set(applications.flatMap(app => app.services)); - return Array.from(allServices).sort(); - }, [applications]); + return Array.from(allServices).sort((a, b) => (services[a] || a).localeCompare(services[b] || b)); + }, [applications, services]); const uniquePlatforms = useMemo(() => { const allPlatforms = new Set(applications.flatMap(app => app.platform)); - return Array.from(allPlatforms).sort(); - }, [applications]); + return Array.from(allPlatforms).sort((a, b) => (platforms[a] || a).localeCompare(platforms[b] || b)); + }, [applications, platforms]); const uniqueDeployments = useMemo(() => { const allDeployments = new Set(applications.flatMap(app => app.deployment)); - return Array.from(allDeployments).sort(); - }, [applications]); + return Array.from(allDeployments).sort((a, b) => (deployments[a] || a).localeCompare(deployments[b] || b)); + }, [applications, deployments]); const uniqueComplexities = useMemo(() => { const allComplexities = new Set(applications.flatMap(app => app.complexity)); return complexities.order.filter(complexity => allComplexities.has(complexity)); }, [applications, complexities.order]); - // Filter applications + // Filter and sort applications const filteredApplications = useMemo(() => { - return applications.filter(app => { + let filtered = applications.filter(app => { // Search filter if (searchTerm) { const searchLower = searchTerm.toLowerCase(); @@ -180,7 +197,19 @@ export const ApplicationsShowcase: React.FC = ({ return true; }); - }, [applications, filters, searchTerm]); + + // Sort applications + return filtered.sort((a, b) => { + if (sortBy === 'title') { + return a.title.localeCompare(b.title); + } else { + const complexityOrder = { basic: 0, intermediate: 1, advanced: 2 }; + const aComplexity = complexityOrder[a.complexity[0] as keyof typeof complexityOrder] ?? 1; + const bComplexity = complexityOrder[b.complexity[0] as keyof typeof complexityOrder] ?? 1; + return aComplexity - bComplexity; + } + }); + }, [applications, filters, searchTerm, sortBy]); const toggleFilter = (filterType: keyof FilterState, item: string) => { if (filterType === 'showProOnly') return; @@ -193,100 +222,155 @@ export const ApplicationsShowcase: React.FC = ({ })); }; + const clearAllFilters = () => { + setFilters({ + services: [], + platforms: [], + deployments: [], + complexities: [], + showProOnly: false, + }); + setSearchTerm(''); + }; + + const hasActiveFilters = filters.services.length > 0 || + filters.platforms.length > 0 || + filters.deployments.length > 0 || + filters.complexities.length > 0 || + filters.showProOnly || + searchTerm.length > 0; + return (
-
- setSearchTerm(e.target.value)} - className="search-input" - /> - -
-
- {filteredApplications.length} application{filteredApplications.length !== 1 ? 's' : ''} -
-
- -
- + toggleFilter('platforms', item)} + getDisplayName={(code) => platforms[code] || code} + isOpen={openDropdown === 'platforms'} + onToggleOpen={() => setOpenDropdown(openDropdown === 'platforms' ? null : 'platforms')} + /> -
- {filteredApplications.map((app, index) => ( - toggleFilter('complexities', item)} + getDisplayName={(code) => complexities.data[code] || code} + isOpen={openDropdown === 'complexities'} + onToggleOpen={() => setOpenDropdown(openDropdown === 'complexities' ? null : 'complexities')} /> - ))} - - {filteredApplications.length === 0 && ( -
-

No applications match your current filters.

-
+ +
+ + {filteredApplications.length} application{filteredApplications.length !== 1 ? 's' : ''} + + {hasActiveFilters && ( + + )} +
+
+
+ +
+ {filteredApplications.map((app, index) => ( + + ))} + + {filteredApplications.length === 0 && ( +
+
+ + + + +

No applications found

+

Try adjusting your search terms or filters to find what you're looking for.

+
- )} - +
+ )}
); From 4b7846c94f720e3a28b3c2cdaf163687ba820bac Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Thu, 19 Jun 2025 13:06:22 +0530 Subject: [PATCH 3/6] more improvements --- src/components/ApplicationsShowcase.astro | 522 ++++-------------- .../applications/ApplicationsShowcase.tsx | 335 +++++------ 2 files changed, 250 insertions(+), 607 deletions(-) diff --git a/src/components/ApplicationsShowcase.astro b/src/components/ApplicationsShowcase.astro index df5230af..3a3153d4 100644 --- a/src/components/ApplicationsShowcase.astro +++ b/src/components/ApplicationsShowcase.astro @@ -19,352 +19,149 @@ const applications = applicationsData.applications; /> \ No newline at end of file diff --git a/src/components/applications/ApplicationsShowcase.tsx b/src/components/applications/ApplicationsShowcase.tsx index e0ce12ed..e49cb05d 100644 --- a/src/components/applications/ApplicationsShowcase.tsx +++ b/src/components/applications/ApplicationsShowcase.tsx @@ -1,5 +1,26 @@ import React, { useState, useMemo } from 'react'; -import type { Application, FilterState } from './types'; + +interface Application { + title: string; + description: string; + url: string; + teaser: string; + services: string[]; + platform: string[]; + deployment: string[]; + tags: string[]; + complexity: string[]; + pro: boolean; + cloudPods: boolean; +} + +interface FilterState { + services: string[]; + platforms: string[]; + deployments: string[]; + complexities: string[]; + showProOnly: boolean; +} interface ApplicationsShowcaseProps { applications: Application[]; @@ -16,14 +37,12 @@ const ApplicationCard: React.FC<{ deployments: Record; }> = ({ app, services, platforms, deployments }) => { return ( -
+
{app.title} -
-
- {app.pro && Pro} - {app.complexity[0]} -
+
+ {app.pro && Pro} + {app.complexity[0]}
@@ -33,33 +52,19 @@ const ApplicationCard: React.FC<{
- {app.services.slice(0, 8).map((serviceCode) => ( -
+ {app.services.slice(0, 10).map((serviceCode) => ( +
{services[serviceCode]
))} - {app.services.length > 8 && ( -
+{app.services.length - 8}
+ {app.services.length > 10 && ( +
+{app.services.length - 10}
)}
-
- {app.platform.slice(0, 3).map((platformCode) => ( - - {platforms[platformCode] || platformCode} - - ))} - {app.deployment.slice(0, 2).map((deploymentCode) => ( - - {deployments[deploymentCode] || deploymentCode} - - ))} -
- void; - getDisplayName: (code: string) => string; - isOpen: boolean; - onToggleOpen: () => void; -}> = ({ title, items, selectedItems, onToggle, getDisplayName, isOpen, onToggleOpen }) => { - return ( -
- - - {isOpen && ( -
-
- {items.map((item) => ( - - ))} -
-
- )} -
- ); -}; - export const ApplicationsShowcase: React.FC = ({ applications, services, @@ -130,7 +96,6 @@ export const ApplicationsShowcase: React.FC = ({ const [searchTerm, setSearchTerm] = useState(''); const [sortBy, setSortBy] = useState<'title' | 'complexity'>('title'); - const [openDropdown, setOpenDropdown] = useState(null); // Get unique values for filters const uniqueServices = useMemo(() => { @@ -162,38 +127,18 @@ export const ApplicationsShowcase: React.FC = ({ const matchesSearch = app.title.toLowerCase().includes(searchLower) || app.description.toLowerCase().includes(searchLower) || - app.tags.some(tag => tag.toLowerCase().includes(searchLower)); + app.tags.some(tag => tag.toLowerCase().includes(searchLower)) || + app.services.some(service => (services[service] || service).toLowerCase().includes(searchLower)) || + app.platform.some(platform => (platforms[platform] || platform).toLowerCase().includes(searchLower)); if (!matchesSearch) return false; } - // Service filter - if (filters.services.length > 0) { - const hasService = filters.services.some(service => app.services.includes(service)); - if (!hasService) return false; - } - - // Platform filter - if (filters.platforms.length > 0) { - const hasPlatform = filters.platforms.some(platform => app.platform.includes(platform)); - if (!hasPlatform) return false; - } - - // Deployment filter - if (filters.deployments.length > 0) { - const hasDeployment = filters.deployments.some(deployment => app.deployment.includes(deployment)); - if (!hasDeployment) return false; - } - - // Complexity filter - if (filters.complexities.length > 0) { - const hasComplexity = filters.complexities.some(complexity => app.complexity.includes(complexity)); - if (!hasComplexity) return false; - } - - // Pro filter - if (filters.showProOnly && !app.pro) { - return false; - } + // Other filters + if (filters.services.length > 0 && !filters.services.some(service => app.services.includes(service))) return false; + if (filters.platforms.length > 0 && !filters.platforms.some(platform => app.platform.includes(platform))) return false; + if (filters.deployments.length > 0 && !filters.deployments.some(deployment => app.deployment.includes(deployment))) return false; + if (filters.complexities.length > 0 && !filters.complexities.some(complexity => app.complexity.includes(complexity))) return false; + if (filters.showProOnly && !app.pro) return false; return true; }); @@ -209,7 +154,7 @@ export const ApplicationsShowcase: React.FC = ({ return aComplexity - bComplexity; } }); - }, [applications, filters, searchTerm, sortBy]); + }, [applications, filters, searchTerm, sortBy, services, platforms]); const toggleFilter = (filterType: keyof FilterState, item: string) => { if (filterType === 'showProOnly') return; @@ -242,107 +187,101 @@ export const ApplicationsShowcase: React.FC = ({ return (
-
-
-
-
- - - - setSearchTerm(e.target.value)} - className="search-input" - /> - {searchTerm && ( - - )} -
-
- -
- - - -
+
+
+ setSearchTerm(e.target.value)} + className="search-input" + /> + {searchTerm && ( + + )}
+ + -
-
- toggleFilter('services', item)} - getDisplayName={(code) => services[code] || code} - isOpen={openDropdown === 'services'} - onToggleOpen={() => setOpenDropdown(openDropdown === 'services' ? null : 'services')} - /> + - toggleFilter('deployments', item)} - getDisplayName={(code) => deployments[code] || code} - isOpen={openDropdown === 'deployments'} - onToggleOpen={() => setOpenDropdown(openDropdown === 'deployments' ? null : 'deployments')} - /> + - toggleFilter('platforms', item)} - getDisplayName={(code) => platforms[code] || code} - isOpen={openDropdown === 'platforms'} - onToggleOpen={() => setOpenDropdown(openDropdown === 'platforms' ? null : 'platforms')} - /> + - toggleFilter('complexities', item)} - getDisplayName={(code) => complexities.data[code] || code} - isOpen={openDropdown === 'complexities'} - onToggleOpen={() => setOpenDropdown(openDropdown === 'complexities' ? null : 'complexities')} - /> -
+ + + -
- - {filteredApplications.length} application{filteredApplications.length !== 1 ? 's' : ''} - - {hasActiveFilters && ( - - )} -
-
+ {hasActiveFilters && ( + + )} +
+ +
+ {filteredApplications.length} application{filteredApplications.length !== 1 ? 's' : ''}
@@ -358,17 +297,11 @@ export const ApplicationsShowcase: React.FC = ({ {filteredApplications.length === 0 && (
-
- - - - -

No applications found

-

Try adjusting your search terms or filters to find what you're looking for.

- -
+

No applications found

+

Try adjusting your search or filters.

+
)}
From 435dad736d319de2b33438f898dea7c53fe8d47e Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Thu, 19 Jun 2025 13:12:32 +0530 Subject: [PATCH 4/6] minor css work --- src/components/ApplicationsShowcase.astro | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/ApplicationsShowcase.astro b/src/components/ApplicationsShowcase.astro index 3a3153d4..2a833d3f 100644 --- a/src/components/ApplicationsShowcase.astro +++ b/src/components/ApplicationsShowcase.astro @@ -41,8 +41,8 @@ const applications = applicationsData.applications; :global(.search-container) { position: relative; - flex: 1; - min-width: 250px; + flex: 2; + min-width: 300px; } :global(.search-input) { @@ -88,7 +88,8 @@ const applications = applicationsData.applications; background: var(--sl-color-bg); color: var(--sl-color-white); font-size: 0.875rem; - min-width: 120px; + min-width: 140px; + flex-shrink: 0; } :global(.filter-select:focus) { @@ -113,7 +114,8 @@ const applications = applicationsData.applications; background: var(--sl-color-bg); color: var(--sl-color-white); font-size: 0.875rem; - min-width: 100px; + min-width: 120px; + flex-shrink: 0; } :global(.clear-filters) { @@ -326,11 +328,11 @@ const applications = applicationsData.applications; :global(.top-bar) { flex-direction: column; align-items: stretch; - gap: 0.75rem; } :global(.search-container) { min-width: auto; + flex: none; } :global(.filter-select), From b45c9e3cc27bb08284cac936e6a2c3e47c0fe7b8 Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Thu, 19 Jun 2025 13:24:41 +0530 Subject: [PATCH 5/6] improve cards --- src/components/ApplicationsShowcase.astro | 16 ++++------------ .../applications/ApplicationsShowcase.tsx | 8 ++++---- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/components/ApplicationsShowcase.astro b/src/components/ApplicationsShowcase.astro index 2a833d3f..25b9e969 100644 --- a/src/components/ApplicationsShowcase.astro +++ b/src/components/ApplicationsShowcase.astro @@ -41,7 +41,7 @@ const applications = applicationsData.applications; :global(.search-container) { position: relative; - flex: 2; + flex: 1; min-width: 300px; } @@ -89,7 +89,6 @@ const applications = applicationsData.applications; color: var(--sl-color-white); font-size: 0.875rem; min-width: 140px; - flex-shrink: 0; } :global(.filter-select:focus) { @@ -115,7 +114,6 @@ const applications = applicationsData.applications; color: var(--sl-color-white); font-size: 0.875rem; min-width: 120px; - flex-shrink: 0; } :global(.clear-filters) { @@ -239,10 +237,7 @@ const applications = applicationsData.applications; :global(.service-icon) { width: 1.75rem; height: 1.75rem; - padding: 0.25rem; - background: var(--sl-color-bg); - border: 1px solid var(--sl-color-gray-6); - border-radius: 0.25rem; + padding: 0.125rem; display: flex; align-items: center; justify-content: center; @@ -250,7 +245,6 @@ const applications = applicationsData.applications; } :global(.service-icon:hover) { - border-color: var(--sl-color-accent); transform: scale(1.1); } @@ -273,20 +267,18 @@ const applications = applicationsData.applications; display: inline-flex; align-items: center; gap: 0.5rem; - color: var(--sl-color-accent); + color: white; text-decoration: none; font-weight: 500; font-size: 0.875rem; padding: 0.5rem 0.75rem; - border: 1px solid var(--sl-color-accent); border-radius: 0.375rem; transition: all 0.2s ease; white-space: nowrap; } :global(.card-link:hover) { - background: var(--sl-color-accent); - color: white; + color: var(--sl-color-accent); } /* No Results */ diff --git a/src/components/applications/ApplicationsShowcase.tsx b/src/components/applications/ApplicationsShowcase.tsx index e49cb05d..5ca8f7e3 100644 --- a/src/components/applications/ApplicationsShowcase.tsx +++ b/src/components/applications/ApplicationsShowcase.tsx @@ -208,7 +208,7 @@ export const ApplicationsShowcase: React.FC = ({ onChange={(e) => e.target.value ? toggleFilter('services', e.target.value) : null} className="filter-select" > - + {uniqueServices.map((service) => (
+ ); }; \ No newline at end of file