Skip to content

Commit 401a2f7

Browse files
committed
improve homepage
1 parent c24cddf commit 401a2f7

File tree

1 file changed

+63
-34
lines changed

1 file changed

+63
-34
lines changed

playground/pages/home.tsx

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,45 @@ interface Repls {
3636
list: APIRepl[];
3737
}
3838

39+
const formatter = new Intl.RelativeTimeFormat('en');
40+
const timeAgo = (ms: number): string => {
41+
const sec = Math.round(ms / 1000);
42+
const min = Math.round(sec / 60);
43+
const hr = Math.round(min / 60);
44+
const day = Math.round(hr / 24);
45+
const month = Math.round(day / 30);
46+
const year = Math.round(month / 12);
47+
if (sec < 10) {
48+
return 'just now';
49+
} else if (sec < 45) {
50+
return formatter.format(-sec, 'second');
51+
} else if (sec < 90 || min < 45) {
52+
return formatter.format(-min, 'minute');
53+
} else if (min < 90 || hr < 24) {
54+
return formatter.format(-hr, 'hour');
55+
} else if (hr < 36 || day < 30) {
56+
return formatter.format(-day, 'day');
57+
} else if (month < 18) {
58+
return formatter.format(-month, 'month');
59+
} else {
60+
return formatter.format(-year, 'year');
61+
}
62+
};
63+
3964
export const Home = () => {
4065
const params = useParams();
4166
const context = useAppContext()!;
4267
const navigate = useNavigate();
4368
const location = useLocation();
4469

4570
createEffect(() => {
46-
if (!location.hash && (context.token || localStorage.getItem('scratchpad'))) return;
71+
if (!location.hash && context.token) return;
4772

4873
const initialTabs = parseHash(location.hash.slice(1), defaultTabs);
4974

5075
localStorage.setItem(
5176
'scratchpad',
5277
JSON.stringify({
53-
title: 'Scratchpad',
54-
public: true,
55-
labels: [],
56-
version: '1.0',
5778
files: initialTabs.map((x) => ({
5879
name: x.name + ((x as any).type ? `.${(x as any).type}` : ''),
5980
content: x.source.split('\n'),
@@ -92,37 +113,45 @@ export const Home = () => {
92113
}}
93114
/>
94115
<div class="m-8">
95-
<button
96-
class="bg-solid-lightgray shadow-md dark:bg-solid-darkLighterBg rounded-xl p-4 text-3xl flex mx-auto"
97-
onClick={async () => {
98-
const result = await fetch(`${API}/repl`, {
99-
method: 'POST',
100-
headers: {
101-
'authorization': `Bearer ${context.token}`,
102-
'Content-Type': 'application/json',
103-
},
104-
body: JSON.stringify({
105-
title: 'Counter Example',
106-
public: true,
107-
labels: [],
108-
version: '1.0',
109-
files: defaultTabs.map((x) => ({ name: x.name, content: x.source.split('\n') })),
110-
}),
111-
});
112-
const { id } = await result.json();
113-
navigate(`/${context.user()?.display}/${id}`);
114-
}}
115-
>
116-
<Icon path={plus} class="w-8" /> Create new REPL
117-
</button>
116+
<div class="flex flex-col align-middle">
117+
<button
118+
class="bg-solid-lightgray shadow-md dark:bg-solid-darkLighterBg rounded-xl p-4 text-3xl flex mx-auto"
119+
onClick={async () => {
120+
const result = await fetch(`${API}/repl`, {
121+
method: 'POST',
122+
headers: {
123+
'authorization': `Bearer ${context.token}`,
124+
'Content-Type': 'application/json',
125+
},
126+
body: JSON.stringify({
127+
title: 'Counter Example',
128+
public: true,
129+
labels: [],
130+
version: '1.0',
131+
files: defaultTabs.map((x) => ({ name: x.name, content: x.source.split('\n') })),
132+
}),
133+
});
134+
const { id } = await result.json();
135+
navigate(`/${context.user()?.display}/${id}`);
136+
}}
137+
>
138+
<Icon path={plus} class="w-8" /> Create new REPL
139+
</button>
140+
<p class="text-center text-gray-300 text-sm">
141+
Or{' '}
142+
<a href="/scratchpad" class="hover:underline">
143+
open my scratchpad
144+
</a>
145+
</p>
146+
</div>
118147

119148
<h1 class="text-center text-3xl mb-4 mt-16">{params.user || 'My'} Repls</h1>
120-
<table class="w-128 mx-auto">
149+
<table class="w-200 max-w-full mx-auto">
121150
<thead>
122151
<tr class="border-b border-neutral-600">
123-
<td>Title</td>
124-
<td>Edited</td>
125-
<td>Options</td>
152+
<td class="w-6/10">Title</td>
153+
<td class="w-32">Edited</td>
154+
<td class="text-right w-20">Options</td>
126155
</tr>
127156
</thead>
128157
<tbody>
@@ -153,8 +182,8 @@ export const Home = () => {
153182
<td>
154183
<a href={`${params.user || context.user()?.display}/${repl.id}`}>{repl.title}</a>
155184
</td>
156-
<td>{new Date(repl.created_at).toLocaleString()}</td>
157-
<td>
185+
<td>{timeAgo(Date.now() - new Date(repl.updated_at || repl.created_at).getTime())}</td>
186+
<td class="text-right">
158187
<Icon
159188
path={repl.public ? eye : eyeOff}
160189
class="w-6 inline m-2 ml-0 cursor-pointer"

0 commit comments

Comments
 (0)