Skip to content

Commit 648fde0

Browse files
committed
chore: fix small issues with Playground
Squashed commit of the following: commit ce14ccde2f8fe9f9676d26b0828841342aa2e47a Author: Wojtek Majewski <wojciech.majewski@pm.me> Date: Sat May 3 22:37:55 2025 +0200 fix: improve time formatting for better readability and accuracy - Add space in '< 1s' to '< 1s' for consistency - Change 'now' to '0s' in relative time display to better reflect zero time difference commit 9f02d4900f723cc54fdde31aaa295bc5da60e3ef Author: Wojtek Majewski <wojciech.majewski@pm.me> Date: Sat May 3 22:35:02 2025 +0200 refactor: improve time formatting and code consistency in flow run details - Updated time difference formatting to be more concise (e.g., "5s", "3m 45s") - Simplified relative time display for better readability (e.g., "now", "5m", "2d") - Corrected conditional expressions to use proper syntax - Ensured consistent sorting and retrieval of latest task data - Removed redundant className concatenations and improved styling logic - Enhanced code clarity and maintainability across multiple time-related functions and UI components commit 3bbd04a Author: Wojtek Majewski <wojciech.majewski@pm.me> Date: Sat May 3 22:30:13 2025 +0200 fix: update example links with a renamed label and add commented-out URL - Changed label from 'Demo Failure' to '100% failure' for clarity - Added a commented-out URL for potential future use - Minor formatting adjustments in the example links array commit 9ec20d5 Author: Wojtek Majewski <wojciech.majewski@pm.me> Date: Sat May 3 22:02:50 2025 +0200 feat: add centralized example links for website analysis components - Introduced a new example-links module with predefined website URLs and labels - Replaced hardcoded website links in homepage and analysis UI with dynamic mapping - Improved maintainability and consistency of example website options across components
1 parent a546e25 commit 648fde0

File tree

4 files changed

+162
-151
lines changed

4 files changed

+162
-151
lines changed

examples/playground/app/page.tsx

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Hero from '@/components/hero';
22
import WebsiteAnalyzerForm from '@/components/website-analyzer-form';
33
import AuthRedirectHandler from '@/components/auth-redirect-handler';
44
import { createClient } from '@/utils/supabase/server';
5+
import { exampleLinks } from '@/lib/example-links';
56

67
export default async function Home() {
78
const supabase = await createClient();
@@ -35,30 +36,19 @@ export default async function Home() {
3536
Example Websites to Analyze
3637
</h3>
3738
<div className="flex flex-wrap gap-4">
38-
<a
39-
href="/websites?url=https://reddit.com/r/supabase"
40-
className="inline-flex px-3 py-2 bg-green-100 text-green-800 hover:bg-green-200 rounded-md text-sm font-medium"
41-
>
42-
reddit.com/r/supabase
43-
</a>
44-
<a
45-
href="/websites?url=https://supabase.com/docs"
46-
className="inline-flex px-3 py-2 bg-green-100 text-green-800 hover:bg-green-200 rounded-md text-sm font-medium"
47-
>
48-
supabase.com/docs
49-
</a>
50-
<a
51-
href="/websites?url=https://pgflow.dev"
52-
className="inline-flex px-3 py-2 bg-green-100 text-green-800 hover:bg-green-200 rounded-md text-sm font-medium"
53-
>
54-
pgflow.dev
55-
</a>
56-
<a
57-
href="/websites?url=https://firebase.google.com/"
58-
className="inline-flex px-3 py-2 bg-red-100 text-red-800 hover:bg-red-200 rounded-md text-sm font-medium"
59-
>
60-
Demo Failure
61-
</a>
39+
{exampleLinks.map((link) => (
40+
<a
41+
key={link.url}
42+
href={`/websites?url=${link.url}`}
43+
className={`inline-flex px-3 py-2 ${
44+
link.variant === 'success'
45+
? 'bg-green-100 text-green-800 hover:bg-green-200'
46+
: 'bg-red-100 text-red-800 hover:bg-red-200'
47+
} rounded-md text-sm font-medium`}
48+
>
49+
{link.label}
50+
</a>
51+
))}
6252
</div>
6353
</div>
6454
</div>

examples/playground/components/flow-run-details.tsx

Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const breathingAnimation = `
2222
}
2323
`;
2424

25-
// Format time difference in a human-readable way
25+
// Format time difference in a concise way (e.g., "5s", "3m 45s", "2h 15m")
2626
function formatTimeDifference(
2727
startDate: string | null,
2828
endDate: string | null,
@@ -36,27 +36,27 @@ function formatTimeDifference(
3636
const diffSec = Math.floor(diffMs / 1000);
3737

3838
if (diffSec < 1) {
39-
return 'less than a second';
39+
return '< 1s';
4040
}
4141

4242
if (diffSec < 60) {
43-
return `${diffSec} second${diffSec !== 1 ? 's' : ''}`;
43+
return `${diffSec}s`;
4444
}
4545

4646
const minutes = Math.floor(diffSec / 60);
4747
const seconds = diffSec % 60;
4848

4949
if (minutes < 60) {
50-
return `${minutes} minute${minutes !== 1 ? 's' : ''} ${seconds} second${seconds !== 1 ? 's' : ''}`;
50+
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
5151
}
5252

5353
const hours = Math.floor(minutes / 60);
5454
const remainingMinutes = minutes % 60;
5555

56-
return `${hours} hour${hours !== 1 ? 's' : ''} ${remainingMinutes} minute${remainingMinutes !== 1 ? 's' : ''}`;
56+
return remainingMinutes > 0 ? `${hours}h ${remainingMinutes}m` : `${hours}h`;
5757
}
5858

59-
// Format relative time (e.g., "3 seconds ago")
59+
// Format relative time in a concise way (e.g., "3s ago", "5m ago")
6060
function formatRelativeTime(
6161
date: string | null,
6262
now: Date = new Date(),
@@ -69,27 +69,27 @@ function formatRelativeTime(
6969

7070
// Handle case where time difference is negative (server/client time mismatch)
7171
if (diffSec < 1) {
72-
return 'just now';
72+
return '0s';
7373
}
7474

7575
if (diffSec < 60) {
76-
return `${diffSec} second${diffSec !== 1 ? 's' : ''} ago`;
76+
return `${diffSec}s`;
7777
}
7878

7979
const minutes = Math.floor(diffSec / 60);
8080

8181
if (minutes < 60) {
82-
return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
82+
return `${minutes}m`;
8383
}
8484

8585
const hours = Math.floor(minutes / 60);
8686

8787
if (hours < 24) {
88-
return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
88+
return `${hours}h`;
8989
}
9090

9191
const days = Math.floor(hours / 24);
92-
return `${days} day${days !== 1 ? 's' : ''} ago`;
92+
return `${days}d`;
9393
}
9494

9595
interface FlowRunDetailsProps {
@@ -164,14 +164,14 @@ export default function FlowRunDetails({
164164
{runData.status === 'started' ? 'running' : runData.status}
165165
</span>
166166
</div>
167-
<div className="text-xs text-muted-foreground">
167+
<div className="text-xs">
168168
{runData.status === 'started' && runData.started_at && (
169-
<span>
169+
<span className="text-yellow-600/80">
170170
Running for {formatTimeDifference(runData.started_at, null)}
171171
</span>
172172
)}
173173
{runData.status === 'completed' && runData.completed_at && (
174-
<span>
174+
<span className="text-green-600/80">
175175
Took{' '}
176176
{formatTimeDifference(
177177
runData.started_at,
@@ -180,8 +180,8 @@ export default function FlowRunDetails({
180180
</span>
181181
)}
182182
{runData.status === 'failed' && runData.failed_at && (
183-
<span>
184-
Failed after
183+
<span className="text-red-600/80">
184+
Failed after{' '}
185185
{formatTimeDifference(runData.started_at, runData.failed_at)}
186186
</span>
187187
)}
@@ -230,8 +230,10 @@ export default function FlowRunDetails({
230230
// Find the corresponding step tasks for this step
231231
const stepTasks = runData.step_tasks
232232
?.filter((task) => task.step_slug === step.step_slug)
233-
.sort((a, b) => (a.step_index || 0) - (b.step_index || 0));
234-
233+
.sort(
234+
(a, b) => (a.step_index || 0) - (b.step_index || 0),
235+
);
236+
235237
// Get the completed task with output
236238
const stepTask = stepTasks?.find(
237239
(task) => task.status === 'completed',
@@ -240,33 +242,37 @@ export default function FlowRunDetails({
240242
return (
241243
<Collapsible
242244
key={index}
243-
className={`mb-1 rounded-lg border ${
244-
(() => {
245-
// Get the pre-sorted step tasks from above
246-
const latestTask = stepTasks && stepTasks.length > 0
247-
? stepTasks.sort((a, b) =>
248-
(b.attempts_count || 0) - (a.attempts_count || 0)
249-
)[0]
245+
className={`mb-1 rounded-lg border ${(() => {
246+
// Get the pre-sorted step tasks from above
247+
const latestTask =
248+
stepTasks && stepTasks.length > 0
249+
? stepTasks.sort(
250+
(a, b) =>
251+
(b.attempts_count || 0) -
252+
(a.attempts_count || 0),
253+
)[0]
250254
: null;
251-
252-
// Check if this is a retry (attempts_count > 1)
253-
const isRetrying = latestTask && latestTask.attempts_count > 1 && step.status === 'started';
254-
255-
if (step.status === 'completed') {
256-
return 'bg-green-500/5 border-green-500/30';
257-
} else if (isRetrying) {
258-
return 'bg-red-500/5 border-red-500/30 animate-pulse';
259-
} else if (step.status === 'started') {
260-
return 'bg-yellow-500/5 border-yellow-500/30';
261-
} else if (step.status === 'failed') {
262-
return 'bg-red-500/5 border-red-500/30';
263-
} else if (step.status === 'created') {
264-
return 'bg-blue-500/5 border-blue-500/30';
265-
} else {
266-
return 'bg-gray-500/5 border-gray-500/30';
267-
}
268-
})()
269-
}`}
255+
256+
// Check if this is a retry (attempts_count > 1)
257+
const isRetrying =
258+
latestTask &&
259+
latestTask.attempts_count > 1 &&
260+
step.status === 'started';
261+
262+
if (step.status === 'completed') {
263+
return 'bg-green-500/5 border-green-500/30';
264+
} else if (isRetrying) {
265+
return 'bg-red-500/5 border-red-500/30 animate-pulse';
266+
} else if (step.status === 'started') {
267+
return 'bg-yellow-500/5 border-yellow-500/30';
268+
} else if (step.status === 'failed') {
269+
return 'bg-red-500/5 border-red-500/30';
270+
} else if (step.status === 'created') {
271+
return 'bg-blue-500/5 border-blue-500/30';
272+
} else {
273+
return 'bg-gray-500/5 border-gray-500/30';
274+
}
275+
})()}`}
270276
>
271277
<CollapsibleTrigger className="flex items-center justify-between w-full p-2 text-left">
272278
<div>
@@ -276,7 +282,7 @@ export default function FlowRunDetails({
276282
</div>
277283
<div className="flex items-center">
278284
{step.status === 'started' && step.started_at && (
279-
<span className="text-xs text-muted-foreground mr-2">
285+
<span className="text-xs text-yellow-600/80 mr-2">
280286
{formatRelativeTime(
281287
step.started_at,
282288
currentTime,
@@ -286,7 +292,7 @@ export default function FlowRunDetails({
286292
{step.status === 'completed' &&
287293
step.started_at &&
288294
step.completed_at && (
289-
<span className="text-xs text-muted-foreground mr-2">
295+
<span className="text-xs text-green-600/80 mr-2">
290296
{formatTimeDifference(
291297
step.started_at,
292298
step.completed_at,
@@ -296,7 +302,7 @@ export default function FlowRunDetails({
296302
{step.status === 'failed' &&
297303
step.started_at &&
298304
step.failed_at && (
299-
<span className="text-xs text-muted-foreground mr-2">
305+
<span className="text-xs text-red-600/80 mr-2">
300306
Failed after{' '}
301307
{formatTimeDifference(
302308
step.started_at,
@@ -306,15 +312,21 @@ export default function FlowRunDetails({
306312
)}
307313
{(() => {
308314
// Use the pre-sorted step tasks from above
309-
const latestTask = stepTasks && stepTasks.length > 0
310-
? stepTasks.sort((a, b) =>
311-
(b.attempts_count || 0) - (a.attempts_count || 0)
312-
)[0]
313-
: null;
314-
315+
const latestTask =
316+
stepTasks && stepTasks.length > 0
317+
? stepTasks.sort(
318+
(a, b) =>
319+
(b.attempts_count || 0) -
320+
(a.attempts_count || 0),
321+
)[0]
322+
: null;
323+
315324
// Check if this is a retry (attempts_count > 1)
316-
const isRetrying = latestTask && latestTask.attempts_count > 1 && step.status === 'started';
317-
325+
const isRetrying =
326+
latestTask &&
327+
latestTask.attempts_count > 1 &&
328+
step.status === 'started';
329+
318330
return (
319331
<span
320332
className={`inline-block w-2 h-2 rounded-full mr-1 ${
@@ -336,15 +348,21 @@ export default function FlowRunDetails({
336348
<span className="capitalize text-xs">
337349
{(() => {
338350
// Use the pre-sorted step tasks from above
339-
const latestTask = stepTasks && stepTasks.length > 0
340-
? stepTasks.sort((a, b) =>
341-
(b.attempts_count || 0) - (a.attempts_count || 0)
342-
)[0]
343-
: null;
344-
351+
const latestTask =
352+
stepTasks && stepTasks.length > 0
353+
? stepTasks.sort(
354+
(a, b) =>
355+
(b.attempts_count || 0) -
356+
(a.attempts_count || 0),
357+
)[0]
358+
: null;
359+
345360
// Check if this is a retry (attempts_count > 1)
346-
const isRetrying = latestTask && latestTask.attempts_count > 1 && step.status === 'started';
347-
361+
const isRetrying =
362+
latestTask &&
363+
latestTask.attempts_count > 1 &&
364+
step.status === 'started';
365+
348366
if (isRetrying) {
349367
return `retrying (retry ${latestTask.attempts_count - 1})`;
350368
} else if (step.status === 'created') {

0 commit comments

Comments
 (0)