Skip to content

Commit

Permalink
Merge pull request #211 from wri/feat/add_modal_design
Browse files Browse the repository at this point in the history
Feat/Edit Modal Component and Add Modal Types
  • Loading branch information
dottyy authored May 28, 2024
2 parents fdc45ef + e4d954b commit 18ec8ac
Show file tree
Hide file tree
Showing 21 changed files with 1,286 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/components/elements/Commentary/Commentary.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ export const Default: Story = {
date: "Oct 6, 2022 at 1:12 AM",
comentary: `Don't see the outline. the source code also needs to be updated.re: aligned to one source. we need to make sure whether this is appropriate. consider that we have the organization in sign-up/profile, mask, and work request boards. On Thursday will provide the the source tables requested`,
files: comentaryFiles,
status: "Submitted"
status: "submitted"
}
};
6 changes: 3 additions & 3 deletions src/components/elements/Commentary/Commentary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ export interface ComentaryProps {
lastName: string;
date: string;
comentary: string;
status?: "Submitted" | "Draft";
status?: "draft" | "submitted";
files?: ComentaryFilesProps[];
}

const statusStyle = {
Submitted: { container: "bg-primary-200", textColor: "text-primary" },
Draft: { container: "bg-pinkCustom-200", textColor: "text-pinkCustom" }
submitted: { container: "bg-primary-200", textColor: "text-primary" },
draft: { container: "bg-pinkCustom-200", textColor: "text-pinkCustom" }
};

const Comentary = (props: ComentaryProps) => {
Expand Down
61 changes: 41 additions & 20 deletions src/components/elements/Status/Status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,60 @@ import Text from "../Text/Text";

export interface StatusProps {
className?: string;
status: "Draft" | "Submitted" | "Approved" | "Under Review" | "Needs More Info" | "Planting in Progress";
status:
| "draft"
| "submitted"
| "approved"
| "under-review"
| "needs-more-information"
| "planting-in-progress"
| "awaiting-approval";
textVariant?: TextVariants;
}

const Status = (props: StatusProps) => {
const { className, status, textVariant = "text-12-semibold" } = props;

const convertStatusToReadableStatus = (status: string): string => {
const statusMap: { [key: string]: string } = {
approved: "Approved",
submitted: "Submitted",
draft: "Draft",
"under-review": "Under Review",
"needs-more-information": "Needs More Information",
"planting-in-progress": "Planting in Progress",
"awaiting-approval": "Awaiting Approval"
};

return statusMap[status] || "";
};

const getColorStatusText = (status: string): string => {
const colorMap: { [key: string]: string } = {
Approved: "text-green-500",
Submitted: "text-blue",
Draft: "text-pinkCustom",
"Under Review": "text-tertiary-600",
"Needs More Info": "text-tertiary-600",
"Planting in Progress": "text-blue"
approved: "text-green-500",
submitted: "text-blue",
draft: "text-pinkCustom",
"under-review": "text-tertiary-600",
"needs-more-information": "text-tertiary-600",
"planting-in-progress": "text-blue",
"awaiting-approval": "text-tertiary-600"
};

return colorMap[status] ?? "";
return colorMap[status] || "";
};

const getColorStatusBg = (status: string): string => {
const colorMap: { [key: string]: string } = {
Approved: "bg-secondary-200",
Submitted: "bg-blue-200",
Draft: "bg-pinkCustom-200",
"Under Review": "bg-tertiary-50",
"Awaiting approval": "bg-tertiary-50",
"Needs More Info": "bg-tertiary-50",
"Needs more information": "bg-tertiary-50",
"Planting in Progress": "bg-blue-200"
approved: "bg-secondary-200",
submitted: "bg-blue-200",
draft: "bg-pinkCustom-200",
"under-review": "bg-tertiary-50",
"awaiting-approval": "bg-tertiary-50",
"needs-more-information": "bg-tertiary-50",
"planting-in-progress": "bg-blue-200"
};

return colorMap[status] ?? "";
return colorMap[status] || "";
};

return (
Expand All @@ -49,12 +70,12 @@ const Status = (props: StatusProps) => {
>
<Text
variant={textVariant}
className={`flex w-fit items-center gap-[6px] whitespace-nowrap ${getColorStatusText(status)}`}
className={`flex w-fit items-center justify-center gap-[6px] text-center ${getColorStatusText(status)}`}
>
<When condition={status === "Approved"}>
<When condition={status === "approved"}>
<Icon name={IconNames.CHECK_CIRCLE_FILL} className="h-4 w-4 text-secondary" />
</When>
{status}
{convertStatusToReadableStatus(status)}
</Text>
</div>
);
Expand Down
10 changes: 7 additions & 3 deletions src/components/extensive/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface CarouselProps<T> extends SwiperProps {
swiperButtonsClassName?: string;
hidePaginationBullet?: boolean;
breakpoints?: CarouselBreakPoints;
setSelectedImage?: (index: number) => void;
setSelectecImage?: (index: number) => void;
buttonsOutside?: boolean;
smallSwiperButtons?: boolean;
}
Expand All @@ -38,7 +38,7 @@ const Carousel = <T extends Record<any, any>>({
swiperSlideClassName,
swiperButtonsClassName,
hidePaginationBullet,
setSelectedImage,
setSelectecImage,
buttonsOutside = false,
smallSwiperButtons,
...swiperProps
Expand All @@ -47,7 +47,11 @@ const Carousel = <T extends Record<any, any>>({

const swiperButtonSize = smallSwiperButtons ? 12 : 24;

const handleSlideChange = (swiper: { activeIndex: any }) => setSelectedImage?.(swiper.activeIndex);
const handleSlideChange = (swiper: { activeIndex: any }) => {
if (setSelectecImage) {
setSelectecImage(swiper.activeIndex);
}
};

return (
<div className={classNames("relative mx-auto", className)}>
Expand Down
6 changes: 3 additions & 3 deletions src/components/extensive/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from "classnames";
import { DetailedHTMLProps, FC, HTMLAttributes } from "react";
import { DetailedHTMLProps, FC, HTMLAttributes, ReactNode } from "react";
import { When } from "react-if";
import { twMerge } from "tailwind-merge";

Expand All @@ -12,8 +12,8 @@ export type ModalBaseProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, H
export interface ModalProps extends ModalBaseProps {
title: string;
iconProps?: IconProps;
content?: string;
primaryButtonProps: IButtonProps;
content?: ReactNode;
primaryButtonProps?: IButtonProps;
secondaryButtonProps?: IButtonProps;
}

Expand Down
36 changes: 36 additions & 0 deletions src/components/extensive/Modal/ModalAdd.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Meta, StoryObj } from "@storybook/react";

import Text from "@/components/elements/Text/Text";

import { ModalProps as Props } from "./Modal";
import Component from "./ModalAdd";

const meta: Meta<typeof Component> = {
title: "Components/Extensive/Modal/ModalAdd",
component: Component
};

export default meta;
type Story = StoryObj<typeof Component>;

export const Default: Story = {
render: (args: Props) => (
<div className="flex items-center justify-center bg-primary-400 p-8">
<Component onCLose={() => {}} {...args} />
</div>
),
args: {
title: "Add Polygons",
descriptionInput: "Drag and drop a GeoJSON, Shapefile, or KML for your site Tannous/Brayton Road.",
descriptionList: (
<div className="mt-9 flex">
<Text variant="text-12-bold">TerraMatch upload limits:&nbsp;</Text>
<Text variant="text-12-light">50 MB per upload</Text>
</div>
),
onCLose: () => {},
content: "Start by adding polygons to your site.",
primaryButtonText: "Close",
primaryButtonProps: { className: "px-8 py-3", variant: "primary", onClick: () => {} }
}
};
156 changes: 156 additions & 0 deletions src/components/extensive/Modal/ModalAdd.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { remove } from "lodash";
import React, { FC, ReactNode, useEffect, useState } from "react";
import { When } from "react-if";
import { twMerge } from "tailwind-merge";

import Button from "@/components/elements/Button/Button";
import FileInput from "@/components/elements/Inputs/FileInput/FileInput";
import {
FileInputVariant,
VARIANT_FILE_INPUT_MODAL_ADD
} from "@/components/elements/Inputs/FileInput/FileInputVariants";
import Status from "@/components/elements/Status/Status";
import Text from "@/components/elements/Text/Text";
import { FileType, UploadedFile } from "@/types/common";

import Icon, { IconNames } from "../Icon/Icon";
import { ModalBaseProps, ModalProps } from "./Modal";

export const ModalAddBase: FC<ModalBaseProps> = ({ children, className, ...rest }) => {
return (
<div
{...rest}
className={twMerge(
"margin-4 z-50 m-auto flex h-[80%] max-h-full w-[776px] flex-col items-center justify-start overflow-y-auto rounded-lg border-2 border-neutral-100 bg-white",
className
)}
>
{children}
</div>
);
};

export interface ModalAddProps extends ModalProps {
primaryButtonText?: string;
secondaryButtonText?: string;
descriptionInput?: string;
descriptionList?: ReactNode;
variantFileInput?: FileInputVariant;
descriptionListStatus?: string;
acceptedTYpes?: FileType[];
status?: "under-review" | "approved" | "draft" | "submitted";
onCLose?: () => void;
setFile?: (file: UploadedFile[]) => void;
}

const ModalAdd: FC<ModalAddProps> = ({
iconProps,
title,
content,
primaryButtonProps,
primaryButtonText,
secondaryButtonProps,
secondaryButtonText,
descriptionInput,
descriptionList,
descriptionListStatus,
acceptedTYpes,
variantFileInput = VARIANT_FILE_INPUT_MODAL_ADD,
children,
status,
setFile,
onCLose,
...rest
}) => {
const [files, setFiles] = useState<UploadedFile[]>([]);

useEffect(() => {
if (setFile && files) {
console.log("gets here", files);
setFile(files);
}
}, [files]);

return (
<ModalAddBase {...rest}>
<header className="flex w-full items-center justify-between border-b border-b-neutral-200 px-8 py-5">
<Icon name={IconNames.WRI_LOGO} width={108} height={30} className="min-w-[108px]" />
<div className="flex items-center">
<When condition={status}>
<Status status={status ? status : "draft"} className="rounded px-2 py-[2px]" textVariant="text-14-bold" />
</When>
<button onClick={onCLose} className="ml-2 rounded p-1 hover:bg-grey-800">
<Icon name={IconNames.CLEAR} width={16} height={16} className="text-darkCustom-100" />
</button>
</div>
</header>
<div className="max-h-[100%] w-full overflow-auto px-8 py-8">
<When condition={!!iconProps}>
<Icon
{...iconProps!}
width={iconProps?.width || 40}
className={twMerge("mb-8", iconProps?.className)}
style={{ minHeight: iconProps?.height || iconProps?.width || 40 }}
/>
</When>
<div className="flex items-center justify-between">
<Text variant="text-24-bold">{title}</Text>
</div>
<When condition={!!content}>
<Text variant="text-12-light" className="mt-1 mb-4">
{content}
</Text>
</When>
<FileInput
descriptionInput={descriptionInput}
descriptionList={descriptionList}
descriptionListStatus={descriptionListStatus}
variant={variantFileInput}
accept={acceptedTYpes}
onDelete={file =>
setFiles(state => {
const tmp = [...state];
remove(tmp, f => f.uuid === file.uuid);
return tmp;
})
}
onChange={files =>
setFiles(f => [
...f,
...files.map(file => ({
title: file.name,
file_name: file.name,
mime_type: file.type,
collection_name: "storybook",
size: file.size,
url: "https://google.com",
created_at: "now",
uuid: file.name,
is_public: true,
rawFile: file
}))
])
}
files={files}
/>
{children}
</div>
<div className="flex w-full justify-end gap-3 px-8 py-4">
<When condition={!!secondaryButtonProps}>
<Button {...secondaryButtonProps!} variant="white-page-admin">
<Text variant="text-14-bold" className="capitalize">
{secondaryButtonText}
</Text>
</Button>
</When>
<Button {...primaryButtonProps}>
<Text variant="text-14-bold" className="capitalize text-white">
{primaryButtonText}
</Text>
</Button>
</div>
</ModalAddBase>
);
};

export default ModalAdd;
Loading

0 comments on commit 18ec8ac

Please sign in to comment.