Skip to content

Commit

Permalink
Merge pull request #163 from datagrove/multipleFavorites
Browse files Browse the repository at this point in the history
Multiple favorites
  • Loading branch information
r-southworth authored Oct 8, 2024
2 parents c1ff5af + 44aca0e commit 9592c42
Show file tree
Hide file tree
Showing 19 changed files with 1,558 additions and 323 deletions.
2 changes: 1 addition & 1 deletion src/components/common/cart/AddAllToCart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const AddAllToCart: Component<Props> = (props: Props) => {
}

return (
<div class="relative z-10 w-full">
<div class="">
<button
onclick={(e) => clickHandler(e)}
class="btn-cart"
Expand Down
115 changes: 70 additions & 45 deletions src/components/common/notices/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,46 @@ import type { Component, JSX } from "solid-js";
import { createSignal, createEffect, onCleanup, Show } from "solid-js";
import { getHeading } from "./utils";
import type { HeadingProps } from "./utils";
import { createStore } from "solid-js/store";
import { Portal } from "solid-js/web";

type ModalProps = {
children: JSX.Element;
buttonClass: string;
buttonId: string;
buttonContent: JSX.Element;
buttonAriaLabel?: string;
heading: HeadingProps["heading"];
headingLevel?: HeadingProps["headingLevel"];
classList?: string;
//classList?: string;
};

export const [isOpen, setIsOpen] = createSignal<Record<string, boolean>>({});

export function openModal(modalId: string, e?: Event) {
e?.preventDefault();
e?.stopPropagation();
setIsOpen((prev) => ({ ...prev, [modalId]: true }));
}

export function closeModal(modalId: string, e?: Event) {
e?.preventDefault();
e?.stopPropagation();
setIsOpen((prev) => ({ ...prev, [modalId]: false }));
}

export function isModalOpen(modalId: string) {
return isOpen()[modalId];
}

const Modal: Component<ModalProps> = (props) => {
const [isOpen, setIsOpen] = createSignal<boolean>(false);
const [modal, setModal] = createSignal<HTMLElement | null>(null);

const focusableElements =
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';

createEffect(() => {
if (isOpen()) {
if (isModalOpen(props.buttonId)) {
console.log("modal open");
const originalFocusedElement =
document.activeElement as HTMLElement;
Expand All @@ -37,7 +57,7 @@ const Modal: Component<ModalProps> = (props) => {
const isTabPressed = (key || code) === "Tab";
const isEscapePressed = (key || code) === "Escape";
if (!isTabPressed && !isEscapePressed) return;
if (isEscapePressed) return setIsOpen(false);
if (isEscapePressed) return closeModal(props.buttonId, e);
if (shiftKey) {
// if shift key pressed for shift + tab combination
if (document.activeElement === firstFocusableElement) {
Expand All @@ -60,57 +80,62 @@ const Modal: Component<ModalProps> = (props) => {
}
});

function openModal (e: Event) {
e.preventDefault();
e.stopPropagation();
setIsOpen(true);
}
// function openModal(e: Event) {
// e.preventDefault();
// e.stopPropagation();
// setIsOpen(true);
// }

// function closeModal(e: Event) {
// e.preventDefault();
// e.stopPropagation();
// setIsOpen(false);
// }

function closeModal (e: Event) {
e.preventDefault();
e.stopPropagation();
setIsOpen(false);
}

return (
<>
<button
class={props.buttonClass}
id={props.buttonId}
aria-label={props.buttonAriaLabel}
type="button"
onClick={(e) => openModal(e)}
onClick={(e) => openModal(props.buttonId, e)}
>
{props.buttonContent}
</button>
<Show when={isOpen()}>
<div
role="presentation"
class="modal__backdrop min-h-100vh min-w-100vw fixed inset-0 z-[55] dark:bg-background1 bg-background1-DM bg-opacity-50 dark:bg-opacity-30"
onClick={(e) => closeModal(e)}
onKeyPress={(e) =>
(e.key || e.code) === "Escape" ? closeModal(e) : null
}
/>
<section
role="dialog"
class="modal p-4 min-h-100vh w-100vw fixed inset-0 z-[60] overflow-y-auto dark:bg-background1-DM bg-background1 md:-translate-x-1/2 md:-translate-y-1/2 md:left-1/2 md:top-1/2 md:max-h-[calc(100vh-4rem)] md:min-h-fit md:w-[calc(100vw-4rem)] md:max-w-[768px] md:rounded-xl"
ref={setModal}
>
<header class="flex flex-row flex-nowrap border-b-[1px] gap-[2rem] justify-between sticky items-center">
{getHeading({
heading: props.heading,
headingLevel: props?.headingLevel,
})}
<button
aria-label="Close Dialog"
class="modal__close text-xl"
onClick={(e) => closeModal(e)}
>
&times;
</button>
</header>
<div class="modal__body pt-2">{props.children}</div>
</section>
<Show when={isModalOpen(props.buttonId)}>
<Portal>
<div
role="presentation"
class="modal__backdrop min-h-100vh min-w-100vw fixed inset-0 z-[55] bg-background1-DM bg-opacity-50 dark:bg-background1 dark:bg-opacity-30"
onClick={(e) => closeModal(props.buttonId, e)}
onKeyPress={(e) =>
(e.key || e.code) === "Escape"
? closeModal(props.buttonId, e)
: null
}
/>
<section
role="dialog"
class="modal min-h-100vh w-100vw fixed inset-0 z-[60] overflow-y-auto bg-background1 p-4 dark:bg-background1-DM md:left-1/2 md:top-1/2 md:max-h-[calc(100vh-4rem)] md:min-h-fit md:w-[calc(100vw-4rem)] md:max-w-[768px] md:-translate-x-1/2 md:-translate-y-1/2 md:rounded-xl"
ref={setModal}
>
<header class="sticky flex flex-row flex-nowrap items-center justify-between gap-[2rem] border-b-[1px]">
{getHeading({
heading: props.heading,
headingLevel: props?.headingLevel,
})}
<button
aria-label="Close Dialog"
class="modal__close text-xl"
onClick={(e) => closeModal(props.buttonId, e)}
>
&times;
</button>
</header>
<div class="modal__body pt-2">{props.children}</div>
</section>
</Portal>
</Show>
</>
);
Expand Down
8 changes: 6 additions & 2 deletions src/components/members/UserProfileView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ export const UserProfileView: Component = () => {

onMount(async () => {
console.log(User);
setSession(User?.session);
await fetchUser(User?.session?.user.id!);
if (typeof User?.session === "undefined") {
alert(t("messages.signIn"));
} else {
setSession(User?.session);
await fetchUser(User?.session?.user.id!);
}
// await getPurchasedItems();
});

Expand Down
81 changes: 81 additions & 0 deletions src/components/members/user/createFavoriteList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createSignal, createEffect, onMount } from "solid-js";
import type { Component } from "solid-js";
import { useTranslations } from "@i18n/utils";
import Modal, { closeModal } from "@components/common/notices/modal";
import supabase from "@lib/supabaseClient";

interface Props {
user_id: string;
lang: "en" | "es" | "fr";
onListCreated: () => void;
buttonContent?: string;
}

export const CreateFavoriteList: Component<Props> = (props) => {
const [listName, setListName] = createSignal("");
const lang = props.lang;
const t = useTranslations(lang);

onMount(() => {
if (props.user_id === "") {
alert();
}
});

createEffect(() => {
console.log(listName());
});

function createListMenu(buttonId: string) {
return (
<div class="flex flex-col p-4">
<label for="listName">{t("formLabels.listName")}</label>
<input
id="listName"
type="text"
class="rounded-md border border-black text-black"
oninput={(e) => setListName(e.target.value)}
/>
<div class="flex justify-center">
<button
class="btn-primary mt-4 w-fit"
onclick={(e) => {
createList(e, buttonId);
}}
>
{t("buttons.createList")}
</button>
</div>
</div>
);
}

async function createList(e: Event, buttonId: string) {
e.preventDefault();
console.log(listName());

const { data: favoriteList, error: favoriteError } = await supabase
.from("favorites")
.insert({
customer_id: props.user_id,
list_name: listName(),
});
if (favoriteError) {
console.log(favoriteError.message);
} else {
closeModal(buttonId, e);
props.onListCreated();
}
}

return (
<Modal
children={<>{createListMenu("createFavoriteListMenu")}</>}
buttonClass={`btn-primary text-2xl`}
buttonId="createFavoriteListMenu"
buttonContent={props.buttonContent ? props.buttonContent : "+"}
heading={t("buttons.createFavoriteList")}
headingLevel={3}
></Modal>
);
};
Loading

0 comments on commit 9592c42

Please sign in to comment.