Skip to content

Commit

Permalink
Merge pull request #26 from PotLock/bug/add-to-cart
Browse files Browse the repository at this point in the history
add cart logic back
  • Loading branch information
wpdas authored May 3, 2024
2 parents 4140543 + f03968e commit 33f6c44
Show file tree
Hide file tree
Showing 18 changed files with 472 additions and 98 deletions.
197 changes: 197 additions & 0 deletions src/components/ButtonStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import styled from "styled-components";

type ButtonProps = {
direction: "right" | "left";
type: "outline" | "tonal" | "standard" | "primary" | "brand-outline";
};

export const Icon = styled.img`
width: 20px;
height: 20px;
object-fit: contain;
`;

export const ButtonContainer = styled.div`
all: unset;
width: 120px;
height: 22px;
border-radius: 6px;
padding: 9px 16px 9px 12px;
justify-content: center;
align-items: center;
display: inline-flex;
gap: 8px;
font-size: 14px;
font-weight: 500;
// font-family: "Mona Sans", sans-serif;
line-height: 22px;
text-align: center;
font-feature-settings: "ss01" on, "salt" on;
/* Mona sans/Text sm/14px:Medium */
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 22px; /* 157.143% */
flex-shrink: 0;
transition: all 200ms cubic-bezier(0.17, 0.67, 0.83, 0.67);
flex-direction: ${(props: ButtonProps) => {
if (props.direction === "right") {
return "row";
} else if (props.direction === "left") {
return "row-reverse";
}
}};
svg path {
fill: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "rgba(123, 123, 123, 1)";
case "tonal":
return "#656565";
case "standard":
return "#FFFFFF";
case "primary":
return "#FFFFFF";
case "brand-outline":
return "hsla(358, 88%, 71%, 1)";
}
}};
}
background: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "var(--button-outline-bg, Neutral/White)";
case "tonal":
return "var(--button-tonal-bg,#FEF6EE) ";
case "standard":
return "var(--button-standard-bg, #3D3D3D)";
case "primary":
return "var(--button-primary-bg, #DD3345)";
case "brand-outline":
return "hsla(0, 0%, 100%, 0.01)";
}
}};
color: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "var(--button-outline-color, #292929)";
case "tonal":
return "var(--button-tonal-color,#292929) ";
case "standard":
return "var(--button-standard-color, #FFFFFF)";
case "primary":
return "var(--button-primary-color, #FFFFFF)";
case "brand-outline":
return "hsla(354, 71%, 53%, 1)";
}
}};
box-shadow: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.22) inset, 0px -1px 0px 0px rgba(15, 15, 15, 0.15) inset, 0px 1px 2px -0.5px rgba(5, 5, 5, 0.08);";
case "tonal":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px #FFF inset, 0px 0px 0px 2px #FFF inset, 0px 1.5px 0px 0px rgba(0, 0, 0, 0.84);";
case "standard":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px rgba(166, 166, 166, 0.40) inset, 0px 0px 0px 2px rgba(166, 166, 166, 0.40) inset, 0px 1px 2px 0px rgba(15, 15, 15, 0.15), 0px 1px 3px -1px rgba(5, 5, 5, 0.08);";
case "primary":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px rgba(246, 118, 122, 0.50) inset, 0px 0px 0px 2px rgba(246, 118, 122, 0.50) inset, 0px 1.5px 0px 0px rgba(0, 0, 0, 0.84);";
case "brand-outline":
return "0px 0px 0px 1px rgba(243, 78, 95, 0.78) inset, 0px -1px 0px 0px rgba(73, 8, 19, 0.50) inset, 0px 1px 2px -0.5px rgba(73, 8, 19, 0.20);";
}
}};
&:hover:not(:disabled) {
transform: ${(props: ButtonProps) => {
switch (props.type) {
case "primary":
case "tonal":
return "translateY(1px)";
}
}};
box-shadow: ${(props: ButtonProps) => {
switch (props.type) {
case "primary":
return " 0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px #ED464F inset;";
case "outline":
return " 0px 0px 0px 1px rgba(0, 0, 0, 0.22) inset, 0px -1px 0px 0px rgba(15, 15, 15, 0.15) inset, 0px 1px 2px -0.5px rgba(5, 5, 5, 0.08);";
case "standard":
return " 0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px rgba(166, 166, 166, 0.40) inset, 0px 0px 0px 2px rgba(166, 166, 166, 0.40) inset, 0px 1px 2px 0px rgba(15, 15, 15, 0.15), 0px 1px 3px -1px rgba(5, 5, 5, 0.08);";
case "tonal":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px #FFF inset;";
case "brand-outline":
return "0px 0px 0px 1px rgba(243, 78, 95, 0.78) inset, 0px -1px 0px 0px rgba(73, 8, 19, 0.50) inset, 0px 1px 2px -0.5px rgba(73, 8, 19, 0.20);";
}
}};
background: ${(props: ButtonProps) => {
switch (props.type) {
case "primary":
return " #DD3345";
case "outline":
return "Neutral/50";
case "standard":
return " #525252";
case "tonal":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px #FFF inset;";
case "brand-outline":
return "#FEF3F2";
}
}};
}
&:focus:not(:disabled) {
box-shadow: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.22) inset, 0px -1px 0px 0px rgba(15, 15, 15, 0.15) inset, 0px 1px 2px -0.5px rgba(5, 5, 5, 0.08), 0px 0px 0px 2px #FFF, 0px 0px 0px 4px rgba(0, 0, 0, 0.84);";
case "primary":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 0px 0px 2px #FFF, 0px 0px 0px 4px rgba(0, 0, 0, 0.84);";
case "standard":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 1px 1px 1px rgba(166, 166, 166, 0.30) inset, 0px 0px 0px 2px rgba(166, 166, 166, 0.30) inset, 0px 0px 0px 2px #FFF, 0px 0px 0px 4px rgba(0, 0, 0, 0.84);";
case "tonal":
return "0px 0px 0px 1px rgba(0, 0, 0, 0.84) inset, 0px 0px 0px 2px #FFF, 0px 0px 0px 4px rgba(0, 0, 0, 0.84);";
case "brand-outline":
return "0px 0px 0px 1px rgba(243, 78, 95, 0.78) inset, 0px -1px 0px 0px rgba(73, 8, 19, 0.50) inset, 0px 1px 2px -0.5px rgba(5, 5, 5, 0.08), 0px 0px 0px 2px #FFF, 0px 0px 0px 4px rgba(0, 0, 0, 0.84);";
}
}};
}
&:disabled {
color: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "hsla(0, 0%, 78%, 1)"; // Adjust color value
case "standard":
return "hsla(0, 0%, 65%, 1)"; // Use CSS variable for color or specify a fallback
default:
return "inherit"; // Fallback to default color
}
}};
box-shadow: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "0px 0px 0px 1px rgba(15, 15, 15, 0.15) inset;"; // Adjust box-shadow value
case "standard":
return "0px 0px 0px 1px rgba(15, 15, 15, 0.15) inset;"; // Adjust box-shadow value
default:
return "none"; // No box-shadow for other types
}
}};
background: ${(props: ButtonProps) => {
switch (props.type) {
case "outline":
return "var(--button-outline-bg-disabled, #fff)"; // Use CSS variable for background or specify a fallback
case "standard":
return "var(--button-standard-bg-disabled, #EBEBEB)"; // Use CSS variable for background or specify a fallback
default:
return "inherit"; // Fallback to default background
}
}};
}
`;
28 changes: 14 additions & 14 deletions src/components/Cart/NavItem/NavItem.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { VM } from "alem";
import { useCart } from "@app/hooks/useCart";
import { CartButton, CartCountContainer, CartText } from "./styles";

const { getCartItemCount } = VM.require("potlock.near/widget/SDK.cart") ?? {
getCartItemCount: () => 0,
};

// const { CartModal } = VM.require("potlock.near/widget/Cart.Modal") ?? {
// CartModal: () => <></>,
// };

const numCartItems = getCartItemCount();
import { RouteLink, navigate } from "alem";
import routesPath from "@app/routes/routesPath";

const NavItem = () => {
const { cart } = useCart();

const numCartItems = cart ? Object.keys(cart).length : 0;
return (
<>
<CartButton numCartItems={numCartItems} onClick={() => {}}>
<RouteLink to={routesPath.CART_TAB}>
<CartButton
numCartItems={numCartItems}
onClick={() => {
numCartItems > 0 ? navigate.to("cart") : {};
}}
>
<CartText>Cart</CartText>
{numCartItems > 0 && (
<CartCountContainer>
<CartText style={{ fontSize: "12px" }}>{numCartItems}</CartText>
</CartCountContainer>
)}
</CartButton>
</>
</RouteLink>
);
};

Expand Down
77 changes: 77 additions & 0 deletions src/contexts/CartProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Storage, createContext } from "alem";

export type CartItem = {
id: string;
amount: string;
token: string;
referrerId?: string;
potId?: string;
};

type Cart = {
[id: string]: CartItem;
};

// potDetail: activeRound ? state.detailForPots[activeRound] : null,

export type CartContextProps = {
cart: Cart;

/**
* Set cart
* @param item
* @returns
*/
addItemstoCart: (cart: CartItem[]) => void;
removeItemsFromCart: (idsToRemove: CartItem["id"][]) => void;
clearCart: () => void;
};

const DEFAULT_CART = {};

const CART_KEY = "cart";

const getCart = () => JSON.parse(Storage.get(CART_KEY)) || DEFAULT_CART;

const CartProvider = () => {
const { setDefaultData, updateData, getSelf } = createContext<CartContextProps>("cart-context");

const updateCart = (cart: Cart) => {
Storage.set(CART_KEY, JSON.stringify(cart));
updateData({
cart,
});
};

// Set default data
setDefaultData({
cart: getCart(),
addItemstoCart: (items: CartItem[]) => {
const { cart } = getSelf();
items.forEach((item) => {
cart[item.id] = item;
});
updateCart(cart);
},
clearCart: () => {
updateData({
cart: DEFAULT_CART,
});
updateCart(DEFAULT_CART);
},
removeItemsFromCart: (idsToRemove: CartItem["id"][]) => {
const { cart } = getSelf();
idsToRemove.forEach((id) => {
// Check if id key exists in the cart
if (cart.hasOwnProperty(id)) {
// If the id exists, delete it from the cart
delete cart[id];
}
});
updateCart(cart);
},
});
};

// Main context to be injected
export default CartProvider;
4 changes: 4 additions & 0 deletions src/hooks/useCart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { useContext } from "alem";
import { CartContextProps } from "@app/contexts/CartProvider";

export const useCart = () => useContext<CartContextProps>("cart-context");
3 changes: 3 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { RouterContext, loadExternalStyles } from "alem";
import Main from "./Main";
import CartProvider from "./contexts/CartProvider";
import Spinner from "./components/Spinner";
import DonationModalProvider from "./contexts/DonationModalProvider";
// import ProjectsProvider from "./contexts/ProjectsProvider";

const App = () => {
const fontsLoaded = loadExternalStyles([
"https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400..700;1,400..700&display=swap",
]);

RouterContext();
CartProvider();
DonationModalProvider();
return <div className="app-container">{fontsLoaded ? <Main /> : <Spinner />}</div>;
};
Expand Down
6 changes: 4 additions & 2 deletions src/modals/ModalDonation/ConfirmDirect/ConfirmDirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import PotSDK from "@app/SDK/pot";
import DonateSDK from "@app/SDK/donate";
import constants from "@app/constants";
import { Amout, ButtonWrapper, Container, FeesRemoval, Label, NoteWrapper } from "./styles";
import { Button } from "../FormDirect/styles";
import nearToUsd from "@app/utils/nearToUsd";
import ProfileImage from "@app/components/mob.near/ProfileImage";
import CheckBox from "@app/components/Inputs/Checkbox/Checkbox";
import Button from "@app/components/Button";
import NearIcon from "@app/assets/svgs/near-icon";
import BreakdownSummary from "@app/components/Cart/BreakdownSummary/BreakdownSummary";
import TextArea from "@app/components/Inputs/TextArea/TextArea";
Expand Down Expand Up @@ -368,7 +368,9 @@ const ConfirmDirect = ({
</NoteWrapper>
)}
<ButtonWrapper>
<Button type="primary" text="Confirm donation" onClick={handleDonate} />
<Button className="filled" onClick={handleDonate}>
Confirm donation
</Button>
</ButtonWrapper>
</Container>
);
Expand Down
6 changes: 1 addition & 5 deletions src/modals/ModalDonation/ConfirmDirect/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,5 @@ export const ButtonWrapper = styled.div`
display: flex;
margin-top: 2rem;
margin-bottom: 0.5rem;
button {
padding: 12px 16px;
width: 100%;
font-weight: 500;
}
justify-content: flex-end;
`;
Loading

0 comments on commit 33f6c44

Please sign in to comment.