Skip to content

Commit 550a6c6

Browse files
committed
refactor: remove the suspense card in favour of spinner
it was quite annoying that nothing would be accessible if soarca was not reachabble. Also the skeleton cards were quite ugly, I changed it to a simple spinner.
1 parent eb29980 commit 550a6c6

12 files changed

Lines changed: 370 additions & 496 deletions

File tree

src/api/utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ export async function deleteToApi(url: string): Promise<void> {
7777
* @example
7878
* const errorResponse = apiErrorToErrorResponse(error);
7979
*/
80-
export const getErrorFromApiResponse = (error: Error): ErrorResponse => {
81-
if (error && error instanceof Error) {
80+
export const getErrorFromApiResponse = (error: unknown): ErrorResponse => {
81+
if (error instanceof Error) {
8282
try {
8383
return JSON.parse(error.message) as ErrorResponse;
8484
} catch {
@@ -90,14 +90,14 @@ export const getErrorFromApiResponse = (error: Error): ErrorResponse => {
9090

9191
/**
9292
* Formats an error for display in a toast notification.
93-
* @param error - The Error object to format
93+
* @param error - The error to format (any value; non-Error inputs use the default message)
9494
* @param defaultMessage - The default message to use if the error does not have a specific message
9595
* @returns Formatted error message string
9696
* @example
9797
* const message = formatErrorForToast(error, "An unexpected error occurred.");
9898
*/
9999
export const formatErrorForToast = (
100-
error: Error,
100+
error: unknown,
101101
defaultMessage: string,
102102
): string => {
103103
const parsed = getErrorFromApiResponse(error);

src/components/Containers.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ export const PageContainer = styled.div<PageContainerProps>`
3434
3535
padding: 0;
3636
`;
37+
38+
export const CenteredCardContent = styled.div`
39+
display: flex;
40+
align-items: center;
41+
justify-content: center;
42+
min-height: 12rem;
43+
`;

src/components/CopyButton.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Copy } from "lucide-react";
22
import React from "react";
33
import toast from "react-hot-toast";
44

5+
import { formatErrorForToast } from "@/api/utils";
56
import { Button } from "./Button";
67
import Icon from "./Icon";
78
import { ThemeSize } from "./utils";
@@ -23,8 +24,6 @@ export const CopyButton: React.FC<CopyButtonProps> = ({
2324
disabled = false,
2425
...rest
2526
}) => {
26-
27-
2827
const handleClick = async (e: React.MouseEvent) => {
2928
e.stopPropagation();
3029
if (disabled || !$text) return;
@@ -33,8 +32,7 @@ export const CopyButton: React.FC<CopyButtonProps> = ({
3332
await navigator.clipboard.writeText($text);
3433
toast.success("Copied to clipboard");
3534
} catch (err) {
36-
console.error("Copy failed", err);
37-
toast.error("Failed to copy to clipboard");
35+
toast.error(formatErrorForToast(err, "Failed to copy to clipboard"));
3836
}
3937
};
4038

src/components/Form.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const Input = styled.input`
1818
1919
padding: ${({ theme }) => theme.spacing.md} ${({ theme }) => theme.spacing.md};
2020
21-
font: ${({ theme }) => theme.typography.caption.font};
21+
font: ${({ theme }) => theme.typography.body.font};
2222
color: ${({ theme }) => theme.colors.text.primary};
2323
background: ${({ theme }) => theme.colors.background.primary};
2424
@@ -53,16 +53,24 @@ export const Input = styled.input`
5353
const StyledSelect = styled.select`
5454
width: 100%;
5555
box-sizing: border-box;
56+
appearance: none;
57+
-webkit-appearance: none;
5658
5759
border: 1px solid ${({ theme }) => theme.colors.border.medium};
5860
border-radius: ${({ theme }) => theme.radius.md};
5961
60-
padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.md}`};
62+
padding: ${({ theme }) =>
63+
`${theme.spacing.md} ${theme.spacing["2xl"]} ${theme.spacing.md} ${theme.spacing.md}`};
6164
6265
font: ${({ theme }) => theme.typography.body.font};
6366
color: ${({ theme }) => theme.colors.text.primary};
64-
background: ${({ theme }) => theme.colors.background.primary};
65-
line-height: 1.5;
67+
background-color: ${({ theme }) => theme.colors.background.primary};
68+
background-image: ${({ theme }) => {
69+
const color = theme.colors.text.tertiary.replace("#", "%23");
70+
return `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='${color}' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C%2Fsvg%3E")`;
71+
}};
72+
background-repeat: no-repeat;
73+
background-position: right ${({ theme }) => theme.spacing.md} center;
6674
6775
transition: border-color ${({ theme }) => theme.transitions.base};
6876
@@ -80,7 +88,7 @@ const StyledSelect = styled.select`
8088
&:disabled {
8189
opacity: 0.5;
8290
cursor: not-allowed;
83-
background: ${({ theme }) => theme.colors.background.secondary};
91+
background-color: ${({ theme }) => theme.colors.background.secondary};
8492
}
8593
8694
& > option {

src/components/cards/SuspenseCard.tsx

Lines changed: 0 additions & 154 deletions
This file was deleted.

src/components/cards/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
export * from "./Card";
22
export * from "./ExpandableCard";
3-
export * from "./SuspenseCard";

src/pages/main-page/Credits.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from "react";
1+
import React, { useEffect, useRef, useState } from "react";
22

33
import { FormLabel, Link } from "@/components";
44
import {
@@ -7,30 +7,28 @@ import {
77
} from "@/pages/main-page/monitoring-page/ExecutionDetailPage.styles";
88
import { MadeWithLove, PixelHeart } from "./Credits.styles";
99

10+
const TRIGGER = "credits";
11+
1012
/**
1113
* Little fun easter egg that shows credits when the user types "credits".
1214
* It also desappears when the user types anything else.
1315
* I would like to add all the contributosrs here, but for now it's just me :)
1416
*/
1517
export const CreditsEasterEgg: React.FC = () => {
1618
const [showEasterEgg, setShowEasterEgg] = useState(false);
17-
const [keyBuffer, setKeyBuffer] = useState("");
19+
const keyBufferRef = useRef("");
1820

1921
useEffect(() => {
2022
const handleKeyPress = (e: KeyboardEvent) => {
21-
const newBuffer = (keyBuffer + e.key).slice(-7);
22-
setKeyBuffer(newBuffer);
23-
24-
if (newBuffer === "credits") {
25-
setShowEasterEgg(true);
26-
} else if (showEasterEgg) {
27-
setShowEasterEgg(false);
28-
}
23+
keyBufferRef.current = (keyBufferRef.current + e.key).slice(
24+
-TRIGGER.length,
25+
);
26+
setShowEasterEgg(keyBufferRef.current === TRIGGER);
2927
};
3028

3129
window.addEventListener("keydown", handleKeyPress);
3230
return () => window.removeEventListener("keydown", handleKeyPress);
33-
}, [keyBuffer, showEasterEgg]);
31+
}, []);
3432

3533
if (!showEasterEgg) {
3634
return null;

0 commit comments

Comments
 (0)