Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create cart #15

Merged
merged 18 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading