Skip to content

Commit 5bd6468

Browse files
committed
feat: Added homepage
1 parent 35e6646 commit 5bd6468

File tree

5 files changed

+77
-5
lines changed

5 files changed

+77
-5
lines changed

src/components/molecules/TemplateRenderer.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ function BaseTemplateRenderer({ template, onSubmit }: TemplateRendererProps): Re
2727
useEffect(() => {
2828
let isMounted = true;
2929
fetch(`/api/templates/${template}`)
30-
.then(res => (res.ok ? (res.json() as Promise<{ template: string }>) : setNoTemplate(true)))
30+
.then(res => {
31+
if (res.ok) return res.json() as Promise<{ template: string }>;
32+
else {
33+
setNoTemplate(true);
34+
return null;
35+
}
36+
})
3137
.then(data => {
3238
if (isMounted) setTemplateResponse(data?.template);
3339
});
@@ -83,7 +89,9 @@ function BaseTemplateRenderer({ template, onSubmit }: TemplateRendererProps): Re
8389
<Card className="bg-card/50 backdrop-blur-sm border-muted grow shrink basis-0 min-w-0">
8490
<CardContent className="pt-6">
8591
<pre className="text-start">
86-
{noTemplate ? 'Template not found.' : parts.map(part => (part === '\n' ? <br /> : typeof part === 'string' ? part : part.component))}
92+
{noTemplate
93+
? 'Template not found.'
94+
: parts.map(part => (part === '\n' ? <br /> : typeof part === 'string' ? part : part.component))}
8795
</pre>
8896
<hr className="m-6 border-zinc-300 dark:border-zinc-600" />
8997
<Button onClick={() => console.log(getCurrentCode())}>Submit!</Button>

src/hooks/useFetch.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useRef, useState } from 'react';
2+
3+
export function useFetch<Data>(...args: Parameters<typeof fetch>): {
4+
data: Data | null;
5+
loading: boolean;
6+
error: Response | null;
7+
} {
8+
const [loading, setLoading] = useState(false);
9+
const [error, setError] = useState<Response | null>(null);
10+
const [data, setData] = useState<Data | null>(null);
11+
12+
const fetchRef = useRef(false);
13+
if (!fetchRef.current) {
14+
fetch(...args).then(res => {
15+
if (!res.ok) {
16+
setLoading(false);
17+
setError(res);
18+
} else {
19+
res.json().then(data => {
20+
setLoading(false);
21+
setData(data);
22+
});
23+
}
24+
});
25+
fetchRef.current = true;
26+
}
27+
return { data, loading, error };
28+
}

src/index.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { serve } from 'bun';
22
import path from 'path';
33
import index from './index.html';
4+
import { readdir } from 'fs/promises';
45

56
const server = serve({
67
routes: {
@@ -22,6 +23,14 @@ const server = serve({
2223
return Response.json({ message: 'Not found' }, { status: 404 });
2324
}
2425
},
26+
27+
'/api/exercises': async () => {
28+
const files = await readdir(path.join(__dirname, '..', 'templates'));
29+
const exercises = files
30+
.filter(file => file.endsWith('.template.ts'))
31+
.map(file => file.replace('.template.ts', ''));
32+
return Response.json({ exercises });
33+
},
2534
},
2635

2736
websocket: {

src/pages/Exercises.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { useFetch } from '@/hooks/useFetch';
2+
import { Button } from '@/components/ui/button';
3+
4+
export function Exercises() {
5+
const { data, loading } = useFetch<{ exercises: string[] }>('/api/exercises');
6+
const exercises = data?.exercises ?? [];
7+
return (
8+
<>
9+
Welcome to TypeScript exercises!
10+
<br />
11+
{loading ? (
12+
'Loading exercises...'
13+
) : (
14+
<>
15+
Available exercises:
16+
<ul>
17+
{exercises.map(exercise => (
18+
<li key={exercise}>
19+
<Button value={exercise} size="sm">
20+
<a href={`/exercise/${exercise}`}>{exercise}</a>
21+
</Button>
22+
</li>
23+
))}
24+
</ul>
25+
</>
26+
)}
27+
</>
28+
);
29+
}

src/pages/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
export function Index() {
2-
return 'Welcome to TypeScript exercises!';
3-
}
1+
export { Exercises as Index } from './Exercises';

0 commit comments

Comments
 (0)