Skip to content

Commit

Permalink
Merge branch 'Dev' into CodedVeli/issue238
Browse files Browse the repository at this point in the history
  • Loading branch information
sonylomo authored Nov 12, 2024
2 parents a582795 + 7229bb6 commit 1096811
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 25 deletions.
7 changes: 6 additions & 1 deletion src/components/Caroussel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ function Caroussel({ CarousselData }) {
};

return (
<section className="pt-4 sm:pt-16 pb-10 mx-auto w-full max-w-screen-2xl">
<section
className="pt-4 sm:pt-16 pb-10 mx-auto w-full max-w-screen-2xl"
data-testid="carousel"
>
<div
ref={carouselRef}
className="py-6 grid grid-cols-1 md:grid-cols-2 gap-8 overflow-x-auto scrollbar-hide"
Expand Down Expand Up @@ -74,13 +77,15 @@ function Caroussel({ CarousselData }) {
type="button"
aria-label="back button"
onClick={() => scroll(-400)}
data-testid="previous"
>
<PiArrowCircleLeft className="text-green-header size-16" />
</button>
<button
type="button"
aria-label="forward button"
onClick={() => scroll(400)}
data-testid="next"
>
<PiArrowCircleRight className="text-green-header size-16" />
</button>
Expand Down
16 changes: 9 additions & 7 deletions src/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ function Header() {
{/* mobile menu */}
<div className="flex gap-4 items-center">
<div className="flex md:hidden">
<button
type="button"
aria-label="open cart"
onClick={() => setOpen(true)}
>
<CartIcon />
</button>
{pathname === "/shop" && (
<button
type="button"
aria-label="open cart"
onClick={() => setOpen(true)}
>
<CartIcon />
</button>
)}
</div>
{showNavlinks ? (
<button
Expand Down
10 changes: 9 additions & 1 deletion src/components/shop/CartDrawer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { LazyLoadImage } from "react-lazy-load-image-component";
import { Link, useNavigate } from "react-router-dom";
import { useDeleteSwag } from "../../hooks/Mutations/shop/useCartSwagg";
import formatPrice from "../../utilities/formatPrice";
import { categoryColors } from "../../utilities/utils";

function CartDrawer({ open, setOpen }) {
const navigate = useNavigate();
Expand Down Expand Up @@ -64,6 +65,8 @@ function CartDrawer({ open, setOpen }) {
const handleDeleteSwag = (cartItemId) => {
removeSwagFromCart(cartItemId);
deleteFromLocalStorage(cartItemId);
// dispatch custom event to notify cart change
window.dispatchEvent(new Event("swagListUpdated"));
};

const handleCheckout = () => {
Expand Down Expand Up @@ -148,7 +151,12 @@ function CartDrawer({ open, setOpen }) {
<div className="flex flex-row justify-between items-center mb-4">
<div className="flex flex-col space-y-2 justify-start">
<div className="flex justify-between">
<p className="flex justify-between items-center gap-1 font-medium bg-[#FEF3F2] text-[#B42318] text-sm rounded-full px-2 py-1">
<p
style={categoryColors(
cartProduct.category
)}
className="flex justify-between items-center gap-1 font-medium bg-[#FEF3F2] text-[#B42318] text-sm rounded-full px-2 py-1"
>
<CiShoppingTag />
{cartProduct.category}
</p>
Expand Down
33 changes: 32 additions & 1 deletion src/components/shop/CartIcon.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
import { useEffect, useState } from "react";
import { MdAddShoppingCart } from "react-icons/md";
import SectionWrapper from "./SectionWrapper";

function CartIcon() {
const [cartProducts, setCartProducts] = useState(() => {
// Initialize state with the value from localStorage if it exists
const storedProducts = localStorage.getItem("swagList");
return storedProducts ? JSON.parse(storedProducts) : [];
});

useEffect(() => {
// Event listener for storage changes in other tabs/windows
const handleStorageChange = () => {
const storedProducts = localStorage.getItem("swagList");
setCartProducts(storedProducts ? JSON.parse(storedProducts) : []);
};

// Listen for "storage" events, whenever swagList is updated from another tab
window.addEventListener("storage", handleStorageChange);
// Listen for custom swagListUpdated events, fired whenever swagList is updated
window.addEventListener("swagListUpdated", handleStorageChange);

// Cleanup event listeners on unmount
return () => {
window.removeEventListener("storage", handleStorageChange);
window.removeEventListener("swagListUpdated", handleStorageChange);
};
}, []);

return (
<SectionWrapper>
<div className="flex justify-end ">
<div className="flex justify-end relative">
<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">
<div className="flex w-full h-full p-1.5 md:p-2 rounded-full justify-center items-center bg-green-dark">
<MdAddShoppingCart color="white" className="h-full w-full" />
</div>
{cartProducts.length > 0 && (
<div className="absolute bottom-0 right-0 bg-[#B3261E] text-white text-xs font-medium rounded-full w-5 h-5 flex items-center justify-center">
<p>{cartProducts?.length}</p>
</div>
)}
</div>
</div>
</SectionWrapper>
Expand Down
4 changes: 3 additions & 1 deletion src/components/shop/ProductCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ function ProductCard({ product }) {
className="flex justify-between pr-1"
>
<h3 className="text-md uppercase font-medium text-gray-600">
{product.name}
{product.name.length > 15
? `${product.name.slice(0, 18)}...`
: product.name}
</h3>
<div className="p-1 rounded-xl bg-green-dark/10">
{totalStock > 0 ? (
Expand Down
5 changes: 4 additions & 1 deletion src/pages/aboutUs/sections/HeroSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ function HeroSection() {
<div className="px-4 sm:px-14 xl:px-28 sm:m-auto max-w-screen-2xl">
<div className="flex flex-col md:flex-row items-center pt-10 gap-4">
<div className="md:w-1/2">
<h1 className="mb-2 md:text-[40px] leading-tight text-2xl font-medium text-gray-900">
<h1
className="mb-2 md:text-[40px] leading-tight text-2xl font-medium text-gray-900"
data-testid="title"
>
Empowering <span className="text-primary">innovation</span> in the{" "}
<span className="text-primary">African tech space</span>
</h1>
Expand Down
11 changes: 9 additions & 2 deletions src/pages/aboutUs/sections/LeadershipSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ function LeadershipSection() {
<section className="pt-16 sm:pt-0 pb-10 mx-auto w-full max-w-screen-2xl sm:mt-24 px-4 md:px-0">
<div className="mx-auto w-full flex flex-row items-center gap-2 md:gap-4 my-6">
<div className="w-full h-0.5 rounded-sm bg-gray-300" />
<h2 className="min-w-fit text-primary text-sm leading-loose px-4 bg-gradient-to-r from-[#D7F4EB] to-white py-2 rounded-full font-semibold border-2 border-gray-300 uppercase">
<h2
className="min-w-fit text-primary text-sm leading-loose px-4 bg-gradient-to-r from-[#D7F4EB] to-white py-2 rounded-full font-semibold border-2 border-gray-300 uppercase"
data-testid="leadership"
>
Our leadership
</h2>
<div className="w-full h-0.5 bg-gray-300" />
Expand Down Expand Up @@ -119,6 +122,7 @@ function LeadershipSection() {
aria-label="Partner with us"
onClick={openModal}
className="text-white bg-gradient-to-b to-primary from-green-dark border-0 py-3 px-4 md:px-8 focus:outline-none rounded-lg text-sm md:text-base w-fit text-center"
data-testid="partner-with-us"
>
Partner with us
</button>
Expand All @@ -139,7 +143,10 @@ function LeadershipSection() {
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black/25" />
<div
className="fixed inset-0 bg-black/25"
data-testid="partner-popup"
/>
</Transition.Child>

<div className="fixed inset-0 overflow-y-auto">
Expand Down
5 changes: 4 additions & 1 deletion src/pages/aboutUs/sections/MissionVisionSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ function MissionVisionSection() {
<div className="max-w-screen-xl mx-auto mt-24 px-4 md:px-0">
<div className="mx-auto w-full flex flex-row items-center gap-2 md:gap-4 my-8">
<div className="w-full h-0.5 rounded-sm bg-gray-300" />
<h2 className="min-w-fit text-primary text-sm leading-loose px-4 bg-gradient-to-r from-[#D7F4EB] to-white py-2 rounded-full font-semibold border-2 border-gray-300 uppercase">
<h2
className="min-w-fit text-primary text-sm leading-loose px-4 bg-gradient-to-r from-[#D7F4EB] to-white py-2 rounded-full font-semibold border-2 border-gray-300 uppercase"
data-testid="mission"
>
A bit more about us
</h2>
<div className="w-full h-0.5 bg-gray-300" />
Expand Down
7 changes: 6 additions & 1 deletion src/pages/aboutUs/sections/PartnerCTA.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ function PartnerCTA() {
<section className="pt-16 pb-10 mx-auto w-full max-w-screen-2xl">
<div className="flex flex-col sm:flex-row justify-between px-4 sm:px-28">
<div className="space-y-4 mb-8 sm:mb-0">
<h3 className="font-semibold text-md sm:text-xl">Our Reports</h3>
<h3
className="font-semibold text-md sm:text-xl"
data-testid="reports"
>
Our Reports
</h3>
<p>
<a
href={Report}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import PropTypes from "prop-types";
import React from "react";
import formatEventDescription from "../../../../../../utilities/formatEventDescription";

function EventDescription({ eventDesc }) {
return (
<div className="w-full text-center max-w-3xl mx-auto text-sm md:text-[15px] md:leading-[22px] font-normal text-gray-600">
{eventDesc}
<div className="w-full max-w-3xl mx-auto text-sm md:text-[15px] md:leading-[22px] font-normal text-gray-600">
{formatEventDescription(eventDesc)}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ function Hero({ event }) {

const [isOpen, setIsOpen] = useState(false);

// eslint-disable-next-line no-unused-vars
function openModal() {
setIsOpen(true);
}
Expand Down Expand Up @@ -180,17 +181,19 @@ ${isVirtual ? "text-white" : "text-green-header"}
</div>
</div>

<button
type="button"
onClick={openModal}
<a
href={event?.link}
target="_blank"
rel="noreferrer"
// onClick={openModal}
className={`py-2 px-20 rounded-lg ${
isVirtual
? "text-green-header bg-white"
: "text-white bg-gradient-to-b to-primary from-green-dark"
}`}
>
Reserve for Free
</button>
Reserve Tickets
</a>
</div>

<EventRSVP
Expand Down
4 changes: 3 additions & 1 deletion src/pages/shop/SingleItemPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ export default function SingleItemPage() {
});
// Add to local storage
addToLocalStorage();
// dispatch custom event to notify cart change
window.dispatchEvent(new Event("swagListUpdated"));

// open cart
setOpen(true);
Expand Down Expand Up @@ -177,7 +179,7 @@ export default function SingleItemPage() {
key={index}
src={image}
alt={singleSwag.name}
className={`m-auto min-w-full ${selectedImage === index + 1 ? "block" : "hidden"}`}
className={`m-auto rounded-lg min-w-full ${selectedImage === index + 1 ? "block" : "hidden"}`}
/>
))}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/shop/sections/Banner/Carousal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function Carousel() {
From KES {formatPrice(swagList[selectedIndex]?.price)}
</p>
<Link
to={`/shop/item/${isSuccess ? swagList[selectedIndex]?.slug : ""} `}
to={`/shop/item/${isSuccess ? swagList[selectedIndex]?.slug : ""}`}
className="text-white font-bold bg-gradient-to-b to-primary from-green-dark py-3 px-4 mb-2 rounded-md"
>
Shop Now
Expand Down
20 changes: 20 additions & 0 deletions src/utilities/formatEventDescription.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable react/no-array-index-key */
import React from "react";
// .split("\r\n\r\n") Splits by paragraphs
// .split("\r\n") splits by lines
const formatEventDescription = (text) =>
text.split("\r\n\r\n").map((paragraph) => (
<p key={crypto.randomUUID()} className="leading-6 mb-4 whitespace-pre-wrap">
{paragraph.split("\r\n").map((line, i) => (
<React.Fragment key={i}>
{line}
{i < paragraph.split("\r\n").length - 1 && (
// Adds space between lines
<br className="mb-2" />
)}
</React.Fragment>
))}
</p>
));

export default formatEventDescription;
89 changes: 89 additions & 0 deletions tests/pages/About.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { render, screen } from "@testing-library/react";
import { HelmetProvider } from "react-helmet-async";
import { BrowserRouter } from "react-router-dom";
import { describe, expect, it } from "vitest";

import placeholder from "../../src/assets/images/sytLogo.png";
import Caroussel from "../../src/components/Caroussel";
import AboutUs from "../../src/pages/aboutUs/AboutUs";

const LeadershipData = [
{
name: "First User",
title: "Founder",
image: placeholder,
linkedin: {
href: "https://www.linkedin.com/",
username: "First User",
},
twitter: {
href: "https://twitter.com/x",
username: "First User",
},
},
{
name: "Second User",
title: "Dev Relations & Opensource Programs",
image: placeholder,
linkedin: {
href: "https://www.linkedin.com",
username: "Second User",
},
twitter: {
href: "",
username: "",
},
},
{
name: "Third User",
title: "Community Manager",
image: placeholder,
linkedin: {
href: "https://www.linkedin.com",
username: "Third User",
},
twitter: {
href: "",
username: "",
},
},
];

describe("About us page unit tests", () => {
const renderWithRouter = (ui) =>
render(
<HelmetProvider>
<BrowserRouter>{ui}</BrowserRouter>
</HelmetProvider>
);

it("should render Hero Section successfully", () => {
renderWithRouter(<AboutUs />);
const titleElement = screen.getByTestId("title");
expect(titleElement).toBeTruthy();
});

it("should render Mission/Vision Section successfully", () => {
renderWithRouter(<AboutUs />);
const testElement = screen.getByTestId("mission");
expect(testElement).toBeTruthy();
});

it("should render Leadership Section successfully", () => {
renderWithRouter(<AboutUs />);
const testElement = screen.getByTestId("leadership");
expect(testElement).toBeTruthy();
});

it("should render Reports Section successfully", () => {
renderWithRouter(<AboutUs />);
const testElement = screen.getByTestId("reports");
expect(testElement).toBeTruthy();
});

it("should render leadership carousel successfully", () => {
renderWithRouter(<Caroussel CarousselData={LeadershipData} />);
const carouselElement = screen.getByTestId("carousel");
expect(carouselElement).toBeTruthy();
});
});
Loading

0 comments on commit 1096811

Please sign in to comment.