Skip to content

Commit

Permalink
Merge pull request #959 from rockingrohit9639/feature/kits
Browse files Browse the repository at this point in the history
Feature/kits
  • Loading branch information
DonKoko committed May 14, 2024
2 parents 0a35d1c + ea38a2a commit 9f70c78
Show file tree
Hide file tree
Showing 50 changed files with 3,626 additions and 115 deletions.
3 changes: 3 additions & 0 deletions app/atoms/selected-assets-atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ export const bookingsSelectedAssetsAtom = atom<string[]>([]);

/** Track selected assets for adding assets to location */
export const locationsSelectedAssetsAtom = atom<string[]>([]);

/** Track selected assets for adding assets to kits */
export const kitsSelectedAssetsAtom = atom<string[]>([]);
46 changes: 27 additions & 19 deletions app/components/assets/actions-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import { useLoaderData, useSearchParams } from "@remix-run/react";
import { useLoaderData } from "@remix-run/react";
import { useHydrated } from "remix-utils/use-hydrated";
import { ChevronRight, UserXIcon } from "~/components/icons/library";
import { ChevronRight } from "~/components/icons/library";
import {
DropdownMenu,
DropdownMenuContent,
Expand All @@ -19,20 +18,19 @@ import { Button } from "../shared/button";
const ConditionalActionsDropdown = () => {
const { asset } = useLoaderData<typeof loader>();
const assetCanBeReleased = asset.custody;
let [searchParams] = useSearchParams();
const refIsQrScan = searchParams.get("ref") === "qr";
const defaultOpen = window.innerWidth <= 640 && refIsQrScan;
const [defaultApplied, setDefaultApplied] = useState(false);
const assetIsCheckedOut = asset.status === "CHECKED_OUT";

const [dropdownRef, open, setOpen] = useControlledDropdownMenu(defaultOpen);
const {
ref: dropdownRef,
defaultApplied,
open,
defaultOpen,
setOpen,
} = useControlledDropdownMenu();

useEffect(() => {
if (defaultOpen && !defaultApplied) {
setOpen(true);
setDefaultApplied(true);
}
}, [defaultOpen, defaultApplied, setOpen]);
const assetIsPartOfUnavailableKit = Boolean(
asset.kit && asset.kit.status !== "AVAILABLE"
);

return (
<>
Expand Down Expand Up @@ -106,13 +104,18 @@ const ConditionalActionsDropdown = () => {
to="release-custody"
role="link"
variant="link"
className="justify-start whitespace-nowrap
px-4 py-3 text-gray-700 hover:text-gray-700"
className={tw(
"justify-start whitespace-nowrap px-4 py-3 text-gray-700 hover:text-gray-700",
assetIsPartOfUnavailableKit
? "pointer-events-none cursor-not-allowed opacity-50"
: ""
)}
width="full"
onClick={() => setOpen(false)}
disabled={assetIsPartOfUnavailableKit}
>
<span className="flex items-center gap-1">
<UserXIcon /> Release Custody
<Icon icon="take-custody" /> Release Custody
</span>
</Button>
) : (
Expand All @@ -125,7 +128,7 @@ const ConditionalActionsDropdown = () => {
onClick={() => setOpen(false)}
>
<span className="flex items-center gap-2">
<Icon icon="user" /> Assign custody
<Icon icon="give-custody" /> Assign custody
</span>
</Button>
)}
Expand Down Expand Up @@ -192,7 +195,7 @@ const ConditionalActionsDropdown = () => {
onSelect={(e) => {
e.preventDefault();
}}
disabled={assetIsCheckedOut}
disabled={assetIsCheckedOut || assetIsPartOfUnavailableKit}
>
<DeleteAsset asset={asset} />
</DropdownMenuItem>
Expand All @@ -212,6 +215,11 @@ const ConditionalActionsDropdown = () => {
Some actions are disabled due to the asset being checked out.
</div>
) : null}
{assetIsPartOfUnavailableKit ? (
<div className=" border-t p-2 text-left text-xs">
Some actions are disabled due to the asset being part of a kit.
</div>
) : null}
</div>
</DropdownMenuContent>
</DropdownMenu>
Expand Down
54 changes: 4 additions & 50 deletions app/components/assets/asset-status-badge.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import type { SVGProps } from "react";
import { AssetStatus } from "@prisma/client";
import { Badge } from "../shared/badge";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "../shared/tooltip";
import { UnavailableBadge } from "../shared/unavailable-badge";

export const userFriendlyAssetStatus = (status: AssetStatus) => {
switch (status) {
Expand Down Expand Up @@ -44,49 +38,9 @@ export function AssetStatusBadge({
<Badge color={assetStatusColorMap(status)}>
{userFriendlyAssetStatus(status)}
</Badge>
{!availableToBook && <UnavailableBadge />}
{!availableToBook && (
<UnavailableBadge title="This asset is marked as unavailable for bookings" />
)}
</div>
);
}

const UnavailableBadge = (props: SVGProps<SVGSVGElement>) => (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<svg
xmlns="http://www.w3.org/2000/svg"
width={22}
height={22}
fill="none"
{...props}
>
<g
style={{
mixBlendMode: "multiply",
}}
>
<rect width={22} height={22} fill="#F2F4F7" rx={11} />
<rect width={22} height={22} stroke="#EAECF0" rx={11} />
<g clipPath="url(#a)">
<path
stroke="#667085"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
d="M15.5 10.75V9.4c0-.84 0-1.26-.164-1.581a1.5 1.5 0 0 0-.655-.656C14.361 7 13.941 7 13.1 7H8.9c-.84 0-1.26 0-1.581.163a1.5 1.5 0 0 0-.656.656c-.163.32-.163.74-.163 1.581v4.2c0 .84 0 1.26.163 1.581a1.5 1.5 0 0 0 .656.655c.32.164.74.164 1.581.164h2.35m4.25-6h-9M13 6v2M9 6v2m6.5 7.5L13 13m.1 2.5 2.4-2.5"
/>
</g>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M5 5h12v12H5z" />
</clipPath>
</defs>
</svg>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>This asset is marked as unavailable for bookings</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
19 changes: 17 additions & 2 deletions app/components/forms/fake-checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
export const FakeCheckbox = ({ checked }: { checked: boolean }) =>
import type { SVGProps } from "react";

type FakeCheckboxProps = SVGProps<SVGSVGElement> & {
checked?: boolean;
};

export const FakeCheckbox = ({ checked, ...svgProps }: FakeCheckboxProps) =>
checked ? (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...svgProps}
>
<rect x="0.5" y="0.5" width="19" height="19" rx="5.5" fill="#FEF6EE" />
<path
Expand All @@ -24,8 +31,16 @@ export const FakeCheckbox = ({ checked }: { checked: boolean }) =>
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...svgProps}
>
<rect x="0.5" y="0.5" width="19" height="19" rx="5.5" fill="white" />
<rect
x="0.5"
y="0.5"
width="19"
height="19"
rx="5.5"
fill="currentColor"
/>
<rect x="0.5" y="0.5" width="19" height="19" rx="5.5" stroke="#D0D5DD" />
</svg>
);
57 changes: 57 additions & 0 deletions app/components/icons/library.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1419,3 +1419,60 @@ export const CustomFiedIcon = (props: SVGProps<SVGSVGElement>) => (
/>
</svg>
);

export const KitIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
width="100%"
height="100%"
viewBox="0 0 22 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M15 5C15 4.07003 15 3.60504 14.8978 3.22354C14.6204 2.18827 13.8117 1.37962 12.7765 1.10222C12.395 1 11.93 1 11 1C10.07 1 9.60504 1 9.22354 1.10222C8.18827 1.37962 7.37962 2.18827 7.10222 3.22354C7 3.60504 7 4.07003 7 5M4.2 19H17.8C18.9201 19 19.4802 19 19.908 18.782C20.2843 18.5903 20.5903 18.2843 20.782 17.908C21 17.4802 21 16.9201 21 15.8V8.2C21 7.07989 21 6.51984 20.782 6.09202C20.5903 5.71569 20.2843 5.40973 19.908 5.21799C19.4802 5 18.9201 5 17.8 5H4.2C3.07989 5 2.51984 5 2.09202 5.21799C1.71569 5.40973 1.40973 5.71569 1.21799 6.09202C1 6.51984 1 7.07989 1 8.2V15.8C1 16.9201 1 17.4802 1.21799 17.908C1.40973 18.2843 1.71569 18.5903 2.09202 18.782C2.51984 19 3.0799 19 4.2 19Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);

export const GiveCustodyIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
width="100%"
height="100%"
viewBox="0 0 16 16"
{...props}
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
d="m12.666 14 2-2m0 0-2-2m2 2h-4M8 10.333H5c-.93 0-1.396 0-1.774.115a2.666 2.666 0 0 0-1.778 1.778c-.115.378-.115.844-.115 1.774m8.333-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
/>
</svg>
);

export const TakeCustodyIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
width="100%"
height="100%"
viewBox="0 0 16 16"
{...props}
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
d="m12.666 14-2-2m0 0 2-2m-2 2h4M8 10.333H5c-.93 0-1.396 0-1.774.115a2.666 2.666 0 0 0-1.778 1.778c-.115.378-.115.844-.115 1.774m8.333-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
/>
</svg>
);
Loading

0 comments on commit 9f70c78

Please sign in to comment.