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

refactor: gallery delete button #381

Merged
merged 12 commits into from
Nov 8, 2023
62 changes: 62 additions & 0 deletions resources/js/Components/Galleries/DeleteGalleryButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import userEvent from "@testing-library/user-event";
import DeleteGalleryButton from "./DeleteGalleryButton";
import GalleryDataFactory from "@/Tests/Factories/Gallery/GalleryDataFactory";
import { mockInertiaUseForm, render, screen } from "@/Tests/testing-library";

describe("DeleteGalleryButton", () => {
const gallery = new GalleryDataFactory().create();

it("should render", () => {
render(<DeleteGalleryButton gallery={gallery} />);

expect(screen.getByTestId("DeleteGalleryButton")).toBeInTheDocument();
});

it("opens the slideout panel when pressed", async () => {
render(<DeleteGalleryButton gallery={gallery} />);

expect(screen.queryByTestId("ConfirmationDialog__form")).not.toBeInTheDocument();

await userEvent.click(screen.getByTestId("DeleteGalleryButton"));

expect(screen.getByTestId("ConfirmationDialog__form")).toBeInTheDocument();
});

it("closes the slideout panel when close button is pressed", async () => {
render(<DeleteGalleryButton gallery={gallery} />);

expect(screen.queryByTestId("ConfirmationDialog__form")).not.toBeInTheDocument();

await userEvent.click(screen.getByTestId("DeleteGalleryButton"));

expect(screen.getByTestId("ConfirmationDialog__form")).toBeInTheDocument();

await userEvent.click(screen.getByTestId("ConfirmationDialog__close"));

expect(screen.queryByTestId("ConfirmationDialog__form")).not.toBeInTheDocument();
});

it("deletes the gallery when submitted", async () => {
const submitFunction = vi.fn().mockImplementation((_, options) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
options?.onFinish?.();
});

mockInertiaUseForm({
data: {},
delete: submitFunction,
});

render(<DeleteGalleryButton gallery={gallery} />);

await userEvent.click(screen.getByTestId("DeleteGalleryButton"));

await userEvent.type(screen.getByTestId("ConfirmDeletionDialog__input"), "DELETE");

await userEvent.click(screen.getByTestId("ConfirmationDialog__confirm"));

expect(submitFunction).toHaveBeenCalled();

expect(screen.queryByTestId("ConfirmationDialog__form")).not.toBeInTheDocument();
});
});
54 changes: 54 additions & 0 deletions resources/js/Components/Galleries/DeleteGalleryButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useForm } from "@inertiajs/react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "@/Components/Buttons";
import { ConfirmDeletionDialog } from "@/Components/ConfirmDeletionDialog";

const DeleteGalleryButton = ({ gallery }: { gallery: App.Data.Gallery.GalleryData }): JSX.Element => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);

const { processing, delete: remove } = useForm({});

const submit = (): void => {
remove(
route("my-galleries.destroy", {
slug: gallery.slug,
}),
{
onFinish: () => {
setOpen(false);
},
},
);
};

return (
<>
<Button
icon="Trash"
onClick={() => {
setOpen(true);
}}
variant="secondary"
iconSize="md"
className="bg-transparent p-2"
data-testid="DeleteGalleryButton"
/>

<ConfirmDeletionDialog
title={t("pages.galleries.delete_modal.title")}
isOpen={open}
onClose={() => {
setOpen(false);
}}
onConfirm={submit}
isDisabled={processing}
>
{t("pages.galleries.delete_modal.confirmation_text")}
</ConfirmDeletionDialog>
</>
);
};

export default DeleteGalleryButton;
22 changes: 22 additions & 0 deletions resources/js/Components/Galleries/NftGalleryCard.blocks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,17 @@ describe("GalleryStats", () => {
expect(screen.getByTestId("GalleryHeadingPlaceholder")).toBeInTheDocument();
});

it("should render gallery stats when delete button is enabled", () => {
render(
<GalleryStats
gallery={gallery}
showDeleteButton
/>,
);

expect(screen.getByTestId("GalleryStats")).toBeInTheDocument();
});

it("should force like if user was not authenticated", async () => {
signedActionMock.mockImplementation((action) => {
action({ authenticated: false, signed: false });
Expand Down Expand Up @@ -593,4 +604,15 @@ describe("GalleryFooter", () => {

expect(screen.getByTestId("GalleryStats__views")).toHaveTextContent(gallery.views.toString());
});

it("shows delete button when enabled", () => {
render(
<GalleryFooter
gallery={gallery}
showDeleteButton
/>,
);

expect(screen.getByTestId("DeleteGalleryButton")).toBeInTheDocument();
});
});
68 changes: 52 additions & 16 deletions resources/js/Components/Galleries/NftGalleryCard.blocks.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cn from "classnames";
import { type MouseEventHandler, useRef } from "react";
import { useTranslation } from "react-i18next";
import DeleteGalleryButton from "./DeleteGalleryButton";
import { Avatar } from "@/Components/Avatar";
import { DynamicBalance } from "@/Components/DynamicBalance";
import { Heading } from "@/Components/Heading";
Expand Down Expand Up @@ -306,35 +307,60 @@ const GalleryStatsLikeButton = ({ gallery }: { gallery: App.Data.Gallery.Gallery
);
};

export const GalleryFooter = ({ gallery }: { gallery: App.Data.Gallery.GalleryData }): JSX.Element => (
export const GalleryFooter = ({
gallery,
showDeleteButton = false,
}: {
gallery: App.Data.Gallery.GalleryData;
showDeleteButton?: boolean;
}): JSX.Element => (
<div
className="flex items-center justify-between text-theme-secondary-700 dark:text-theme-dark-200"
data-testid="GalleryFooter"
>
<GalleryStatsLikeButton gallery={gallery} />

<div className="flex items-center space-x-2">
<Icon
name="Eye"
size="lg"
/>
<span
className="text-sm"
data-testid="GalleryStats__views"
>
{gallery.views}
</span>
<div className="flex items-center">
<div className="flex items-center space-x-2">
<Icon
name="Eye"
size="lg"
/>
<span
className="text-sm"
data-testid="GalleryStats__views"
>
{gallery.views}
</span>
</div>

{showDeleteButton && (
<>
<span className="ml-3 mr-1 flex h-1.25 w-1.25 rounded-full bg-theme-secondary-400 dark:bg-theme-dark-700"></span>

<DeleteGalleryButton gallery={gallery} />
</>
)}
</div>
</div>
);

export const GalleryStats = ({ gallery }: { gallery: App.Data.Gallery.GalleryData }): JSX.Element => {
export const GalleryStats = ({
gallery,
showDeleteButton = false,
}: {
gallery: App.Data.Gallery.GalleryData;
showDeleteButton?: boolean;
}): JSX.Element => {
const { user } = useAuth();
const { t } = useTranslation();

return (
<div
className="rounded-b-xl bg-theme-secondary-50 px-6 pb-3 font-medium dark:bg-theme-dark-800"
className={cn(
"rounded-b-xl bg-theme-secondary-50 px-6 font-medium dark:bg-theme-dark-800",
showDeleteButton ? "pb-1.5" : "pb-3",
)}
data-testid="GalleryStats"
>
<div className="flex justify-between pt-3">
Expand Down Expand Up @@ -369,8 +395,18 @@ export const GalleryStats = ({ gallery }: { gallery: App.Data.Gallery.GalleryDat
<span className="text-sm dark:text-theme-dark-50 sm:text-base">{gallery.collectionsCount}</span>
</div>
</div>
<hr className="my-3 text-theme-secondary-300 dark:text-theme-dark-700" />
<GalleryFooter gallery={gallery} />

<hr
className={cn(
"mt-3 text-theme-secondary-300 dark:text-theme-dark-700",
showDeleteButton ? "mb-2" : "mb-3",
)}
/>

<GalleryFooter
gallery={gallery}
showDeleteButton={showDeleteButton}
/>
</div>
);
};
Expand Down
30 changes: 19 additions & 11 deletions resources/js/Components/Galleries/NftGalleryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import cn from "classnames";
import { GalleryCoverImage } from "@/Components/Galleries/GalleryPage/GalleryCoverImage";
import { GalleryHeading, GalleryStats, NftImageGrid } from "@/Components/Galleries/NftGalleryCard.blocks";

export const NftGalleryCard = ({ gallery }: { gallery: App.Data.Gallery.GalleryData }): JSX.Element => (
<Link
href={route("galleries.view", gallery.slug)}
className="group focus-visible:outline-none focus-visible:ring-0"
>
export const NftGalleryCard = ({
gallery,
showDeleteButton = false,
}: {
gallery: App.Data.Gallery.GalleryData;
showDeleteButton?: boolean;
}): JSX.Element => (
<div className="group focus-visible:outline-none focus-visible:ring-0">
<div
className={cn(
"transition-default m-1 box-content flex flex-col rounded-xl border border-theme-secondary-300 dark:border-theme-dark-700",
Expand All @@ -22,13 +25,18 @@ export const NftGalleryCard = ({ gallery }: { gallery: App.Data.Gallery.GalleryD

{gallery.coverImage === null && <NftImageGrid nfts={gallery.nfts} />}

<GalleryHeading
name={gallery.name}
wallet={gallery.wallet}
/>
<Link href={route("galleries.view", gallery.slug)}>
<GalleryHeading
name={gallery.name}
wallet={gallery.wallet}
/>
</Link>
</div>

<GalleryStats gallery={gallery} />
<GalleryStats
showDeleteButton={showDeleteButton}
gallery={gallery}
/>
</div>
</Link>
</div>
);
1 change: 1 addition & 0 deletions resources/js/Pages/Galleries/MyGalleries/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const Index = ({
<NftGalleryCard
key={index}
gallery={gallery}
showDeleteButton
/>
))}
</div>
Expand Down
Loading