Skip to content

Commit d03f1a1

Browse files
committed
framer motion page transitions
1 parent cf8ffcc commit d03f1a1

File tree

12 files changed

+240
-64
lines changed

12 files changed

+240
-64
lines changed

client/src/App.js

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React, { useEffect } from "react";
2-
import { Routes, Route } from "react-router-dom";
2+
import { Routes, Route, useLocation } from "react-router-dom";
33
import { useDispatch, useSelector } from "react-redux";
44
import { getProducts } from "./store/actions/products-actions";
5+
import { AnimatePresence } from "framer-motion";
56

67
import Home from './pages/Home';
78
import About from './pages/About';
@@ -27,8 +28,11 @@ import HomeRedirect from "./components/auth/HomeRedirect";
2728

2829

2930

31+
32+
3033
const App = () => {
3134
const dispatch = useDispatch();
35+
const location = useLocation();
3236
const isAdmin = useSelector((state) => state.auth.isAdmin);
3337
// const products = useSelector((state) => state.products.products);
3438

@@ -40,37 +44,43 @@ const App = () => {
4044
return (
4145
<>
4246
{!isAdmin && <MainNavigation />}
43-
<Routes>
44-
<Route element={<HomeRedirect />}>
45-
<Route path="/" element={<Home />} />
46-
<Route path="/about" element={<About />} />
47-
<Route path="/cart" element={<Cart />} />
48-
<Route path="/checkout" element={<Checkout />} />
49-
<Route path="/products" element={<Products />} />
50-
<Route path="/products/:productId" element={<ProductDetail />} />
51-
</Route>
52-
53-
<Route element={<LoginRedirect />}>
54-
<Route path="/login" element={<Login />} />
55-
</Route>
56-
57-
<Route element={<RegisterRedirect />}>
58-
<Route path="/register" element={<Register />} />
59-
</Route>
60-
61-
<Route element={<DashboardRedirect />}>
62-
<Route path="admin/dashboard" element={<Dashboard />}>
63-
<Route path="products" element={<TheProducts />} />
64-
<Route path="addproduct" element={<AddProduct />} />
65-
<Route path="updateproducts">
66-
<Route index element={<UpdateProducts />} />
67-
<Route path=":productId" element={<ProductUpdate />} />
47+
<AnimatePresence exitBeforeEnter >
48+
49+
<Routes location={location} key={location.pathname}>
50+
51+
<Route element={<HomeRedirect />}>
52+
<Route path="/" element={<Home />} />
53+
<Route path="/about" element={<About />} />
54+
<Route path="/cart" element={<Cart />} />
55+
<Route path="/checkout" element={<Checkout />} />
56+
<Route path="/products" element={<Products />} />
57+
<Route path="/products/:productId" element={<ProductDetail />} />
58+
</Route>
59+
60+
<Route element={<LoginRedirect />}>
61+
<Route path="/login" element={<Login />} />
62+
</Route>
63+
64+
<Route element={<RegisterRedirect />}>
65+
<Route path="/register" element={<Register />} />
66+
</Route>
67+
68+
<Route element={<DashboardRedirect />}>
69+
<Route path="admin/dashboard" element={<Dashboard />}>
70+
<Route path="products" element={<TheProducts />} />
71+
<Route path="addproduct" element={<AddProduct />} />
72+
<Route path="updateproducts">
73+
<Route index element={<UpdateProducts />} />
74+
<Route path=":productId" element={<ProductUpdate />} />
75+
</Route>
6876
</Route>
6977
</Route>
70-
</Route>
7178

72-
<Route path="*" element={<NotFound />} />
73-
</Routes>
79+
<Route path="*" element={<NotFound />} />
80+
81+
</Routes>
82+
83+
</AnimatePresence>
7484
{!isAdmin && <Footer />}
7585
</>
7686
);

client/src/pages/About.jsx

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,46 @@ import PageHero from '../layout/PageHero';
55
import { ABOUT_IMG_URL } from '../utils/constants';
66

77

8+
const containerVariants = {
9+
hidden: {
10+
opacity: 0
11+
},
12+
visible: {
13+
opacity: 1,
14+
transition: { duration: .3 }
15+
},
16+
exit: {
17+
x: '-100vw',
18+
transition: { ease: 'easeInOut' }
19+
}
20+
};
21+
22+
const underlineAnimate = {
23+
hidden: {
24+
opacity: 0,
25+
pathLength: 0,
26+
},
27+
visible: {
28+
opacity: 1,
29+
pathLength: 1,
30+
transition: {
31+
delay: 1,
32+
duration: .8,
33+
},
34+
},
35+
};
36+
37+
838
const About = () => {
939

10-
const underlineAnimate = {
11-
hidden: {
12-
opacity: 0,
13-
pathLength: 0,
14-
},
15-
visible: {
16-
opacity: 1,
17-
pathLength: 1,
18-
transition: {
19-
delay: 1,
20-
duration: .8,
21-
},
22-
},
23-
};
2440

2541
return (
26-
<main>
42+
<motion.main
43+
variants={containerVariants}
44+
initial="hidden"
45+
animate="visible"
46+
exit="exit"
47+
>
2748
<PageHero title="about" />
2849
<div className='w-full py-32'>
2950
<div className='w-[85vw] flex mx-auto'>
@@ -75,7 +96,7 @@ const About = () => {
7596
</div>
7697
</div>
7798
</div>
78-
</main>
99+
</motion.main>
79100
);
80101
};
81102

client/src/pages/Cart.jsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,44 @@
11
import React from 'react';
22
import { useSelector } from 'react-redux';
3+
import { motion } from 'framer-motion';
34

45
import PageHero from '../layout/PageHero';
56
import CartContent from '../components/cart/CartContent';
67
import CartEmpty from '../components/cart/CartEmpty';
78

89

10+
const containerVariants = {
11+
hidden: {
12+
opacity: 0
13+
},
14+
visible: {
15+
opacity: 1,
16+
transition: { duration: .3 }
17+
},
18+
exit: {
19+
x: '-100vw',
20+
transition: { ease: 'easeInOut' }
21+
}
22+
};
23+
24+
925
const Cart = () => {
1026
const cart = useSelector((state) => state.cart.items);
1127
const totalPrice = useSelector((state) => state.cart.totalPrice);
1228

1329
return (
14-
<div>
30+
<motion.div
31+
variants={containerVariants}
32+
initial="hidden"
33+
animate="visible"
34+
exit="exit"
35+
>
1536
<PageHero title='cart' />
1637
<div className='w-[90%] mx-auto'>
1738
{cart.length < 1 && <CartEmpty />}
1839
{cart.length > 0 && <CartContent cart={cart} totalPrice={totalPrice} />}
1940
</div>
20-
</div>
41+
</motion.div>
2142
);
2243
};
2344

client/src/pages/Checkout.jsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,45 @@
11
import React from "react";
22
import { useSelector } from "react-redux";
3+
import { motion } from 'framer-motion';
34

45
import PageHero from "../layout/PageHero";
56
import CheckoutContent from "../components/cart/CheckoutContent";
67
import CartEmpty from '../components/cart/CartEmpty';
78

89

10+
const containerVariants = {
11+
hidden: {
12+
opacity: 0
13+
},
14+
visible: {
15+
opacity: 1,
16+
transition: { duration: .3 }
17+
},
18+
exit: {
19+
x: '-100vw',
20+
transition: { ease: 'easeInOut' }
21+
}
22+
}
23+
24+
925
const Checkout = () => {
1026
const totalPrice = useSelector((state) => state.cart.totalPrice);
1127
const cart = useSelector((state) => state.cart.items);
1228
const { name } = useSelector((state) => state.auth.user);
1329

1430
return (
15-
<div>
31+
<motion.div
32+
variants={containerVariants}
33+
initial="hidden"
34+
animate="visible"
35+
exit="exit"
36+
>
1637
<PageHero title='checkout' />
1738
<div className="w-[80%] mx-auto mb-40 mt-24">
1839
{cart.length < 1 && <CartEmpty />}
1940
{cart.length > 0 && <CheckoutContent totalPrice={totalPrice} name={name} />}
2041
</div>
21-
</div>
42+
</motion.div>
2243
);
2344
};
2445

client/src/pages/Home.jsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,43 @@
11
import React from 'react';
22

3+
import { motion } from 'framer-motion';
4+
35
import Hero from "../components/home/Hero";
46
import Overview from '../components/home/Overview';
57
import FeaturedProducts from '../components/home/FeaturedProducts';
68
import TheServices from '../components/home/TheServices';
79
import TheContact from '../components/home/TheContact';
810

911

12+
const containerVariants = {
13+
hidden: {
14+
opacity: 0
15+
},
16+
visible: {
17+
opacity: 1,
18+
transition: { duration: .3 }
19+
},
20+
exit: {
21+
x: '-100vw',
22+
transition: { ease: 'easeInOut' }
23+
}
24+
}
25+
1026

1127
const Home = () => {
1228
return (
13-
<main>
29+
<motion.main
30+
variants={containerVariants}
31+
initial="hidden"
32+
animate="visible"
33+
exit="exit"
34+
>
1435
<Hero />
1536
<Overview />
1637
<FeaturedProducts />
1738
<TheServices />
1839
<TheContact />
19-
</main>
40+
</motion.main>
2041
);
2142
};
2243

client/src/pages/Login.jsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import { useFormik } from "formik";
33
import * as Yup from "yup";
4+
import { motion } from 'framer-motion';
45

56
import { MdEmail } from "react-icons/md";
67
import { FiLogIn } from 'react-icons/fi'
@@ -12,6 +13,22 @@ import TheSpinner from "../layout/TheSpinner";
1213

1314

1415

16+
const containerVariants = {
17+
hidden: {
18+
opacity: 0
19+
},
20+
visible: {
21+
opacity: 1,
22+
transition: { duration: .3 }
23+
},
24+
exit: {
25+
x: '-100vw',
26+
transition: { ease: 'easeInOut' }
27+
}
28+
};
29+
30+
31+
1532

1633
const Login = () => {
1734
const dispatch = useDispatch();
@@ -38,7 +55,12 @@ const Login = () => {
3855
});
3956

4057
return (
41-
<div className="w-[80%] mx-auto mt-40 mb-52">
58+
<motion.div className="w-[80%] mx-auto mt-40 mb-52"
59+
variants={containerVariants}
60+
initial="hidden"
61+
animate="visible"
62+
exit="exit"
63+
>
4264
<div className="w-[320px] sm:w-[400px] rounded shadow-xl border-2 border-solid px-4 sm:px-8 py-20 mx-auto">
4365
<h2 className="text-3xl uppercase tracking-wider font-bold text-center mb-12 select-none">
4466
<span className="text-primary">tech</span>
@@ -106,7 +128,7 @@ const Login = () => {
106128
}
107129
<p className="text-center mt-6">Not registered? <Link to='/register' className="text-primary">Create an account</Link> </p>
108130
</div>
109-
</div>
131+
</motion.div>
110132
);
111133
};
112134

0 commit comments

Comments
 (0)