added save button
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import { Infinite } from "../../productModels/productEnums.js";
|
||||
import { OnIncrease } from "./productItemEnums.js";
|
||||
import { OnDecrease } from "./productItemEnums.js";
|
||||
import { OnDecrease, OnIncrease } from "./productItemEnums.js";
|
||||
|
||||
export const TierInfinite = "inf";
|
||||
|
||||
@@ -95,8 +94,10 @@ export const LimitedItemSchema = ProductItemSchema.extend({
|
||||
});
|
||||
|
||||
export const FrontendProductItem = ProductItemSchema.extend({
|
||||
price: z.union([z.number(), z.string()]).nullish(),
|
||||
isPrice: z.boolean(),
|
||||
isVariable: z.boolean().nullish(),
|
||||
isBasePrice: z.boolean().nullish(),
|
||||
});
|
||||
|
||||
export type ProductItem = z.infer<typeof ProductItemSchema>;
|
||||
|
||||
@@ -85,9 +85,6 @@ export const productsAreSame = ({
|
||||
items1 = sanitizeItems({ items: items1, features });
|
||||
items2 = sanitizeItems({ items: items2, features });
|
||||
|
||||
console.log("Items 1:", items1);
|
||||
console.log("Items 2:", items2);
|
||||
|
||||
let itemsSame = true;
|
||||
let pricesChanged = false;
|
||||
const newItems: ProductItem[] = [];
|
||||
@@ -113,14 +110,14 @@ export const productsAreSame = ({
|
||||
if (items1.length !== items2.length) itemsSame = false;
|
||||
|
||||
for (const item of items1) {
|
||||
console.log("Item:", item);
|
||||
// console.log("Item:", item);
|
||||
|
||||
const similarItem = findSimilarItem({
|
||||
item,
|
||||
items: items2,
|
||||
});
|
||||
|
||||
console.log("Similar item:", similarItem);
|
||||
// console.log("Similar item:", similarItem);
|
||||
|
||||
if (!similarItem) {
|
||||
if (isFeaturePriceItem(item) || isPriceItem(item)) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import * as React from "react";
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { LoaderCircle, PlusIcon, Search } from "lucide-react";
|
||||
import { Tooltip, TooltipContent } from "./tooltip";
|
||||
import { TooltipTrigger } from "./tooltip";
|
||||
import * as React from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip";
|
||||
|
||||
// [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0
|
||||
|
||||
@@ -153,30 +151,6 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
} else {
|
||||
return Button;
|
||||
}
|
||||
return (
|
||||
<Comp
|
||||
{...props}
|
||||
className={cn(
|
||||
buttonVariants({ variant, size, className }),
|
||||
isIcon && `w-${dim} h-${dim} p-0`,
|
||||
)}
|
||||
ref={ref}
|
||||
onClick={(e) => {
|
||||
if (isLoading) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
props.onClick?.(e);
|
||||
}}
|
||||
>
|
||||
{isLoading && <LoaderCircle className="animate-spin" size={17} />}
|
||||
{startIcon && !isLoading && <>{startIcon}</>}
|
||||
{variant == "add" && <PlusIcon size={12} />}
|
||||
{children}
|
||||
{endIcon && !isLoading && <>{endIcon}</>}
|
||||
</Comp>
|
||||
);
|
||||
},
|
||||
);
|
||||
Button.displayName = "Button";
|
||||
|
||||
@@ -1,957 +0,0 @@
|
||||
<svg
|
||||
width="212"
|
||||
height="114"
|
||||
viewBox="0 0 212 114"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="211" height="114" transform="translate(0.5)" fill="#FAFAF9" />
|
||||
<path
|
||||
d="M11.3125 13.4375L12.625 14.75L15.6875 11.6875"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 18.25C16.3995 18.25 18.75 15.8995 18.75 13C18.75 10.1005 16.3995 7.75 13.5 7.75C10.6005 7.75 8.25 10.1005 8.25 13C8.25 15.8995 10.6005 18.25 13.5 18.25Z"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M35.5 18.25C38.3995 18.25 40.75 15.8995 40.75 13C40.75 10.1005 38.3995 7.75 35.5 7.75C32.6005 7.75 30.25 10.1005 30.25 13C30.25 15.8995 32.6005 18.25 35.5 18.25Z"
|
||||
stroke="#666666"
|
||||
stroke-miterlimit="10"
|
||||
/>
|
||||
<path
|
||||
d="M33.3125 13H37.6875"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M35.5 10.8125V15.1875"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M59.25 11.25L55.75 14.75"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M55.75 11.25L59.25 14.75"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M57.5 18.25C60.3995 18.25 62.75 15.8995 62.75 13C62.75 10.1005 60.3995 7.75 57.5 7.75C54.6005 7.75 52.25 10.1005 52.25 13C52.25 15.8995 54.6005 18.25 57.5 18.25Z"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M77.569 17.8126H75.125C75.009 17.8126 74.8977 17.7665 74.8156 17.6844C74.7336 17.6024 74.6875 17.4911 74.6875 17.3751V14.9311C74.6876 14.8152 74.7336 14.7041 74.8155 14.6221L81.5595 7.87804C81.6416 7.79605 81.7528 7.75 81.8688 7.75C81.9848 7.75 82.096 7.79605 82.178 7.87804L84.622 10.3204C84.704 10.4024 84.7501 10.5137 84.7501 10.6296C84.7501 10.7456 84.704 10.8569 84.622 10.9389L77.878 17.6846C77.796 17.7665 77.6849 17.8125 77.569 17.8126Z"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M79.9375 9.5L83 12.5625"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M103.623 15.122H104.132C104.845 15.122 105.201 15.122 105.474 14.9833C105.713 14.8612 105.908 14.6664 106.03 14.4269C106.169 14.1546 106.169 13.798 106.169 13.085V10.369C106.169 9.65602 106.169 9.29951 106.03 9.02717C105.908 8.78762 105.713 8.59285 105.474 8.47079C105.201 8.33203 104.845 8.33203 104.132 8.33203H101.416C100.703 8.33203 100.346 8.33203 100.074 8.47079C99.8345 8.59285 99.6397 8.78762 99.5177 9.02717C99.3789 9.29951 99.3789 9.65601 99.3789 10.369V10.8783"
|
||||
stroke="#666666"
|
||||
stroke-width="0.94"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M101.585 10.8779H98.869C98.156 10.8779 97.7995 10.8779 97.5272 11.0167C97.2876 11.1388 97.0929 11.3335 96.9708 11.5731C96.832 11.8454 96.832 12.2019 96.832 12.9149V15.6309C96.832 16.3439 96.832 16.7005 96.9708 16.9728C97.0929 17.2123 97.2876 17.4071 97.5272 17.5292C97.7995 17.6679 98.156 17.6679 98.869 17.6679H101.585C102.298 17.6679 102.655 17.6679 102.927 17.5292C103.166 17.4071 103.361 17.2123 103.483 16.9728C103.622 16.7005 103.622 16.3439 103.622 15.6309V12.9149C103.622 12.2019 103.622 11.8454 103.483 11.5731C103.361 11.3335 103.166 11.1388 102.927 11.0167C102.655 10.8779 102.298 10.8779 101.585 10.8779Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.94"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M128.168 9.6084H118.832"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M122.227 12.1514V15.5464"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M124.77 12.1514V15.5464"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M127.318 9.6084V17.6715C127.318 17.7841 127.274 17.892 127.194 17.9716C127.115 18.0512 127.007 18.0959 126.894 18.0959H120.104C119.992 18.0959 119.884 18.0512 119.804 17.9716C119.724 17.892 119.68 17.7841 119.68 17.6715V9.6084"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M125.619 9.60131V8.75256C125.619 8.52746 125.529 8.31157 125.37 8.1524C125.211 7.99323 124.995 7.90381 124.77 7.90381H122.224C121.999 7.90381 121.783 7.99323 121.624 8.1524C121.464 8.31157 121.375 8.52746 121.375 8.75256V9.60131"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M143.9 10.6C144.341 10.6 144.7 10.2418 144.7 9.8C144.7 9.35817 144.341 9 143.9 9C143.458 9 143.1 9.35817 143.1 9.8C143.1 10.2418 143.458 10.6 143.9 10.6Z"
|
||||
fill="#777777"
|
||||
/>
|
||||
<path
|
||||
d="M147.099 10.6C147.541 10.6 147.899 10.2418 147.899 9.8C147.899 9.35817 147.541 9 147.099 9C146.657 9 146.299 9.35817 146.299 9.8C146.299 10.2418 146.657 10.6 147.099 10.6Z"
|
||||
fill="#777777"
|
||||
/>
|
||||
<path
|
||||
d="M143.9 13.8002C144.341 13.8002 144.7 13.442 144.7 13.0002C144.7 12.5584 144.341 12.2002 143.9 12.2002C143.458 12.2002 143.1 12.5584 143.1 13.0002C143.1 13.442 143.458 13.8002 143.9 13.8002Z"
|
||||
fill="#777777"
|
||||
/>
|
||||
<path
|
||||
d="M147.099 13.8002C147.541 13.8002 147.899 13.442 147.899 13.0002C147.899 12.5584 147.541 12.2002 147.099 12.2002C146.657 12.2002 146.299 12.5584 146.299 13.0002C146.299 13.442 146.657 13.8002 147.099 13.8002Z"
|
||||
fill="#777777"
|
||||
/>
|
||||
<path
|
||||
d="M143.9 16.9999C144.341 16.9999 144.7 16.6417 144.7 16.1999C144.7 15.7581 144.341 15.3999 143.9 15.3999C143.458 15.3999 143.1 15.7581 143.1 16.1999C143.1 16.6417 143.458 16.9999 143.9 16.9999Z"
|
||||
fill="#777777"
|
||||
/>
|
||||
<path
|
||||
d="M147.099 16.9999C147.541 16.9999 147.899 16.6417 147.899 16.1999C147.899 15.7581 147.541 15.3999 147.099 15.3999C146.657 15.3999 146.299 15.7581 146.299 16.1999C146.299 16.6417 146.657 16.9999 147.099 16.9999Z"
|
||||
fill="#777777"
|
||||
/>
|
||||
<g clip-path="url(#clip0_411_1901)">
|
||||
<path
|
||||
d="M165.75 12.5625C168.166 12.5625 170.125 11.6811 170.125 10.5938C170.125 9.50644 168.166 8.625 165.75 8.625C163.334 8.625 161.375 9.50644 161.375 10.5938C161.375 11.6811 163.334 12.5625 165.75 12.5625Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M161.375 10.5938V12.7812C161.375 13.8684 163.334 14.75 165.75 14.75C168.166 14.75 170.125 13.8684 170.125 12.7812V10.5938"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M170.125 11.2896C172.123 11.4722 173.625 12.2663 173.625 13.2189C173.625 14.3061 171.666 15.1877 169.25 15.1877C168.178 15.1877 167.196 15.0143 166.436 14.7261"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M164.875 14.7106V15.4062C164.875 16.4934 166.834 17.375 169.25 17.375C171.666 17.375 173.625 16.4934 173.625 15.4062V13.2188"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</g>
|
||||
<g clip-path="url(#clip1_411_1901)">
|
||||
<path
|
||||
d="M187.537 13.1357C189.953 13.1357 191.912 12.2543 191.912 11.167C191.912 10.0797 189.953 9.19824 187.537 9.19824C185.121 9.19824 183.162 10.0797 183.162 11.167C183.162 12.2543 185.121 13.1357 187.537 13.1357Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M183.162 11.167V13.3545C183.162 14.4417 185.121 15.3232 187.537 15.3232C189.953 15.3232 191.912 14.4417 191.912 13.3545V11.167"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M191.912 11.8623C193.91 12.045 195.412 12.839 195.412 13.7917C195.412 14.8789 193.454 15.7604 191.037 15.7604C189.966 15.7604 188.983 15.5871 188.223 15.2989"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M186.662 15.2839V15.9795C186.662 17.0667 188.621 17.9482 191.037 17.9482C193.453 17.9482 195.412 17.0667 195.412 15.9795V13.792"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M193.344 7.69434L194.146 8.49707L196.02 6.62402"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M17.875 39.8125H9.125C9.00897 39.8125 8.89769 39.7664 8.81564 39.6844C8.73359 39.6023 8.6875 39.491 8.6875 39.375V31.9375L9.5625 30.1875H17.4375L18.3125 31.9375V39.375C18.3125 39.491 18.2664 39.6023 18.1844 39.6844C18.1023 39.7664 17.991 39.8125 17.875 39.8125Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M8.6875 31.9375H18.3125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 33.6875V38.0625"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M11.75 36.3125L13.5 38.0625L15.25 36.3125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.85"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M38.875 33.125L40 32L38.875 30.875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M31 35C31 34.2044 31.3161 33.4413 31.8787 32.8787C32.4413 32.3161 33.2044 32 34 32H40"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M32.125 36.875L31 38L32.125 39.125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M40 35C40 35.7956 39.6839 36.5587 39.1213 37.1213C38.5587 37.6839 37.7956 38 37 38H31"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M52.8809 35H62.1209"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M57.5 30.3799V39.6199"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M74.6875 35H84.3125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M80.375 31.0625L84.3125 35L80.375 38.9375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M106.312 35H96.6875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M100.625 31.0625L96.6875 35L100.625 38.9375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M123.5 32.375V35L125.688 36.3125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M120.438 33.6875H118.25V31.5"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M120.197 38.5002C120.885 39.1494 121.749 39.5814 122.681 39.7423C123.613 39.9033 124.572 39.786 125.438 39.4051C126.303 39.0242 127.038 38.3966 127.549 37.6007C128.06 36.8049 128.325 35.876 128.312 34.9302C128.298 33.9845 128.006 33.0637 127.472 32.283C126.938 31.5023 126.186 30.8962 125.309 30.5406C124.433 30.185 123.471 30.0955 122.544 30.2834C121.617 30.4713 120.766 30.9282 120.097 31.597C119.453 32.2489 118.922 32.8636 118.25 33.6877"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M145.5 40.25C148.399 40.25 150.75 37.8995 150.75 35C150.75 32.1005 148.399 29.75 145.5 29.75C142.601 29.75 140.25 32.1005 140.25 35C140.25 37.8995 142.601 40.25 145.5 40.25Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M145.5 31.9375V35H148.562"
|
||||
stroke="#666666"
|
||||
stroke-width="0.97"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M173.188 31.9288V38.0703C173.187 38.1476 173.165 38.2233 173.126 38.2896C173.086 38.3558 173.029 38.4102 172.961 38.447C172.893 38.4838 172.816 38.5017 172.739 38.4988C172.662 38.4959 172.586 38.4724 172.521 38.4306L167.699 35.3599C167.638 35.3215 167.588 35.2682 167.553 35.2052C167.518 35.1422 167.5 35.0715 167.5 34.9995C167.5 34.9276 167.518 34.8569 167.553 34.7939C167.588 34.7309 167.638 34.6776 167.699 34.6392L172.521 31.5685C172.586 31.5267 172.662 31.5032 172.739 31.5003C172.816 31.4974 172.893 31.5153 172.961 31.5521C173.029 31.5889 173.086 31.6433 173.126 31.7095C173.165 31.7758 173.187 31.8515 173.188 31.9288Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M167.5 31.9288V38.0703C167.499 38.1476 167.478 38.2233 167.438 38.2896C167.398 38.3558 167.341 38.4102 167.273 38.447C167.205 38.4838 167.129 38.5017 167.051 38.4988C166.974 38.4959 166.899 38.4724 166.834 38.4306L162.011 35.3599C161.95 35.3215 161.9 35.2682 161.866 35.2052C161.831 35.1422 161.813 35.0715 161.813 34.9995C161.813 34.9276 161.831 34.8569 161.866 34.7939C161.9 34.7309 161.95 34.6776 162.011 34.6392L166.834 31.5685C166.899 31.5267 166.974 31.5032 167.051 31.5003C167.129 31.4974 167.205 31.5153 167.273 31.5521C167.341 31.5889 167.398 31.6433 167.438 31.7095C167.478 31.7758 167.499 31.8515 167.5 31.9288Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 39.375C191.916 39.375 193.875 37.4162 193.875 35C193.875 32.5838 191.916 30.625 189.5 30.625C187.084 30.625 185.125 32.5838 185.125 35C185.125 37.4162 187.084 39.375 189.5 39.375Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 35H195.188"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 34.9999L186.656 30.0742"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 35L186.656 39.9257"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 30.625V29.3125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M185.711 32.8125L184.574 32.1562"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M185.125 35H183.812"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M185.711 37.1875L184.574 37.8438"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 39.375V40.6875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M191.688 38.7886L192.344 39.9255"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M193.289 37.1875L194.426 37.8438"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M193.289 32.8125L194.426 32.1562"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M191.688 31.2112L192.344 30.0742"
|
||||
stroke="#666666"
|
||||
stroke-width="0.84"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 62.25C16.3995 62.25 18.75 59.8995 18.75 57C18.75 54.1005 16.3995 51.75 13.5 51.75C10.6005 51.75 8.25 54.1005 8.25 57C8.25 59.8995 10.6005 62.25 13.5 62.25Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 51.75V53.9375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 60.0625V62.25"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M8.25 57H10.4375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M16.5625 57H18.75"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M38.5645 52.625H40.752V54.8125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M32.4375 61.375H30.25V59.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M40.752 59.1875V61.375H38.5645"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M30.25 54.8125V52.625H32.4375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M32.875 54.8125V59.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M38.125 54.8125V59.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M36.377 54.8125V59.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M34.625 54.8125V59.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M57.5 52.4873V56.9936"
|
||||
stroke="#666666"
|
||||
stroke-width="1.03"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M60.2036 52.938C61.56 53.8223 62.4567 55.2536 62.4567 56.9936C62.4567 58.3083 61.9345 59.5691 61.0049 60.4987C60.0753 61.4282 58.8145 61.9505 57.4998 61.9505C56.1852 61.9505 54.9244 61.4282 53.9948 60.4987C53.0652 59.5691 52.543 58.3083 52.543 56.9936C52.543 55.2536 53.4397 53.8223 54.7961 52.938"
|
||||
stroke="#666666"
|
||||
stroke-width="1.03"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M83.875 52.1875H75.125C74.8834 52.1875 74.6875 52.3834 74.6875 52.625V61.375C74.6875 61.6166 74.8834 61.8125 75.125 61.8125H83.875C84.1166 61.8125 84.3125 61.6166 84.3125 61.375V52.625C84.3125 52.3834 84.1166 52.1875 83.875 52.1875Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M82.125 51.3125V53.0625"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M76.875 51.3125V53.0625"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M74.6875 54.8125H84.3125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M77.5312 58.3125L78.8438 59.625L81.4688 57"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M106.278 53.3599H96.7225C96.2199 53.3599 95.8125 53.7673 95.8125 54.2699V59.7299C95.8125 60.2324 96.2199 60.6399 96.7225 60.6399H106.278C106.78 60.6399 107.188 60.2324 107.188 59.7299V54.2699C107.188 53.7673 106.78 53.3599 106.278 53.3599Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M102.637 55.1802V58.8202"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M100.363 55.1802V58.8202"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M98.0879 55.1802V58.8202"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<g clip-path="url(#clip2_411_1901)">
|
||||
<path
|
||||
d="M127.438 57.4375H130.062"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M128.75 56.125V58.75"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M122.406 58.75C124.218 58.75 125.688 57.2809 125.688 55.4688C125.688 53.6566 124.218 52.1875 122.406 52.1875C120.594 52.1875 119.125 53.6566 119.125 55.4688C119.125 57.2809 120.594 58.75 122.406 58.75Z"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M117.812 60.9375C118.936 59.6004 120.523 58.75 122.406 58.75C124.29 58.75 125.876 59.6004 127 60.9375"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</g>
|
||||
<g clip-path="url(#clip3_411_1901)">
|
||||
<path
|
||||
d="M144.406 58.75C146.218 58.75 147.688 57.2809 147.688 55.4688C147.688 53.6566 146.218 52.1875 144.406 52.1875C142.594 52.1875 141.125 53.6566 141.125 55.4688C141.125 57.2809 142.594 58.75 144.406 58.75Z"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M139.812 60.9375C140.936 59.6004 142.523 58.75 144.406 58.75C146.29 58.75 147.876 59.6004 149 60.9375"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M149.438 57.875L150.312 58.75L152.062 57"
|
||||
stroke="#666666"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M167.5 58.75C168.708 58.75 169.688 57.7706 169.688 56.5625C169.688 55.3544 168.708 54.375 167.5 54.375C166.292 54.375 165.312 55.3544 165.312 56.5625C165.312 57.7706 166.292 58.75 167.5 58.75Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M163.988 60.9031C164.317 60.2547 164.82 59.7102 165.439 59.3298C166.059 58.9494 166.772 58.748 167.499 58.748C168.226 58.748 168.939 58.9494 169.559 59.3298C170.179 59.7102 170.681 60.2547 171.01 60.9031"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M172.676 56.125C172.861 57.2217 172.692 58.3487 172.194 59.3432C171.697 60.3377 170.896 61.1483 169.907 61.658C168.919 62.1676 167.794 62.35 166.695 62.1786C165.597 62.0073 164.581 61.4912 163.794 60.7048C163.008 59.9185 162.492 58.9025 162.32 57.8037C162.149 56.7049 162.331 55.5801 162.841 54.5916C163.351 53.6032 164.161 52.8023 165.156 52.3046C166.15 51.8069 167.277 51.6382 168.374 51.8228"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M170.562 53.0625L171.438 53.9375L173.188 52.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 53.9375V54.8125"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 59.1875V60.0625"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M189.5 62.25C192.399 62.25 194.75 59.8995 194.75 57C194.75 54.1005 192.399 51.75 189.5 51.75C186.601 51.75 184.25 54.1005 184.25 57C184.25 59.8995 186.601 62.25 189.5 62.25Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M188.188 59.1875H190.156C190.446 59.1875 190.725 59.0723 190.93 58.8671C191.135 58.662 191.25 58.3838 191.25 58.0938C191.25 57.8037 191.135 57.5255 190.93 57.3204C190.725 57.1152 190.446 57 190.156 57H188.844C188.554 57 188.275 56.8848 188.07 56.6796C187.865 56.4745 187.75 56.1963 187.75 55.9062C187.75 55.6162 187.865 55.338 188.07 55.1329C188.275 54.9277 188.554 54.8125 188.844 54.8125H190.812"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 84.25C16.3995 84.25 18.75 81.8995 18.75 79C18.75 76.1005 16.3995 73.75 13.5 73.75C10.6005 73.75 8.25 76.1005 8.25 79C8.25 81.8995 10.6005 84.25 13.5 84.25Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.5 80.75C14.7081 80.75 15.6875 79.7706 15.6875 78.5625C15.6875 77.3544 14.7081 76.375 13.5 76.375C12.2919 76.375 11.3125 77.3544 11.3125 78.5625C11.3125 79.7706 12.2919 80.75 13.5 80.75Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M9.98828 82.9031C10.3175 82.2547 10.8197 81.7102 11.4394 81.3298C12.0591 80.9494 12.7721 80.748 13.4992 80.748C14.2264 80.748 14.9393 80.9494 15.559 81.3298C16.1787 81.7102 16.681 82.2547 17.0102 82.9031"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M32.9414 78.4968L33.9627 77.4754L32.9414 76.4541M34.9841 79.5181H37.0267"
|
||||
stroke="#666666"
|
||||
stroke-width="0.86"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M39.0749 74.4077H31.9256C31.3616 74.4077 30.9043 74.865 30.9043 75.429V82.5783C30.9043 83.1424 31.3616 83.5997 31.9256 83.5997H39.0749C39.639 83.5997 40.0963 83.1424 40.0963 82.5783V75.429C40.0963 74.865 39.639 74.4077 39.0749 74.4077Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.86"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M55.7198 78.7211C55.5428 78.2808 55.4525 77.8104 55.4538 77.3359C55.4538 75.3508 57.053 73.7011 59.0371 73.6378C59.544 73.6209 60.0489 73.7082 60.5206 73.8944C60.9924 74.0806 61.4208 74.3616 61.7795 74.7201C62.1382 75.0786 62.4195 75.507 62.6059 75.9786C62.7924 76.4502 62.88 76.9551 62.8634 77.462C62.798 79.4461 61.1483 81.0453 59.1632 81.0453C58.6887 81.0466 58.2183 80.9563 57.778 80.7793L57.1003 81.457H55.8654V82.6919H54.6305V83.9268H52.9839C52.8747 83.9268 52.77 83.8835 52.6928 83.8063C52.6156 83.7291 52.5723 83.6244 52.5723 83.5152V82.0389C52.5723 81.9299 52.6156 81.8253 52.6927 81.7482L55.7198 78.7211Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.87"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M60.1897 76.9317C60.5307 76.9317 60.8072 76.6553 60.8072 76.3142C60.8072 75.9732 60.5307 75.6968 60.1897 75.6968C59.8487 75.6968 59.5723 75.9732 59.5723 76.3142C59.5723 76.6553 59.8487 76.9317 60.1897 76.9317Z"
|
||||
fill="#666666"
|
||||
/>
|
||||
<path
|
||||
d="M79.5007 84.0927C82.3132 84.0927 84.5932 81.8127 84.5932 79.0002C84.5932 76.1877 82.3132 73.9077 79.5007 73.9077C76.6882 73.9077 74.4082 76.1877 74.4082 79.0002C74.4082 81.8127 76.6882 84.0927 79.5007 84.0927Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M79.5007 84.0927C82.3132 84.0927 84.5932 81.8127 84.5932 79.0002C84.5932 76.1877 82.3132 73.9077 79.5007 73.9077C76.6882 73.9077 74.4082 76.1877 74.4082 79.0002C74.4082 81.8127 76.6882 84.0927 79.5007 84.0927Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M78.6515 79.6212C78.3279 79.4344 78.0749 79.146 77.9319 78.8007C77.7889 78.4555 77.7639 78.0727 77.8606 77.7118C77.9573 77.3508 78.1704 77.0319 78.4669 76.8044C78.7633 76.5769 79.1266 76.4536 79.5002 76.4536C79.8739 76.4536 80.2371 76.5769 80.5336 76.8044C80.8301 77.0319 81.0432 77.3508 81.1399 77.7118C81.2366 78.0727 81.2115 78.4555 81.0685 78.8007C80.9255 79.146 80.6726 79.4344 80.349 79.6212L81.1977 81.5457H77.8027L78.6515 79.6212Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.8"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M99.8027 80.273C99.8027 80.9759 100.563 81.5461 101.5 81.5461C102.438 81.5461 103.198 80.9759 103.198 80.273C103.198 78.5755 99.8972 79.2121 99.8972 77.7267C99.8972 77.0239 100.563 76.4536 101.5 76.4536C102.203 76.4536 102.754 76.7719 102.986 77.2313"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M105.744 74.332H97.2564C97.022 74.332 96.832 74.522 96.832 74.7564V83.2439C96.832 83.4783 97.022 83.6683 97.2564 83.6683H105.744C105.978 83.6683 106.168 83.4783 106.168 83.2439V74.7564C106.168 74.522 105.978 74.332 105.744 74.332Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M128.169 76.4341H118.833C118.598 76.4341 118.408 76.6241 118.408 76.8585V78.556C118.408 78.7903 118.598 78.9803 118.833 78.9803H128.169C128.403 78.9803 128.593 78.7903 128.593 78.556V76.8585C128.593 76.6241 128.403 76.4341 128.169 76.4341Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M127.743 78.9805V82.7998C127.743 82.9124 127.699 83.0203 127.619 83.0999C127.539 83.1795 127.432 83.2242 127.319 83.2242H119.68C119.568 83.2242 119.46 83.1795 119.38 83.0999C119.301 83.0203 119.256 82.9124 119.256 82.7998V78.9805"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M123.5 76.4341V83.2241"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M126.088 73.846C126.584 74.3414 126.613 75.1753 126.088 75.64C125.191 76.4341 123.5 76.4341 123.5 76.4341C123.5 76.4341 123.5 74.743 124.296 73.846C124.759 73.3214 125.593 73.3505 126.088 73.846Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M120.912 73.846C120.416 74.3414 120.387 75.1753 120.912 75.64C121.809 76.4341 123.5 76.4341 123.5 76.4341C123.5 76.4341 123.5 74.743 122.704 73.846C122.241 73.3214 121.407 73.3505 120.912 73.846Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.873"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M145.5 84.0965V78.9899M144.99 83.9586C145.145 84.0483 145.321 84.0955 145.5 84.0955C145.68 84.0955 145.856 84.0483 146.011 83.9586L149.586 81.916C149.741 81.8264 149.87 81.6977 149.959 81.5426C150.049 81.3875 150.096 81.2116 150.096 81.0325V76.9472C150.096 76.7681 150.049 76.5922 149.959 76.4371C149.87 76.2821 149.741 76.1533 149.586 76.0638L146.011 74.0211C145.856 73.9315 145.68 73.8843 145.5 73.8843C145.321 73.8843 145.145 73.9315 144.99 74.0211L141.415 76.0638C141.26 76.1533 141.131 76.2821 141.041 76.4371C140.952 76.5922 140.904 76.7681 140.904 76.9472V81.0325C140.904 81.2116 140.952 81.3875 141.041 81.5426C141.131 81.6977 141.26 81.8264 141.415 81.916L144.99 83.9586Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.83"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M141.051 76.4458L145.499 78.9991L149.947 76.4458"
|
||||
stroke="#666666"
|
||||
stroke-width="0.83"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M162.904 74.4077V82.5783C162.904 82.8492 163.012 83.109 163.203 83.3005C163.395 83.4921 163.655 83.5997 163.926 83.5997H172.096"
|
||||
stroke="#666666"
|
||||
stroke-width="0.86"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M170.567 75.4233H169.546C169.264 75.4233 169.035 75.652 169.035 75.934V81.0407C169.035 81.3227 169.264 81.5513 169.546 81.5513H170.567C170.849 81.5513 171.078 81.3227 171.078 81.0407V75.934C171.078 75.652 170.849 75.4233 170.567 75.4233Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.86"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M166.473 76.9541H165.452C165.17 76.9541 164.941 77.1827 164.941 77.4648V81.0394C164.941 81.3215 165.17 81.5501 165.452 81.5501H166.473C166.755 81.5501 166.984 81.3215 166.984 81.0394V77.4648C166.984 77.1827 166.755 76.9541 166.473 76.9541Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.86"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M185.717 82.5437V75.4562C185.717 75.1429 185.841 74.8424 186.063 74.6209C186.284 74.3994 186.585 74.2749 186.898 74.2749H192.804C192.93 74.2749 193.05 74.3247 193.138 74.4133C193.227 74.5019 193.277 74.6221 193.277 74.7474V83.2524C193.277 83.3777 193.227 83.4979 193.138 83.5865C193.05 83.6751 192.93 83.7249 192.804 83.7249H186.898C186.585 83.7249 186.284 83.6004 186.063 83.3789C185.841 83.1574 185.717 82.8569 185.717 82.5437ZM185.717 82.5437C185.717 82.2304 185.841 81.9299 186.063 81.7084C186.284 81.4869 186.585 81.3624 186.898 81.3624H193.277"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M18.75 97.0625H8.25C8.00838 97.0625 7.8125 97.2584 7.8125 97.5V104.5C7.8125 104.742 8.00838 104.938 8.25 104.938H18.75C18.9916 104.938 19.1875 104.742 19.1875 104.5V97.5C19.1875 97.2584 18.9916 97.0625 18.75 97.0625Z"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M15.6875 103.188H17.4375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M13.0625 103.188H13.9375"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M7.8125 99.25H19.1875"
|
||||
stroke="#666666"
|
||||
stroke-width="0.95"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M39.8316 99.8189L39.8311 96.6694L36.6816 96.6689"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M35.8945 100.606L39.832 96.6689"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M38.2555 101.394V104.937C38.2555 105.042 38.214 105.142 38.1401 105.216C38.0663 105.29 37.9661 105.331 37.8617 105.331H31.5617C31.4573 105.331 31.3571 105.29 31.2833 105.216C31.2095 105.142 31.168 105.042 31.168 104.937V98.6374C31.168 98.533 31.2095 98.4328 31.2833 98.359C31.3571 98.2851 31.4573 98.2437 31.5617 98.2437H35.1055"
|
||||
stroke="#666666"
|
||||
stroke-width="0.9"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<defs>
|
||||
<clipPath id="clip0_411_1901">
|
||||
<rect
|
||||
width="14"
|
||||
height="14"
|
||||
fill="white"
|
||||
transform="translate(160.5 6)"
|
||||
/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_411_1901">
|
||||
<rect
|
||||
width="14"
|
||||
height="14"
|
||||
fill="white"
|
||||
transform="translate(182.5 6)"
|
||||
/>
|
||||
</clipPath>
|
||||
<clipPath id="clip2_411_1901">
|
||||
<rect
|
||||
width="14"
|
||||
height="14"
|
||||
fill="white"
|
||||
transform="translate(116.5 50)"
|
||||
/>
|
||||
</clipPath>
|
||||
<clipPath id="clip3_411_1901">
|
||||
<rect
|
||||
width="14"
|
||||
height="14"
|
||||
fill="white"
|
||||
transform="translate(138.5 50)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>;
|
||||
|
Before Width: | Height: | Size: 32 KiB |
@@ -1,14 +1,14 @@
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import type * as React from "react";
|
||||
|
||||
import * as React from "react";
|
||||
import SmallSpinner from "@/components/general/SmallSpinner";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
`inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-none
|
||||
|
||||
h-6 rounded-lg
|
||||
h-6 rounded-lg group/btn
|
||||
`,
|
||||
{
|
||||
variants: {
|
||||
@@ -16,24 +16,12 @@ const buttonVariants = cva(
|
||||
// Custom
|
||||
primary: `btn-primary-shadow !text-white bg-primary border border-transparent hover:bg-primary-btn-hover
|
||||
focus:bg-primary-btn-active focus:border-primary-btn-border`,
|
||||
|
||||
secondary:
|
||||
"bg-white border border-input hover:border-primary hover:bg-hover-primary focus:bg-active-primary focus:border-primary btn-secondary-shadow",
|
||||
|
||||
// destructive:
|
||||
// "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||
// outline:
|
||||
// "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||
// secondary:
|
||||
// "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
// ghost:
|
||||
// "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
// link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "py-1 !px-[7px] text-body has-[>svg]:px-3",
|
||||
// sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||
// lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||
// icon: "size-9",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
@@ -43,25 +31,78 @@ const buttonVariants = cva(
|
||||
},
|
||||
);
|
||||
|
||||
export interface ButtonProps
|
||||
extends React.ComponentProps<"button">,
|
||||
VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
function Button({
|
||||
className,
|
||||
variant,
|
||||
size,
|
||||
asChild = false,
|
||||
isLoading = false,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<"button"> &
|
||||
VariantProps<typeof buttonVariants> & {
|
||||
asChild?: boolean;
|
||||
}) {
|
||||
}: ButtonProps) {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
const buttonRef = React.useRef<HTMLButtonElement>(null);
|
||||
const [contentWidth, setContentWidth] = React.useState<number | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (buttonRef.current && !isLoading) {
|
||||
// Measure the full button width including padding
|
||||
const width = buttonRef.current.offsetWidth;
|
||||
setContentWidth(width);
|
||||
}
|
||||
}, [isLoading]);
|
||||
|
||||
// Measure width on mount and when loading state changes
|
||||
React.useEffect(() => {
|
||||
if (buttonRef.current && !isLoading) {
|
||||
// Use requestAnimationFrame to ensure DOM is fully rendered
|
||||
requestAnimationFrame(() => {
|
||||
if (buttonRef.current) {
|
||||
const width = buttonRef.current.offsetWidth;
|
||||
setContentWidth(width);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [isLoading]);
|
||||
|
||||
return (
|
||||
<Comp
|
||||
ref={buttonRef}
|
||||
data-slot="button"
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
style={{
|
||||
minWidth:
|
||||
isLoading && contentWidth
|
||||
? `${contentWidth + 0.2}px` // Add small buffer to prevent any slight width changes
|
||||
: undefined,
|
||||
}}
|
||||
disabled={isLoading || props.disabled}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{isLoading ? <SmallSpinner size={14} /> : children}
|
||||
</Comp>
|
||||
);
|
||||
}
|
||||
|
||||
export { Button, buttonVariants };
|
||||
|
||||
// destructive:
|
||||
// "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||
// outline:
|
||||
// "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||
// secondary:
|
||||
// "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
// ghost:
|
||||
// "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
// link: "text-primary underline-offset-4 hover:underline",
|
||||
|
||||
// sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||
// lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||
// icon: "size-9",
|
||||
|
||||
43
vite/src/components/v2/buttons/ShortcutButton.tsx
Normal file
43
vite/src/components/v2/buttons/ShortcutButton.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { Button, type ButtonProps } from "@/components/v2/buttons/Button";
|
||||
|
||||
export const ShortcutButton = ({
|
||||
metaShortcut,
|
||||
children,
|
||||
isLoading,
|
||||
...props
|
||||
}: {
|
||||
metaShortcut: string;
|
||||
children: React.ReactNode;
|
||||
isLoading?: boolean;
|
||||
} & ButtonProps) => {
|
||||
const getMetaKey = () => {
|
||||
if (navigator.userAgent.includes("Mac")) {
|
||||
return "⌘";
|
||||
}
|
||||
return "Ctrl";
|
||||
};
|
||||
|
||||
useHotkeys([`meta+${metaShortcut}`], (e) => {
|
||||
e.preventDefault();
|
||||
props?.onClick?.(e as unknown as React.MouseEvent<HTMLButtonElement>);
|
||||
});
|
||||
|
||||
const keystrokeContainer = (keyStroke: string) => (
|
||||
<div className="bg-[#B07AFF] text-primary-foreground flex items-center justify-center size-4 rounded-md">
|
||||
{keyStroke}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<Button isLoading={isLoading} {...props}>
|
||||
{children}
|
||||
{metaShortcut && (
|
||||
<span className="flex items-center gap-0.5">
|
||||
{keystrokeContainer(getMetaKey())} +{" "}
|
||||
{keystrokeContainer(metaShortcut.toUpperCase())}
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import type React from "react";
|
||||
import { useId } from "react";
|
||||
import { Input } from "./input";
|
||||
import { Input } from "./Input";
|
||||
|
||||
export const LabelInput = ({
|
||||
label,
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { AppEnv } from "@autumn/shared";
|
||||
import type { AxiosError } from "axios";
|
||||
import type { NavigateFunction } from "react-router-dom";
|
||||
|
||||
export const compareStatus = (statusA: string, statusB: string) => {
|
||||
const statusOrder = ["scheduled", "active", "past_due", "expired"];
|
||||
return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB);
|
||||
};
|
||||
|
||||
export const invalidNumber = (value: any) => {
|
||||
return isNaN(parseFloat(value));
|
||||
export const invalidNumber = (value: unknown) => {
|
||||
return Number.isNaN(parseFloat(value as string));
|
||||
};
|
||||
|
||||
export const getBackendErr = (error: any, defaultText: string) => {
|
||||
if (error.response && error.response.data) {
|
||||
const data = error.response.data;
|
||||
export const getBackendErr = (error: AxiosError, defaultText: string) => {
|
||||
if (error.response?.data) {
|
||||
const data = error.response.data as { message: string; code: string };
|
||||
if (data.message && data.code) {
|
||||
return data.message;
|
||||
} else {
|
||||
@@ -22,9 +24,9 @@ export const getBackendErr = (error: any, defaultText: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getBackendErrObj = (error: any) => {
|
||||
if (error.response && error.response.data) {
|
||||
const data = error.response.data;
|
||||
export const getBackendErrObj = (error: AxiosError) => {
|
||||
if (error.response?.data) {
|
||||
const data = error.response.data as { code: string; message: string };
|
||||
if (data.code) {
|
||||
return { code: data.code, message: data.message };
|
||||
}
|
||||
@@ -49,7 +51,11 @@ export const envToPath = (env: AppEnv, currentPath: string) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const navigateTo = (path: string, navigate: any, env?: AppEnv) => {
|
||||
export const navigateTo = (
|
||||
path: string,
|
||||
navigate: NavigateFunction,
|
||||
env?: AppEnv,
|
||||
) => {
|
||||
const curPath = window.location.pathname;
|
||||
const curEnv = getEnvFromPath(curPath);
|
||||
|
||||
@@ -69,7 +75,7 @@ export const pushPage = ({
|
||||
}: {
|
||||
path: string;
|
||||
queryParams?: Record<string, string | undefined>;
|
||||
navigate?: any;
|
||||
navigate?: NavigateFunction;
|
||||
preserveParams?: boolean;
|
||||
}) => {
|
||||
const pathname = window.location.pathname;
|
||||
@@ -117,10 +123,23 @@ export const getRedirectUrl = (path: string, env: AppEnv) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const notNullish = (value: any) => {
|
||||
export const notNullish = (value: unknown) => {
|
||||
return value !== null && value !== undefined;
|
||||
};
|
||||
|
||||
export const nullish = (value: any) => {
|
||||
export const nullish = (value: unknown) => {
|
||||
return value === null || value === undefined;
|
||||
};
|
||||
|
||||
export const parseNumberInput = ({
|
||||
value,
|
||||
fallback = 0,
|
||||
}: {
|
||||
value?: string;
|
||||
fallback?: number;
|
||||
}): number | null => {
|
||||
if (value === undefined) return fallback;
|
||||
|
||||
const numValue = Number.parseFloat(value);
|
||||
return Number.isNaN(numValue) ? fallback : numValue;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createBrowserClient } from "@supabase/ssr";
|
||||
|
||||
export function createClient() {
|
||||
return createBrowserClient(
|
||||
import.meta.env.VITE_SUPABASE_URL!,
|
||||
import.meta.env.VITE_SUPABASE_ANON_KEY!,
|
||||
import.meta.env.VITE_SUPABASE_URL || "",
|
||||
import.meta.env.VITE_SUPABASE_ANON_KEY || "",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ManagePlan } from "./components/Editor";
|
||||
import { EditPlanHeader } from "./components/EditPlanHeader";
|
||||
import { EditPlanItemSheet } from "./components/EditPlanItemSheet";
|
||||
import { EditPlanSheet } from "./components/EditPlanSheet";
|
||||
import { SaveChangesBar } from "./components/SaveChanges";
|
||||
import { SaveChangesBar } from "./components/SaveChangesBar";
|
||||
import { usePlanData } from "./hooks/usePlanData";
|
||||
|
||||
type Sheets = "edit-plan" | "edit-feature" | null;
|
||||
@@ -62,7 +62,7 @@ export default function PlanEditorView() {
|
||||
setOpen={setShowNewVersionDialog}
|
||||
/>
|
||||
<div className="flex w-full h-full overflow-y-auto bg-[#eee]">
|
||||
<div className="flex flex-col justify-between h-full flex-1">
|
||||
<div className="flex flex-col justify-between h-full flex-1 min-w-0">
|
||||
{/* <div className="flex-1"> */}
|
||||
<EditPlanHeader />
|
||||
<ManagePlan />
|
||||
@@ -117,10 +117,7 @@ export const PlanSheets = ({ sheet }: { sheet: Sheets }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="gap-4 sheet-content min-w-md max-w-md bg-card z-50 border-l shadow-sm flex flex-col overflow-y-auto pb-20 h-full
|
||||
"
|
||||
>
|
||||
<div className="w-full max-w-md bg-card z-50 border-l shadow-sm flex flex-col overflow-y-auto h-full">
|
||||
{renderSheet()}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,7 +9,9 @@ export const AddFeatureRow = ({ onClick, disabled }: AddFeatureRowProps) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="group/btn flex items-center justify-center bg-white border border-border rounded-lg h-[30px] w-full shadow-[0px_4px_4px_rgba(0,0,0,0.02),_inset_0px_-3px_4px_rgba(0,0,0,0.04)] cursor-pointer transition-colors disabled:opacity-50 disabled:cursor-not-allowed form-input"
|
||||
className="group/btn flex items-center justify-center bg-white border border-border rounded-lg h-[30px] w-full
|
||||
shadow-[0px_4px_4px_rgba(0,0,0,0.02),_inset_0px_-3px_4px_rgba(0,0,0,0.04)]
|
||||
cursor-pointer duration-none"
|
||||
onClick={onClick}
|
||||
tabIndex={0}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function PlanCard({ product }: { product: ProductV2 }) {
|
||||
editingState.type === "plan" && editingState.id === product.id;
|
||||
|
||||
return (
|
||||
<Card className="min-w-[70%] max-w-[90%] bg-card">
|
||||
<Card className="min-w-sm max-w-xl mx-auto bg-card">
|
||||
<CardHeader>
|
||||
<div className="flex flex-row items-center justify-between gap-2 w-full whitespace-nowrap">
|
||||
<div className="flex flex-row items-baseline gap-2">
|
||||
|
||||
@@ -13,7 +13,6 @@ export const PlanFeatureList = () => {
|
||||
};
|
||||
|
||||
const handleEdit = (item: ProductItem) => {
|
||||
console.log("Edit feature:", item);
|
||||
const itemId =
|
||||
item.entitlement_id ||
|
||||
item.price_id ||
|
||||
@@ -23,12 +22,10 @@ export const PlanFeatureList = () => {
|
||||
};
|
||||
|
||||
const handleDelete = (item: ProductItem) => {
|
||||
console.log("Delete feature:", item);
|
||||
// Add your delete logic here
|
||||
};
|
||||
|
||||
const handleAddFeature = () => {
|
||||
console.log("Add new feature");
|
||||
setEditingState({ type: "feature", id: "new" });
|
||||
setSheet("edit-feature");
|
||||
};
|
||||
|
||||
@@ -40,7 +40,10 @@ export const PlanFeatureRow = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="group flex flex-row items-center bg-white border border-border rounded-lg h-[30px] w-full px-[7px] py-[6px] gap-1 shadow-[0px_4px_4px_rgba(0,0,0,0.02),_inset_0px_-3px_4px_rgba(0,0,0,0.04)] form-input">
|
||||
<div
|
||||
className="group flex flex-row items-center bg-white border border-border rounded-lg h-[30px] w-full
|
||||
input-base input-shadow duration-none"
|
||||
>
|
||||
{/* Left side - Icons and text */}
|
||||
<div className="flex flex-row items-center flex-1 gap-2 min-w-0">
|
||||
{/* Icon container */}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { Button } from "@/components/v2/buttons/Button";
|
||||
import { useProductContext } from "../../product/ProductContext";
|
||||
|
||||
export const SaveChangesBar = () => {
|
||||
const { hasChanges } = useProductContext();
|
||||
// if (!hasChanges) return null;
|
||||
|
||||
const handleSave = () => {
|
||||
// TODO: Implement save functionality
|
||||
console.log("Save changes");
|
||||
};
|
||||
|
||||
const handleDiscard = () => {
|
||||
// TODO: Implement discard functionality
|
||||
console.log("Discard changes");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full flex justify-center items-center h-20 mb-10">
|
||||
<div className="flex items-center gap-2 p-2 pl-3 rounded-xl border border-input bg-white">
|
||||
<p className="text-body">You have unsaved changes</p>
|
||||
<Button variant="secondary" onClick={handleSave}>
|
||||
Discard
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleSave}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
62
vite/src/views/products/plan/components/SaveChangesBar.tsx
Normal file
62
vite/src/views/products/plan/components/SaveChangesBar.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/v2/buttons/Button";
|
||||
import { ShortcutButton } from "@/components/v2/buttons/ShortcutButton";
|
||||
import { useAxiosInstance } from "@/services/useAxiosInstance";
|
||||
import { useProductCountsQuery } from "../../product/hooks/queries/useProductCountsQuery";
|
||||
import { useProductQuery } from "../../product/hooks/useProductQuery";
|
||||
import { useProductContext } from "../../product/ProductContext";
|
||||
import { updateProduct } from "../../product/utils/updateProduct";
|
||||
|
||||
export const SaveChangesBar = () => {
|
||||
const { hasChanges } = useProductContext();
|
||||
const axiosInstance = useAxiosInstance();
|
||||
const [saving, setSaving] = useState(false);
|
||||
const { product, setShowNewVersionDialog } = useProductContext();
|
||||
const { counts, isLoading } = useProductCountsQuery();
|
||||
const { refetch } = useProductQuery();
|
||||
|
||||
const handleSaveClicked = async () => {
|
||||
if (isLoading) toast.error("Product counts are loading");
|
||||
|
||||
if (counts?.all > 0) {
|
||||
setShowNewVersionDialog(true);
|
||||
return;
|
||||
}
|
||||
|
||||
setSaving(true);
|
||||
await updateProduct({
|
||||
axiosInstance,
|
||||
product,
|
||||
onSuccess: async () => {
|
||||
await refetch();
|
||||
},
|
||||
});
|
||||
|
||||
setSaving(false);
|
||||
};
|
||||
|
||||
const handleDiscardClicked = () => {
|
||||
// TODO: Implement discard functionality
|
||||
};
|
||||
|
||||
if (!hasChanges) return null;
|
||||
|
||||
return (
|
||||
<div className="w-full flex justify-center items-center h-20 mb-10">
|
||||
<div className="flex items-center gap-2 p-2 pl-3 rounded-xl border border-input bg-white">
|
||||
<p className="text-body">You have unsaved changes</p>
|
||||
<Button variant="secondary" onClick={handleDiscardClicked}>
|
||||
Discard
|
||||
</Button>
|
||||
<ShortcutButton
|
||||
metaShortcut="s"
|
||||
onClick={handleSaveClicked}
|
||||
isLoading={saving}
|
||||
>
|
||||
Save
|
||||
</ShortcutButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
BillingInterval,
|
||||
billingToItemInterval,
|
||||
isPriceItem,
|
||||
notNullish,
|
||||
nullish,
|
||||
type ProductItem,
|
||||
productV2ToBasePrice,
|
||||
@@ -36,7 +37,7 @@ export const BasePriceSection = () => {
|
||||
amount,
|
||||
interval,
|
||||
}: {
|
||||
amount?: number;
|
||||
amount?: string;
|
||||
interval?: BillingInterval;
|
||||
}) => {
|
||||
const newItems = [...product.items];
|
||||
@@ -45,14 +46,24 @@ export const BasePriceSection = () => {
|
||||
);
|
||||
|
||||
if (basePriceIndex !== -1) {
|
||||
const newAmount =
|
||||
amount === ""
|
||||
? amount
|
||||
: notNullish(amount)
|
||||
? Number.parseFloat(amount ?? "")
|
||||
: basePrice?.amount;
|
||||
|
||||
newItems[basePriceIndex] = {
|
||||
...newItems[basePriceIndex],
|
||||
price: amount ?? basePrice?.amount,
|
||||
price: newAmount,
|
||||
interval: interval
|
||||
? billingToItemInterval(interval)
|
||||
: basePrice?.interval,
|
||||
|
||||
isBasePrice: true,
|
||||
};
|
||||
}
|
||||
|
||||
setProduct({
|
||||
...product,
|
||||
items: newItems,
|
||||
@@ -94,7 +105,7 @@ export const BasePriceSection = () => {
|
||||
value={basePrice?.amount ?? ""}
|
||||
onChange={(e) => {
|
||||
handleUpdateBasePrice({
|
||||
amount: e.target.value as unknown as number,
|
||||
amount: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { FrontendProductItem } from "@autumn/shared";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export const validateItemsBeforeSave = (items: FrontendProductItem[]) => {
|
||||
for (const item of items) {
|
||||
if (item.isBasePrice) {
|
||||
if (typeof item.price !== "number" && !item.price) {
|
||||
toast.error("Base price cannot be empty");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@@ -1,22 +1,31 @@
|
||||
import { type ProductV2, UpdateProductSchema } from "@autumn/shared";
|
||||
import type { AxiosInstance } from "axios";
|
||||
import {
|
||||
type FrontendProductItem,
|
||||
type ProductV2,
|
||||
UpdateProductSchema,
|
||||
} from "@autumn/shared";
|
||||
import type { AxiosError, AxiosInstance } from "axios";
|
||||
import { toast } from "sonner";
|
||||
import { ProductService } from "@/services/products/ProductService";
|
||||
import { getBackendErr } from "@/utils/genUtils";
|
||||
import { validateItemsBeforeSave } from "../../plan/utils/validateItemsBeforeSave";
|
||||
|
||||
export const updateProduct = async ({
|
||||
axiosInstance,
|
||||
product,
|
||||
onSuccess,
|
||||
// mutate,
|
||||
// mutateCount,
|
||||
}: {
|
||||
axiosInstance: AxiosInstance;
|
||||
product: ProductV2;
|
||||
onSuccess: () => Promise<void>;
|
||||
// mutate: () => void;
|
||||
// mutateCount: () => void;
|
||||
}) => {
|
||||
const validated = validateItemsBeforeSave(
|
||||
product.items as FrontendProductItem[],
|
||||
);
|
||||
|
||||
console.log("validated", validated);
|
||||
if (!validated) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
await ProductService.updateProduct(axiosInstance, product.id, {
|
||||
...UpdateProductSchema.parse(product),
|
||||
@@ -30,7 +39,7 @@ export const updateProduct = async ({
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error(getBackendErr(error, "Failed to update product"));
|
||||
toast.error(getBackendErr(error as AxiosError, "Failed to update product"));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user