Skip to content

Commit ddbab4c

Browse files
committed
chore: run formatter
1 parent e916479 commit ddbab4c

15 files changed

Lines changed: 119 additions & 137 deletions

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ A modern, responsive web application for discovering and exploring modules and d
44

55
<img width="1277" height="773" alt="Знімок екрана 2025-08-06 о 17 01 00" src="https://github.com/user-attachments/assets/8be09316-6d87-47ca-8b70-15619d3d5f1f" />
66

7-
87
## 🚀 Features
98

109
- **Dual Interface**: Browse both modules and data sources with dedicated views
@@ -69,6 +68,7 @@ A modern, responsive web application for discovering and exploring modules and d
6968
The application fetches data from multiple sources:
7069

7170
### Modules Data
71+
7272
- **ASIMOV Platform API**: Module metadata, stars, and GitHub information
7373
- **GitHub API**: Live repository data and statistics
7474
- **YAML Manifests**: Module configuration and metadata
@@ -91,6 +91,7 @@ The project uses a custom color palette defined in `src/styles/global.css`:
9191
### Navigation Structure
9292

9393
Two main sections:
94+
9495
- **Sources** (`/`): Browse data sources with endpoints and formats
9596
- **Modules** (`/modules`): Explore GitHub modules with metadata
9697

@@ -165,6 +166,7 @@ npm run format:check # Check code formatting
165166
## 📊 Performance & Caching
166167

167168
### Query Caching
169+
168170
- **TanStack Query**: Intelligent data caching with stale-while-revalidate
169171
- **Optimistic Updates**: Smooth user experience with background refetching
170172
- **Error Recovery**: Automatic retry logic for failed requests

src/components/GitHubStats.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,27 @@ interface GitHubStatsProps {
1212
}
1313

1414
export default function GitHubStats({ variant = 'desktop' }: GitHubStatsProps) {
15-
const { data: stars, isLoading: isStarsLoading } = useQuery({
16-
queryKey: ['asimov-modules-stars'],
17-
queryFn: fetchTotalModuleStars,
18-
staleTime: 10 * 60 * 1000, // 10 minutes
19-
gcTime: 20 * 60 * 1000, // 20 minutes
20-
retry: 2
21-
}, queryClient);
15+
const { data: stars, isLoading: isStarsLoading } = useQuery(
16+
{
17+
queryKey: ['asimov-modules-stars'],
18+
queryFn: fetchTotalModuleStars,
19+
staleTime: 10 * 60 * 1000, // 10 minutes
20+
gcTime: 20 * 60 * 1000, // 20 minutes
21+
retry: 2
22+
},
23+
queryClient
24+
);
2225

23-
const { data: followers, isLoading: isFollowersLoading } = useQuery({
24-
queryKey: ['asimov-platform-followers'],
25-
queryFn: fetchOrgFollowers,
26-
staleTime: 10 * 60 * 1000, // 10 minutes
27-
gcTime: 20 * 60 * 1000, // 20 minutes
28-
retry: 2
29-
}, queryClient);
26+
const { data: followers, isLoading: isFollowersLoading } = useQuery(
27+
{
28+
queryKey: ['asimov-platform-followers'],
29+
queryFn: fetchOrgFollowers,
30+
staleTime: 10 * 60 * 1000, // 10 minutes
31+
gcTime: 20 * 60 * 1000, // 20 minutes
32+
retry: 2
33+
},
34+
queryClient
35+
);
3036

3137
const containerClass =
3238
variant === 'desktop'

src/components/MetricsBadge.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ interface MetricsBadgeProps {
66
loading?: boolean;
77
}
88

9-
export default function MetricsBadge({ href, value, icon: Icon, variant, loading }: MetricsBadgeProps) {
9+
export default function MetricsBadge({
10+
href,
11+
value,
12+
icon: Icon,
13+
variant,
14+
loading
15+
}: MetricsBadgeProps) {
1016
const linkClass =
1117
variant === 'desktop'
1218
? 'group flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white/80 px-3 py-1.5 text-sm transition-all hover:border-orange-200 hover:bg-orange-50'
@@ -27,16 +33,11 @@ export default function MetricsBadge({ href, value, icon: Icon, variant, loading
2733
<div className="h-4 w-8 rounded bg-gray-300"></div>
2834
</div>
2935
) : (
30-
<a
31-
href={href}
32-
target="_blank"
33-
rel="noopener noreferrer"
34-
className={linkClass}
35-
>
36+
<a href={href} target="_blank" rel="noopener noreferrer" className={linkClass}>
3637
<Icon size={14} className={iconClass} />
3738
<span className={textClass}>{value}</span>
3839
</a>
3940
)}
4041
</>
41-
)
42-
};
42+
);
43+
}

src/components/ModuleCard.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ export default function ModuleCard({ module }: ModuleCardProps) {
2525
console.log(manifest);
2626

2727
return (
28-
<div className="group border-sSlate-200 hover:border-sSlate-300 relative overflow-hidden rounded-lg border bg-white p-6 shadow-sm transition-all duration-200 hover:shadow-lg"
29-
>
28+
<div className="group border-sSlate-200 hover:border-sSlate-300 relative overflow-hidden rounded-lg border bg-white p-6 shadow-sm transition-all duration-200 hover:shadow-lg">
3029
<div className="mb-4 flex items-start justify-between">
3130
<div className="flex items-center space-x-3">
3231
<img

src/components/ModulesApp.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ export default function ModulesApp({ initialSort }: ModulesAppProps) {
2525
hasNextPage
2626
} = useInfiniteQuery(createModulesQuery(sortOption), queryClient);
2727

28-
const modules = data?.pages.flatMap(
29-
(page) => page.repositories.filter(({ name }) => rxModule.test(name) && !WHITELISTED_MODULES.includes(name)) || []
30-
) || [];
28+
const modules =
29+
data?.pages.flatMap(
30+
(page) =>
31+
page.repositories.filter(
32+
({ name }) => rxModule.test(name) && !WHITELISTED_MODULES.includes(name)
33+
) || []
34+
) || [];
3135

3236
const handleSortChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
3337
const newSort = event.target.value as SortOption;
@@ -81,7 +85,6 @@ export default function ModulesApp({ initialSort }: ModulesAppProps) {
8185
>
8286
<ModulesGrid modules={modules} loading={loading} error={error?.message || null} />
8387
</InfiniteScroll>
84-
8588
</div>
8689
);
8790
}

src/components/SourcesCardsView.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,7 @@ export default function SourcesCardsView({ sources }: SourcesCardsViewProps) {
8282
<div className="flex items-center space-x-2">
8383
<button
8484
onClick={() =>
85-
copyToClipboard(
86-
endpoint.url,
87-
`card-${dataset}-${endpointIndex}`
88-
)
85+
copyToClipboard(endpoint.url, `card-${dataset}-${endpointIndex}`)
8986
}
9087
className="border-sSlate-200 text-gGray-500 hover:bg-gGray-50 hover:text-sSlate-700 hover:border-sSlate-300 rounded border bg-white p-1 transition-colors"
9188
title="Copy endpoint URL"
@@ -118,7 +115,7 @@ export default function SourcesCardsView({ sources }: SourcesCardsViewProps) {
118115
))}
119116
</div>
120117
</div>
121-
)
118+
);
122119
})}
123120
</div>
124121
);

src/components/SourcesTable.tsx

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { useState, useMemo } from 'react';
22
import { useQuery } from '@tanstack/react-query';
3-
import {
4-
WarningCircle,
5-
List,
6-
GridFour,
7-
MagnifyingGlass,
8-
Database
9-
} from '@phosphor-icons/react';
3+
import { WarningCircle, List, GridFour, MagnifyingGlass, Database } from '@phosphor-icons/react';
104

115
import SourcesTableView from './SourcesTableView';
126
import SourcesCardsView from './SourcesCardsView';
@@ -23,33 +17,28 @@ interface SourcesTableProps {
2317
export default function SourcesTable({ searchQuery = '' }: SourcesTableProps) {
2418
const [viewMode, setViewMode] = useState<'table' | 'cards'>('table');
2519

26-
const {
27-
data,
28-
isLoading: loading,
29-
error
30-
} = useQuery(
31-
createSourcesQuery(),
32-
queryClient
33-
);
20+
const { data, isLoading: loading, error } = useQuery(createSourcesQuery(), queryClient);
3421

3522
const dataSources = useMemo(() => {
36-
const filteredGroups = data?.filter((dataSource) => {
37-
if (!searchQuery) return true;
38-
39-
const searchLower = searchQuery.toLowerCase();
40-
return (
41-
dataSource.dataset.toLowerCase().includes(searchLower) ||
42-
generateDisplayName(dataSource.dataset).toLowerCase().includes(searchLower) ||
43-
dataSource.endpoints.some(
44-
(endpoint) =>
45-
endpoint.url.toLowerCase().includes(searchLower) ||
46-
endpoint.modules.some(module =>
47-
module.name.toLowerCase().includes(searchLower) ||
48-
module.label.toLowerCase().includes(searchLower)
49-
)
50-
)
51-
);
52-
}) ?? [];
23+
const filteredGroups =
24+
data?.filter((dataSource) => {
25+
if (!searchQuery) return true;
26+
27+
const searchLower = searchQuery.toLowerCase();
28+
return (
29+
dataSource.dataset.toLowerCase().includes(searchLower) ||
30+
generateDisplayName(dataSource.dataset).toLowerCase().includes(searchLower) ||
31+
dataSource.endpoints.some(
32+
(endpoint) =>
33+
endpoint.url.toLowerCase().includes(searchLower) ||
34+
endpoint.modules.some(
35+
(module) =>
36+
module.name.toLowerCase().includes(searchLower) ||
37+
module.label.toLowerCase().includes(searchLower)
38+
)
39+
)
40+
);
41+
}) ?? [];
5342

5443
return filteredGroups.sort((a, b) => {
5544
if (b.endpoints.length !== a.endpoints.length) {
@@ -118,8 +107,8 @@ export default function SourcesTable({ searchQuery = '' }: SourcesTableProps) {
118107
<div className="space-y-4">
119108
<div className="text-gGray-600 flex items-center justify-between text-sm">
120109
<span>
121-
{dataSources.length} data source{dataSources.length !== 1 ? 's' : ''}{' '}
122-
{totalModules} unique modules
110+
{dataSources.length} data source{dataSources.length !== 1 ? 's' : ''} {totalModules}{' '}
111+
unique modules
123112
</span>
124113

125114
<div className="flex items-center space-x-4">

src/components/SourcesTableView.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default function SourcesTableView({ sources }: SourcesTableViewProps) {
5858
className="border-sSlate-200 overflow-hidden rounded-lg border bg-white"
5959
>
6060
<div
61-
className="cursor-pointer p-3 transition-colors hover:bg-gGray-50/50 sm:p-4"
61+
className="hover:bg-gGray-50/50 cursor-pointer p-3 transition-colors sm:p-4"
6262
onClick={() => toggleExpanded(dataset)}
6363
onKeyDown={(e) => {
6464
if (e.key === 'Enter' || e.key === ' ') {
@@ -192,10 +192,7 @@ export default function SourcesTableView({ sources }: SourcesTableViewProps) {
192192
<button
193193
onClick={(e) => {
194194
e.stopPropagation();
195-
copyToClipboard(
196-
endpoint.url,
197-
`${dataset}-${endpointIndex}`
198-
);
195+
copyToClipboard(endpoint.url, `${dataset}-${endpointIndex}`);
199196
}}
200197
className="border-sSlate-200 text-gGray-500 hover:bg-gGray-50 hover:text-sSlate-700 hover:border-sSlate-300 rounded border bg-white p-1.5 transition-colors"
201198
title="Copy endpoint URL"
@@ -218,10 +215,7 @@ export default function SourcesTableView({ sources }: SourcesTableViewProps) {
218215
<button
219216
onClick={(e) => {
220217
e.stopPropagation();
221-
copyToClipboard(
222-
endpoint.url,
223-
`${dataset}-${endpointIndex}`
224-
);
218+
copyToClipboard(endpoint.url, `${dataset}-${endpointIndex}`);
225219
}}
226220
className="border-sSlate-200 text-gGray-500 hover:bg-gGray-50 hover:text-sSlate-700 hover:border-sSlate-300 rounded border bg-white p-1.5 transition-colors"
227221
title="Copy endpoint URL"
@@ -247,7 +241,9 @@ export default function SourcesTableView({ sources }: SourcesTableViewProps) {
247241
rel="noopener noreferrer"
248242
>
249243
<GithubLogo className="h-3 w-3 sm:h-4 sm:w-4" />
250-
<span className="max-w-[100px] truncate sm:max-w-none">{module.label}</span>
244+
<span className="max-w-[100px] truncate sm:max-w-none">
245+
{module.label}
246+
</span>
251247
</a>
252248
))}
253249
</div>

src/layouts/Layout.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ const { title = 'ASIMOV.Directory', description = 'ASIMOV Data Sources Directory
3737
<script
3838
is:inline
3939
defer
40-
src="https://cloud.umami.is/script.js" data-website-id="fdbc7ec3-ff92-4e77-948a-2cdeeeb4f630"
41-
></script>
40+
src="https://cloud.umami.is/script.js"
41+
data-website-id="fdbc7ec3-ff92-4e77-948a-2cdeeeb4f630"></script>
4242
</head>
4343
<body>
4444
<slot />

src/lib/config.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ export const ASIMOV_DIRECTORY_REPO_NAME = 'asimov.directory';
77
export const ZUPLO_API_BASE = 'https://asimov-platform-main-4cffcce.d2.zuplo.dev';
88

99
export const WHITELISTED_MODULES = [
10-
".github",
11-
"asimov-template-module",
12-
"asimov-modules.rb",
13-
"asimov-modules.py",
14-
"asimov-goodreads-module",
15-
"asimov-test-module",
16-
"asimov-obsidian-module"
10+
'.github',
11+
'asimov-template-module',
12+
'asimov-modules.rb',
13+
'asimov-modules.py',
14+
'asimov-goodreads-module',
15+
'asimov-test-module',
16+
'asimov-obsidian-module'
1717
];
1818

1919
export const directoryGithubUrl = `${GITHUB_BASE_URL}/${ASIMOV_PROTOCOL_ORG_NAME}/${ASIMOV_DIRECTORY_REPO_NAME}`;

0 commit comments

Comments
 (0)