Skip to content

Commit

Permalink
Merge pull request #15 from datagrove/createCart
Browse files Browse the repository at this point in the history
Create cart
  • Loading branch information
r-southworth authored Mar 27, 2024
2 parents 69adadb + 67741eb commit 5a9efe0
Show file tree
Hide file tree
Showing 27 changed files with 1,415 additions and 89 deletions.
63 changes: 63 additions & 0 deletions src/assets/LearnGroveLogoBWNoText.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/assets/shopping-cart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions src/components/common/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { createSignal, Show } from "solid-js";
import type { Component } from "solid-js";
import { getLangFromUrl, useTranslations } from "../../i18n/utils";

// Internationalization
const lang = getLangFromUrl(new URL(window.location.href));
const t = useTranslations(lang);

//TODO: Upgrade to have an option for required and not let a user select nothing
interface Props {
Expand Down Expand Up @@ -29,8 +34,7 @@ const Dropdown: Component<Props> = (Props: Props) => {
}}
>
<div class="inline-block ml-2">
{/* TODO:Internationalize */}
{Props.selectedOption || "Select an option"}
{Props.selectedOption || t("formLabels.dropdownDefault")}
</div>
{/* Dropdown icon */}
<div class="inline-block">
Expand Down
45 changes: 35 additions & 10 deletions src/components/common/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getLangFromUrl, useTranslations } from "../../i18n/utils";
import ThemeIcon from "./ThemeIcon.astro";
import { ProfileBtn } from "./ProfileBtn";
import { Cart } from "@components/common/cart/Cart";
import { CreatePostsRouting } from "../posts/CreatePostsRouting";
import { ClientRouting } from "../users/ClientRouting";
Expand Down Expand Up @@ -37,15 +38,35 @@ const { links = [] } = Astro.props;
<div class="navLines flex items-center" id="navLines">
<div class="all-logo">
<a id="logo" href=`/${lang}`>
<!--?xml version='1.0' encoding='iso-8859-1'?-->

<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg>
<title>{t("ariaLabels.logo")}</title>
<description>{t("ariaLabels.todo")}</description>
<path
d="M486.965,230.141c28.063-31.641,12.375-71.844,10.453-76.781s-5.25-2.859-6.984-0.25 c-1.766,2.609-40.172,50.484-40.172,50.484H248.403c0,0-103.719-148.453-107.297-153.672s-6.328-5.797-8.797-5.797 c-2.484,0-6.344,0.828-6.344,7.984c0,4.688,0,78.953,0,78.953s-101.25,58.375-115.844,66.328 c-14.547,7.984-10.172,17.891-6.578,25.578c3.156,6.828,44,94.109,45.109,96.594c1.094,2.469,3.844,2.469,4.688,0.813 c0.813-1.656,11.547-16.516,13.469-19.813c1.922-3.281,4.406-2.469,6.063-1.078c1.047,0.859,7.156,4.953,9.625,6.859 c2.484,1.938,5.219,0,6.047-1.391c0.844-1.359,13.484-20.344,14.859-22.547s3.297-1.078,4.141-0.531 c0.813,0.531,5.5,5.219,8.797,8.516c3.297,3.031,4.406,1.922,6.875-1.375c0.984-1.281,9.922-14.844,11.844-16.781 c1.906-1.922,3.281-0.828,4.672,1.094c1.375,1.938,14.313,22.031,18.984,29.438c4.672,7.453,4.125,10.734,4.125,13.484 s-13.766,151.625-13.766,151.625h93l15.688-104.031c0,0,95.203,0,101.813,0c6.594,0,20.906,2.203,35.219,16.25 c14.313,14.016,26.125,87.219,26.125,87.219h91.078L486.965,230.141z"
></path>
<svg class="w-8 h-8" viewBox="0 0 180 180">
<g id="layer1">
<circle
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2.31085;stroke-dasharray:none;stroke-opacity:1"
id="path4-5"
cx="90.255104"
cy="90.192787"
r="86.344574"></circle>
<circle
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2.13599;stroke-dasharray:none;stroke-opacity:1"
id="path4-1-6"
cx="90.114067"
cy="90.788353"
r="79.811508"></circle>
<g
style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.00012;stroke-dasharray:none;stroke-opacity:1"
id="g5-7"
transform="matrix(5.909063,0,0,6.1904404,17.876796,12.726997)"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 12.0634,4.04209 c 2.997,-0.36695 5.7363,1.71348 6.219,4.68849 0.0512,0.31544 0.2501,0.58742 0.5351,0.73186 1.1441,0.57966 1.9861,1.70296 2.1528,3.07616 0.2655,2.1874 -1.2848,4.1698 -3.4526,4.4353 -0.3051,0.0373 -0.6782,0.037 -1.0178,-0.0164 -0.3615,-0.0569 -0.5654,-0.1548 -0.6411,-0.2174 -0.4257,-0.3518 -1.056,-0.2918 -1.4078,0.1339 -0.3518,0.4257 -0.2919,1.0561 0.1338,1.4079 0.4755,0.3929 1.0901,0.5704 1.6044,0.6513 0.5362,0.0844 1.0962,0.084 1.5716,0.0258 3.2712,-0.4005 5.5925,-3.3862 5.195,-6.6614 C 22.7275,10.4174 21.6524,8.84696 20.162,7.9256 19.3016,4.16205 15.7296,1.57827 11.8203,2.05692 9.22789,2.37434 7.10232,3.96441 5.98423,6.12144 2.75534,6.63544 0.999995,9.6056 1,12.6317 c 0,0.9741 0.33367,2.5007 1.49103,3.7971 1.18623,1.3288 3.13057,2.2968 6.11678,2.2968 0.55229,0 1,-0.4477 1,-1 0,-0.5523 -0.44771,-1 -1,-1 -2.52548,0 -3.88504,-0.8 -4.62479,-1.6287 C 3.2144,14.2359 3,13.2155 3,12.6317 3,10.7371 3.84959,9.16206 5.21959,8.45213 5.11229,9.13669 5.09664,9.84705 5.18413,10.5678 5.25068,11.1161 5.74908,11.5066 6.29734,11.44 6.8456,11.3735 7.23611,10.8751 7.16956,10.3268 7.04587,9.30783 7.20007,8.32218 7.57135,7.44331 8.33213,5.64245 10.0002,4.29471 12.0634,4.04209 Z m 4.5951,8.71051 c 0.4156,-0.3637 0.4578,-0.9955 0.0941,-1.4111 -0.3637,-0.4156 -0.9955,-0.4577 -1.4111,-0.0941 l -3.3573,2.9377 -2.34402,-1.9533 c -0.42427,-0.3536 -1.05484,-0.2962 -1.4084,0.128 -0.35357,0.4243 -0.29624,1.0549 0.12804,1.4084 L 11,15.9684 V 22 c 0,0.5523 0.4477,1 1,1 0.5523,0 1,-0.4477 1,-1 v -6.0462 z"
fill="#000000"
id="path1-8"
style="fill:currentColor;fill-opacity:1;stroke:none;stroke-width:1.00012;stroke-dasharray:none;stroke-opacity:1"
></path>
</g>
</g>
</svg>
</a>
</div>
Expand All @@ -63,7 +84,7 @@ const { links = [] } = Astro.props;
<div class="hidden md:block mr-2 w-fit">
<a href={`/${lang}/services`}>
<button class="btn-primary w-fit whitespace-nowrap">
{t("menus.services")}
{t("menus.resources")}
</button>
</a>
</div>
Expand All @@ -77,6 +98,10 @@ const { links = [] } = Astro.props;
<ThemeIcon />
</div>

<div class="">
<Cart client:only="solid-js" />
</div>

<div class="">
<ProfileBtn client:only="solid-js" />
</div>
Expand Down
9 changes: 9 additions & 0 deletions src/components/common/ProfileBtn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const ProfileBtn = () => {
const listShow = document.getElementById("profileItems");
if (listShow?.classList.contains("hidden")) {
listShow?.classList.remove("hidden");
document.getElementById("backdrop")?.classList.remove("hidden")
} else {
listShow?.classList.add("hidden");
}
Expand All @@ -36,6 +37,11 @@ export const ProfileBtn = () => {
console.log("User Error: " + UserError.message);
}

function hideMenu () {
document.getElementById("profileItems")?.classList.add("hidden")
document.getElementById("backdrop")?.classList.add("hidden")
}

function renderWhenUser() {
if (isUser()) {
return (
Expand Down Expand Up @@ -64,6 +70,9 @@ export const ProfileBtn = () => {
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5C3.44772 5 3 5.44772 3 6C3 6.55228 3.44772 7 4 7H20C20.5523 7 21 6.55228 21 6C21 5.44772 20.5523 5 20 5H4ZM3 12C3 11.4477 3.44772 11 4 11H20C20.5523 11 21 11.4477 21 12C21 12.5523 20.5523 13 20 13H4C3.44772 13 3 12.5523 3 12ZM3 18C3 17.4477 3.44772 17 4 17H20C20.5523 17 21 17.4477 21 18C21 18.5523 20.5523 19 20 19H4C3.44772 19 3 18.5523 3 18Z" fill="currentColor" />
</svg>
</button>
<div id="backdrop" class="backdrop absolute h-full w-screen top-0 left-0 hidden" onClick={()=> hideMenu()}>
{/* This allows that if someone clicks anywhere outside the modal the modal will hide */}
</div>
<ul id="profileItems" class="hidden fixed z-50 right-2 bg-background1 dark:bg-background1-DM m-2 p-2 rounded-lg justify-start shadow-md shadow-shadow-LM dark:shadow-shadow-DM">
{renderWhenUser()}
<div class="mt-2 border-b-2 border-border1 dark:border-border1-DM pb-2">
Expand Down
80 changes: 80 additions & 0 deletions src/components/common/cart/AddToCartButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { onMount } from "solid-js";
import { createStore } from "solid-js/store";
import type { Component } from "solid-js";
import { getLangFromUrl, useTranslations } from "@i18n/utils";
import cart from "@assets/shopping-cart.svg";

const lang = getLangFromUrl(new URL(window.location.href));
const t = useTranslations(lang);

interface Item {
description: string;
price: number;
price_id: string;
quantity: number;
product_id: string;
}

interface Props {
description: string;
price: number;
price_id: string;
quantity: number;
product_id: string;
buttonClick: (event: Event) => void;
}

export const [items, setItems] = createStore<Item[]>([]);

export const AddToCart: Component<Props> = (props: Props) => {
const storedItems = localStorage.getItem("cartItems");

onMount(() => {
if (storedItems) {
setItems(JSON.parse(storedItems));
}
});

function clickHandler(e: Event) {
e.preventDefault();
e.stopPropagation();

let itemInCart = false;

const updatedItems = items.map((item: Item) => {
if (item.product_id === props.product_id) {
itemInCart = true;
return { ...item, quantity: item.quantity + props.quantity };
}
return item;
});

if (!itemInCart) {
const newItem = {
description: props.description,
price: props.price,
price_id: props.price_id,
quantity: props.quantity,
product_id: props.product_id,
};
setItems([...updatedItems, newItem]);
} else {
setItems(updatedItems);
}

props.buttonClick(e);
console.log(items);
}

return (
<div class="relative z-10">
<button
onclick={(e) => clickHandler(e)}
class="btn-primary"
aria-label={t("buttons.addToCart")}
>
{t("buttons.addToCart")}
</button>
</div>
);
};
Loading

0 comments on commit 5a9efe0

Please sign in to comment.