Skip to content

Commit 95ea7bd

Browse files
Merge pull request #121 from CodeSpace-Academy/Handle-Errors-on-Recipe-Detail-Page-#96
Handle errors on recipe detail page #96
2 parents 4950217 + 532df87 commit 95ea7bd

File tree

3 files changed

+140
-748
lines changed

3 files changed

+140
-748
lines changed

app/pages/recipes/error.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"use client";
2+
3+
import { useEffect } from "react";
4+
import { motion } from "framer-motion";
5+
6+
/**
7+
* @typedef {Object} SpinningGearProps
8+
* @property {string} [className] - Additional CSS classes for the SVG.
9+
*/
10+
11+
/**
12+
* Renders a spinning gear SVG animation.
13+
* @function
14+
* @returns {JSX.Element} The SpinningGear component.
15+
*/
16+
const SpinningGear = () => (
17+
<motion.svg
18+
xmlns="http://www.w3.org/2000/svg"
19+
width="100"
20+
height="100"
21+
viewBox="0 0 24 24"
22+
fill="none"
23+
stroke="currentColor"
24+
strokeWidth="2"
25+
strokeLinecap="round"
26+
strokeLinejoin="round"
27+
animate={{ rotate: 360 }}
28+
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
29+
>
30+
<circle cx="12" cy="12" r="3" />
31+
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" />
32+
</motion.svg>
33+
);
34+
35+
/**
36+
* @typedef {Object} ErrorProps
37+
* @property {Error} error - The error object.
38+
* @property {Function} reset - Function to reset the error state.
39+
*/
40+
41+
/**
42+
* Renders an error page with animation and a reset button.
43+
* @function
44+
* @param {ErrorProps} props - The component props.
45+
* @returns {JSX.Element} The Error component.
46+
*/
47+
export default function Error({ error, reset }) {
48+
/**
49+
* Logs the error to the console when the component mounts or the error changes.
50+
*/
51+
useEffect(() => {
52+
console.error(error);
53+
}, [error]);
54+
55+
return (
56+
<section className="flex items-center h-full p-[1.28rem] text-teal-900">
57+
<div className="container flex flex-col items-center justify-center px-5 mx-auto my-8">
58+
<div className="max-w-md text-center">
59+
<motion.div
60+
initial={{ scale: 0 }}
61+
animate={{ scale: 1 }}
62+
transition={{ duration: 0.5 }}
63+
>
64+
<SpinningGear />
65+
</motion.div>
66+
<motion.h2
67+
className="mb-8 font-extrabold text-9xl text-teal-600"
68+
initial={{ opacity: 0, y: -50 }}
69+
animate={{ opacity: 1, y: 0 }}
70+
transition={{ delay: 0.2, duration: 0.5 }}
71+
>
72+
<span className="sr-only">Error</span>Oops!
73+
</motion.h2>
74+
<motion.p
75+
className="text-2xl font-semibold md:text-3xl"
76+
initial={{ opacity: 0, y: 50 }}
77+
animate={{ opacity: 1, y: 0 }}
78+
transition={{ delay: 0.4, duration: 0.5 }}
79+
>
80+
Something went wrong!
81+
</motion.p>
82+
<motion.p
83+
className="mt-4 mb-8 text-teal-700"
84+
initial={{ opacity: 0 }}
85+
animate={{ opacity: 1 }}
86+
transition={{ delay: 0.6, duration: 0.5 }}
87+
>
88+
Don&apost t worry, try refreshing or return to the homepage.
89+
</motion.p>
90+
<motion.div
91+
className="flex justify-center space-x-4"
92+
initial={{ opacity: 0, y: 50 }}
93+
animate={{ opacity: 1, y: 0 }}
94+
transition={{ delay: 0.8, duration: 0.5 }}
95+
>
96+
<motion.button
97+
onClick={() => reset()}
98+
className="px-8 py-3 font-semibold rounded bg-teal-600 text-teal-50 hover:bg-teal-700 focus:outline-none focus:ring-2 focus:ring-teal-600 focus:ring-opacity-50"
99+
whileHover={{ scale: 1.05 }}
100+
whileTap={{ scale: 0.95 }}
101+
>
102+
Try again
103+
</motion.button>
104+
</motion.div>
105+
</div>
106+
</div>
107+
</section>
108+
);
109+
}

0 commit comments

Comments
 (0)