From 906db999bb7a6b1bc237fff9422524c34fe94ce1 Mon Sep 17 00:00:00 2001 From: Fernando Date: Mon, 14 Apr 2025 11:31:23 -0400 Subject: [PATCH 1/4] replace loading with spinner --- calc-frontend/src/components/Custom/DerivCustomGraph.tsx | 7 +++++-- calc-frontend/src/components/Custom/IntCustomGraph.tsx | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/calc-frontend/src/components/Custom/DerivCustomGraph.tsx b/calc-frontend/src/components/Custom/DerivCustomGraph.tsx index 662881a..a835249 100644 --- a/calc-frontend/src/components/Custom/DerivCustomGraph.tsx +++ b/calc-frontend/src/components/Custom/DerivCustomGraph.tsx @@ -2,6 +2,7 @@ import { useLayoutEffect , useEffect, useState} from "react"; import axios from "axios"; +import { Blocks } from "react-loader-spinner"; function DerivCustomGraph({func, lowerBound, upperBound, handleSave, onAIResponseComplete}) { @@ -91,8 +92,10 @@ function DerivCustomGraph({func, lowerBound, upperBound, handleSave, onAIRespons if(!ready){ return(
- Loading...
- Complex functions may take longer +
) } diff --git a/calc-frontend/src/components/Custom/IntCustomGraph.tsx b/calc-frontend/src/components/Custom/IntCustomGraph.tsx index ae41678..6e3bcb0 100644 --- a/calc-frontend/src/components/Custom/IntCustomGraph.tsx +++ b/calc-frontend/src/components/Custom/IntCustomGraph.tsx @@ -2,6 +2,7 @@ import { useLayoutEffect , useEffect, useState} from "react"; import axios from "axios"; +import { Blocks } from "react-loader-spinner"; function IntCustomGraph({func, lowerBound, upperBound, handleSave, onAIResponseComplete}) { @@ -90,8 +91,10 @@ function IntCustomGraph({func, lowerBound, upperBound, handleSave, onAIResponseC if(!ready){ return(
- Loading...
- Complex functions may take longer +
) } From 504d9b11b3efc127fafb6dede50b30a6e4076801 Mon Sep 17 00:00:00 2001 From: Fernando Date: Mon, 14 Apr 2025 11:42:42 -0400 Subject: [PATCH 2/4] add sonner to app --- calc-frontend/package-lock.json | 22 +++++++++++++++++++++ calc-frontend/package.json | 2 ++ calc-frontend/src/App/App.tsx | 3 +++ calc-frontend/src/__tests__/App.test.tsx | 9 ++++++++- calc-frontend/src/components/ui/sonner.tsx | 23 ++++++++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 calc-frontend/src/components/ui/sonner.tsx diff --git a/calc-frontend/package-lock.json b/calc-frontend/package-lock.json index ee6de35..7c5a677 100644 --- a/calc-frontend/package-lock.json +++ b/calc-frontend/package-lock.json @@ -19,6 +19,7 @@ "clsx": "^2.1.1", "jsdom": "^26.0.0", "lucide-react": "^0.483.0", + "next-themes": "^0.4.6", "npm": "^11.1.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -28,6 +29,7 @@ "react-router": "^7.1.5", "react-select": "^5.10.1", "rehype-raw": "^7.0.0", + "sonner": "^2.0.3", "tailwind-merge": "^3.2.0", "tailwindcss": "^4.0.4", "tw-animate-css": "^1.2.5" @@ -6384,6 +6386,16 @@ "dev": true, "license": "MIT" }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -9777,6 +9789,16 @@ "node": ">=6" } }, + "node_modules/sonner": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.3.tgz", + "integrity": "sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", diff --git a/calc-frontend/package.json b/calc-frontend/package.json index ca2da0c..b45c9be 100644 --- a/calc-frontend/package.json +++ b/calc-frontend/package.json @@ -22,6 +22,7 @@ "clsx": "^2.1.1", "jsdom": "^26.0.0", "lucide-react": "^0.483.0", + "next-themes": "^0.4.6", "npm": "^11.1.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -31,6 +32,7 @@ "react-router": "^7.1.5", "react-select": "^5.10.1", "rehype-raw": "^7.0.0", + "sonner": "^2.0.3", "tailwind-merge": "^3.2.0", "tailwindcss": "^4.0.4", "tw-animate-css": "^1.2.5" diff --git a/calc-frontend/src/App/App.tsx b/calc-frontend/src/App/App.tsx index c6e6553..35dab8a 100644 --- a/calc-frontend/src/App/App.tsx +++ b/calc-frontend/src/App/App.tsx @@ -7,6 +7,8 @@ import './widgets.css' import RoutesList from "./RoutesList"; import { AuthProvider } from "./AuthContext"; +import { Toaster } from "@/components/ui/sonner"; + function App() { // go to the RootLayout component to edit the visual layout @@ -18,6 +20,7 @@ function App() { return ( + ) diff --git a/calc-frontend/src/__tests__/App.test.tsx b/calc-frontend/src/__tests__/App.test.tsx index ae407e4..035d7b2 100644 --- a/calc-frontend/src/__tests__/App.test.tsx +++ b/calc-frontend/src/__tests__/App.test.tsx @@ -4,6 +4,7 @@ import { createMemoryRouter, createRoutesFromElements, RouterProvider } from 're import { AuthProvider } from '../App/AuthContext' import RoutesList from '../App/RoutesList' +import { Toaster } from '@/components/ui/sonner' test('full app rendering', () => { @@ -11,7 +12,13 @@ test('full app rendering', () => { initialEntries:['/error'], }) - render(, {}) + render( + + + + , + {} + ); // check if heading is visible const heading = screen.getByRole('link', {name: 'Calc Visualizer'}) diff --git a/calc-frontend/src/components/ui/sonner.tsx b/calc-frontend/src/components/ui/sonner.tsx new file mode 100644 index 0000000..cd62aff --- /dev/null +++ b/calc-frontend/src/components/ui/sonner.tsx @@ -0,0 +1,23 @@ +import { useTheme } from "next-themes" +import { Toaster as Sonner, ToasterProps } from "sonner" + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = "system" } = useTheme() + + return ( + + ) +} + +export { Toaster } From 5fe722eb27c010c0d6db23f54cecdf8add2e64c8 Mon Sep 17 00:00:00 2001 From: Fernando Date: Mon, 14 Apr 2025 11:59:41 -0400 Subject: [PATCH 3/4] add sonners for custom graphs --- calc-frontend/src/pages/CustomDerivative.tsx | 3 +++ calc-frontend/src/pages/CustomIntegral.tsx | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/calc-frontend/src/pages/CustomDerivative.tsx b/calc-frontend/src/pages/CustomDerivative.tsx index a48832c..23323de 100644 --- a/calc-frontend/src/pages/CustomDerivative.tsx +++ b/calc-frontend/src/pages/CustomDerivative.tsx @@ -7,6 +7,7 @@ import { Session } from "../lib/auth-client.ts"; import axios from "axios"; import SaveFunctionButton from "../components/ui/SaveFunctionButton.tsx"; import AskAIButtonDerivative from "@/components/ui/AskAIButtonDerivative.tsx"; +import { toast } from "sonner"; function CustomDeriv() { @@ -80,8 +81,10 @@ function CustomDeriv() { Authorization: `Bearer ${session.session.token}` } }) + toast.success("Function Saved Successfully!"); } catch (error) { + toast.error("Function Failed to Save"); console.error("save function error: ",error); } finally{ diff --git a/calc-frontend/src/pages/CustomIntegral.tsx b/calc-frontend/src/pages/CustomIntegral.tsx index e0f7c9c..c18531c 100644 --- a/calc-frontend/src/pages/CustomIntegral.tsx +++ b/calc-frontend/src/pages/CustomIntegral.tsx @@ -8,6 +8,8 @@ import axios from "axios"; import SaveFunctionButton from "../components/ui/SaveFunctionButton.tsx"; import AskAIButton from "../components/ui/AskAIButtonIntegral.tsx"; +import { toast } from "sonner"; + function CustomInt() { const location = useLocation() @@ -80,9 +82,11 @@ function CustomInt() { Authorization: `Bearer ${session.session.token}` } }) - + + toast.success("Function Saved Successfully!"); } catch (error) { + toast.error("Function Failed to Save"); console.error("save function error: ",error); } finally{ From ac77dc1a88d13771e717ec68f7f704d718a2c081 Mon Sep 17 00:00:00 2001 From: Fernando Date: Mon, 14 Apr 2025 12:07:40 -0400 Subject: [PATCH 4/4] add sonners for errors --- .../src/components/ui/FunctionCard.tsx | 93 +++++++++++-------- .../src/components/ui/SignOutButton.tsx | 4 +- 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/calc-frontend/src/components/ui/FunctionCard.tsx b/calc-frontend/src/components/ui/FunctionCard.tsx index 527ed43..8b57ed3 100644 --- a/calc-frontend/src/components/ui/FunctionCard.tsx +++ b/calc-frontend/src/components/ui/FunctionCard.tsx @@ -1,52 +1,71 @@ import axios from "axios"; import { useNavigate } from "react-router"; +import { toast } from "sonner"; interface FunctionCardProps { - topic: string; - equation: string; - lowerBound: number; - upperBound: number; - id: string; - onDelete: (id: string) => void; + topic: string; + equation: string; + lowerBound: number; + upperBound: number; + id: string; + onDelete: (id: string) => void; } -function FunctionCard({topic, equation, lowerBound, upperBound, id, onDelete}: FunctionCardProps) { +function FunctionCard({ + topic, + equation, + lowerBound, + upperBound, + id, + onDelete, +}: FunctionCardProps) { + const navigate = useNavigate(); - const navigate = useNavigate() + const handleView = async () => { + navigate(`/${topic}s/custom`, { + state: { func: equation, bounds: [lowerBound, upperBound] }, + }); + }; - const handleView = async () => { - - navigate(`/${topic}s/custom`, {state: {func: equation, bounds: [lowerBound, upperBound]}} ) - } - - const handleDelete = async () => { + const handleDelete = async () => { + const serverUrl = + import.meta.env.VITE_SERVER_URL || "http://localhost:3000"; - const serverUrl = import.meta.env.VITE_SERVER_URL || 'http://localhost:3000' - - try { - await axios.delete(`${serverUrl}/func/delete/${id}`); - onDelete(id); - } catch (error) { - console.error(`Delete function error: ${error}`) - } + try { + await axios.delete(`${serverUrl}/func/delete/${id}`); + onDelete(id); + } catch (error) { + toast.error("Something went wrong deleting the function"); + console.error(`Delete function error: ${error}`); } + }; - return ( + return (
-

{equation}

- {topic -
- - -
+

{equation}

+ {topic +
+ + +
- ) + ); } -export default FunctionCard; \ No newline at end of file +export default FunctionCard; diff --git a/calc-frontend/src/components/ui/SignOutButton.tsx b/calc-frontend/src/components/ui/SignOutButton.tsx index f3405c2..91e9376 100644 --- a/calc-frontend/src/components/ui/SignOutButton.tsx +++ b/calc-frontend/src/components/ui/SignOutButton.tsx @@ -1,3 +1,4 @@ +import { toast } from "sonner"; import { authClient } from "../../lib/auth-client" function SignOutButton() @@ -7,7 +8,8 @@ function SignOutButton() await authClient.signOut(); } catch (error) { - console.error("Error signing out: ", error); + toast.error("Something went wrong signing out"); + console.error("Error signing out:", error); } }