Skip to content

Commit 0bdb298

Browse files
committed
Merge branch 'Dev' into admin-shop-sales
2 parents 7609fe3 + 8474c2d commit 0bdb298

31 files changed

+2445
-1831
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"dependencies": {
2121
"@emailjs/browser": "^3.11.0",
22-
"@headlessui/react": "^1.7.15",
22+
"@headlessui/react": "^2.1.2",
2323
"@hookstate/core": "^4.0.1",
2424
"@tanstack/react-query": "^5.22.2",
2525
"@tanstack/react-query-devtools": "^5.24.0",

src/components/FAQ.jsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,24 @@
22
import { FaChevronDown, FaChevronUp } from "react-icons/fa";
33
import { useState } from "react";
44

5-
import { questions } from "../pages/landingPage/data";
6-
7-
function FAQ() {
5+
function FAQ({ questions }) {
86
const [activeQuestion, setActiveQuestion] = useState(null);
97

108
const toggleQuestion = (index) => {
119
setActiveQuestion(activeQuestion === index ? null : index);
1210
};
1311

1412
return (
15-
<div className="flex-col justify-center items-center gap-4 w-full max-w-6xl">
13+
<div className="flex-col justify-center items-center gap-4 w-full max-w-6xl mx-auto">
1614
{questions.map((question, index) => (
1715
<div
1816
key={question.id}
19-
className={`rounded-xl bg-white ${
20-
activeQuestion === index && "mb-4"
21-
}`}
17+
className={`rounded-xl bg-white border shadow-sm mb-4 p-4 `}
2218
>
2319
<h2 className="mb-4 font-semibold" id={`flush-heading${index + 1}`}>
2420
<button
2521
aria-label={question.question}
26-
className={`group relative flex w-full items-center rounded-none border-0 py-4 px-5 text-left text-base transition ${
22+
className={`group relative flex w-full items-center rounded-none border-0 text-left text-base transition ${
2723
activeQuestion === index
2824
? ""
2925
: "overflow-anchor:none hover:z-[2] focus:z-[3]"
@@ -63,7 +59,7 @@ function FAQ() {
6359
aria-labelledby={`flush-heading${index + 1}`}
6460
data-te-parent="#accordionFlushExample"
6561
>
66-
<div className="py-4 px-5">{question.answer}</div>
62+
<div className=" ">{question.answer}</div>
6763
</div>
6864
</div>
6965
))}

src/components/Header.jsx

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { LazyLoadImage } from "react-lazy-load-image-component";
55
import { Link, useLocation } from "react-router-dom";
66

77
import logo from "../assets/images/sytLogo.png";
8+
import CartIcon from "./shop/CartIcon";
89

910
const navLinks = [
1011
{
@@ -37,11 +38,11 @@ const navLinks = [
3738
link: "Resources",
3839
route: "/resources",
3940
},
40-
// {
41-
// id: 7,
42-
// link: "Shop",
43-
// route: "/shop",
44-
// },
41+
{
42+
id: 7,
43+
link: "Shop",
44+
route: "/shop",
45+
},
4546
// {
4647
// id: 8,
4748
// link: "Donate",
@@ -63,30 +64,38 @@ function Header() {
6364
</Link>
6465

6566
{/* mobile menu */}
66-
{showNavlinks ? (
67-
<button
68-
type="button"
69-
aria-label="Close menu"
70-
className="md:hidden"
71-
onClick={() => setShowNavlinks(false)}
72-
>
73-
<AiOutlineClose className="h-6 w-6 text-white" aria-hidden="true" />{" "}
74-
{/* Close Icon */}
75-
</button>
76-
) : (
77-
<button
78-
type="button"
79-
aria-label="Open menu"
80-
className="md:hidden"
81-
onClick={() => setShowNavlinks(true)}
82-
>
83-
<HiOutlineMenuAlt4
84-
className="h-6 w-6 text-white"
85-
aria-hidden="true"
86-
/>{" "}
87-
{/* Menu Icon */}
88-
</button>
89-
)}
67+
<div className="flex gap-4 items-center">
68+
<div className="flex md:hidden">
69+
<CartIcon />
70+
</div>
71+
{showNavlinks ? (
72+
<button
73+
type="button"
74+
aria-label="Close menu"
75+
className="md:hidden"
76+
onClick={() => setShowNavlinks(false)}
77+
>
78+
<AiOutlineClose
79+
className="h-6 w-6 text-white"
80+
aria-hidden="true"
81+
/>{" "}
82+
{/* Close Icon */}
83+
</button>
84+
) : (
85+
<button
86+
type="button"
87+
aria-label="Open menu"
88+
className="md:hidden"
89+
onClick={() => setShowNavlinks(true)}
90+
>
91+
<HiOutlineMenuAlt4
92+
className="h-6 w-6 text-white"
93+
aria-hidden="true"
94+
/>{" "}
95+
{/* Menu Icon */}
96+
</button>
97+
)}
98+
</div>
9099

91100
{/* mobile navlinks */}
92101
<nav

src/components/shop/CartDrawer.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ function CartDrawer({ open, setOpen }) {
117117
navigate("/shop/checkout");
118118
// }
119119
};
120-
console.log("cartProducts: ", cartProducts);
120+
121+
// query cart products
122+
// console.log("cartProducts: ", cartProducts);
121123

122124
return (
123125
<Transition.Root show={open} as={Fragment}>

src/components/shop/CartIcon.jsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { MdAddShoppingCart } from "react-icons/md";
2+
import SectionWrapper from "./SectionWrapper";
3+
4+
const CartIcon = () => {
5+
return (
6+
<SectionWrapper>
7+
<div className="flex justify-end ">
8+
<div className="w-12 md:w-16 h-12 md:h-16 rounded-full p-0.5 md:p-1 bg-white border shadow-lg cursor-pointer">
9+
<div className="flex w-full h-full p-1.5 md:p-2 rounded-full justify-center items-center bg-green-dark">
10+
<MdAddShoppingCart color="white" className="h-full w-full" />
11+
</div>
12+
</div>
13+
</div>
14+
</SectionWrapper>
15+
);
16+
};
17+
export default CartIcon;

src/components/shop/ProductCard.jsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { addCommaSeparator, categoryColors, cn } from "@/utilities/utils";
2+
import { CiShoppingTag } from "react-icons/ci";
3+
import { MdAddShoppingCart } from "react-icons/md";
4+
import { LazyLoadImage } from "react-lazy-load-image-component";
5+
import { Link } from "react-router-dom";
6+
7+
const ProductCard = ({ product }) => {
8+
const { backgroundColor, color } = categoryColors(product.category);
9+
10+
return (
11+
<div className="border rounded-lg p-2.5 pr-1.5 shadow-sm group hover:bg-green-dark/10 bg-white flex flex-col gap-4 ">
12+
<Link
13+
to={`/shop/item/${product.id}`}
14+
className="aspect-h-1 aspect-w-1 w-full bg-gray-200 lg:aspect-none group-hover:opacity-75 lg:h-96"
15+
>
16+
<LazyLoadImage
17+
src={product.image}
18+
alt="Product image"
19+
className="w-full h-80 object-cover object-center lg:h-full lg:w-full"
20+
/>
21+
</Link>
22+
<Link
23+
to={`/shop/item/${product.id}`}
24+
className="flex justify-between pr-1"
25+
>
26+
<h3 className="text-md uppercase font-bold text-gray-600">
27+
{product.name}
28+
</h3>
29+
<div className="p-1 rounded-xl bg-green-dark/10">
30+
{product.stock > 0 ? (
31+
<p className="text-green-dark font-medium text-sm px-1">
32+
<span> {product.stock}</span>
33+
<span className="ml-2">items left</span>
34+
</p>
35+
) : (
36+
<div className=" text-red-800 p-1 rounded-lg bg-red-800/20 font-bold text-base">
37+
<p>Out of stock</p>
38+
</div>
39+
)}
40+
</div>
41+
</Link>
42+
<div className="flex justify-start w-full">
43+
<div
44+
style={{ backgroundColor, color }}
45+
className="px-2 rounded-2xl flex gap-2 items-center"
46+
>
47+
<CiShoppingTag size={28} />
48+
<p className="font-medium text-sm">{product.category}</p>
49+
</div>
50+
</div>
51+
<div className="flex justify-between pr-1">
52+
<h3 className="text-lg font-bold text-gray-700">
53+
KES {addCommaSeparator(Number(product.price))}
54+
</h3>
55+
<div className="flex text-green-dark gap-2 items-center md:opacity-0 md:group-hover:opacity-100 transition-opacity cursor-pointer">
56+
<MdAddShoppingCart size={20} />
57+
<p className="font-bold text-base">Add to cart</p>
58+
</div>
59+
</div>
60+
</div>
61+
);
62+
};
63+
export default ProductCard;

src/components/shop/SearchInput.jsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useState } from "react";
2+
import { IoMdSearch } from "react-icons/io";
3+
import { useNavigate } from "react-router-dom";
4+
5+
const SearchInput = () => {
6+
const [searchText, setSearchText] = useState("");
7+
const navigate = useNavigate();
8+
9+
function handleSubmit(e) {
10+
e.preventDefault();
11+
navigate(`/shop/items?search=${searchText}`);
12+
}
13+
14+
return (
15+
<form
16+
onSubmit={handleSubmit}
17+
className="flex justify-between w-full relative "
18+
>
19+
<input
20+
type="text"
21+
placeholder="Search item"
22+
className="rounded-l-lg pl-16 text-sm shadow-sm w-full border outline-none py-3 text-gray-600 "
23+
value={searchText}
24+
onChange={(e) => setSearchText(e.target.value)}
25+
/>
26+
<IoMdSearch className="absolute top-3 left-8 text-gray-400 " size={24} />
27+
<button
28+
type="submit"
29+
className="text-white hidden md:block text-sm bg-gradient-to-b to-primary from-green-dark py-2 px-4 md:px-20 rounded-r-lg"
30+
>
31+
Search
32+
</button>
33+
</form>
34+
);
35+
};
36+
export default SearchInput;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const SectionWrapper = ({ children }) => {
2+
return <div className="px-4 md:px-10 lg:px-20 md:my-4">{children}</div>;
3+
};
4+
export default SectionWrapper;

src/components/shop/SortItems.jsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { IoFilter } from "react-icons/io5";
2+
import { Menu } from "@headlessui/react";
3+
import { Link, useLocation } from "react-router-dom";
4+
5+
const SortItems = () => {
6+
const { pathname } = useLocation();
7+
const path = pathname.includes("category") ? pathname : "/shop/items";
8+
9+
return (
10+
<div className="flex flex-col gap-4 relative h-full">
11+
<Menu>
12+
<Menu.Button className="rounded-lg border shadow-sm py-2 px-4 flex items-center gap-2">
13+
<IoFilter size={30} className="text-gray-400" />
14+
<p className="text-sm hidden md:block text-gray-500"> Sort</p>
15+
</Menu.Button>
16+
<Menu.Items
17+
anchor="bottom"
18+
className="absolute top-10 z-10 right-0 w-48 bg-white py-2 px-4 rounded-md flex flex-col gap-2 border shadow-sm"
19+
>
20+
<Menu.Item>
21+
<Link
22+
to={`${path}?sort=low`}
23+
className="text-sm p-2 text-gray-500 cursor-pointer hover:text-green-dark"
24+
>
25+
<p>Lowest price first</p>
26+
</Link>
27+
</Menu.Item>
28+
<Menu.Item>
29+
<Link
30+
to={`${path}?sort=high`}
31+
className="text-sm p-2 text-gray-500 cursor-pointer hover:text-green-dark"
32+
>
33+
<p>Highest price first</p>
34+
</Link>
35+
</Menu.Item>
36+
</Menu.Items>
37+
</Menu>
38+
</div>
39+
);
40+
};
41+
export default SortItems;

src/hooks/Queries/shop/useSwagList.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ const useSingleSwag = (id) =>
3838
refetchOnWindowFocus: false,
3939
});
4040

41-
export { useSwagList, useSingleSwag };
41+
export { useSwagList, useSingleSwag };

0 commit comments

Comments
 (0)