dev: promote stage release to production (#155)
* refractor: removed modules from user.context * refractor: removed cycles from user context * refractor: removed state from user context * feat: implement channel protocol for tracking issue-activites * refactor: remove blocking code and add todo * refactor: refactor the consumer with function modules * feat: add columns for identifiers for easier redirection * style: minor padding, coloring and consistency changes * feat: track blocker issues * feat: track issue after creation * feat: add runworker in procfile * refractor: moved all context provider to _app for more clarity * dev: added our icons * refractor: removed issues from user context * refactor: rename db names to plural and remove admin register file * refactor: integrate permission layer in endpoints * feat: create product email html templates * refractor: changed to getServerSide from getInitialProps, removed unused component imports and minor refractoring * feat: remirror added * feat: workspace member user details endpoint * fix: resolved build issue * refactor: remove www * feat: workspace details on user endpoint * feat: added authorization in project settings refractor: improved code readability * fix: removed hard-coded workspace slug value, and added workspace in user interface * refactor: invitation workflow for already existing users * feat: modified remirror, fix: issue details sidebar * fix: merge conflicts * fix: merge conflicts * fix: added missing dependencies * refactor: remove user dependency from invitations * refactor: issue description context is updated with manager * dev: redis instance rewrite for ssl settings and remove REDIS_TLS env variable * chore: upgrade python package requirements * dev: added new migrations for changes * dev: ssl config for django channels redis connection * chore: upgrade channels requirements * refactor: better function for connecting with redis ssl django channels * chore: cleanup on manifest file * revert: user endpoint changes * build: setup asgi * refactor: update invitation endpoint to do bulk operations * style: cycles page, custom listbox, issue details page * refractor: removed folder that were moved to workspaceSlug * dev: uvicorn in requirements * Update index.tsx * refactor: get workspace slug on user endpoint * fix: workspace slug redirections and slug value in user context * fix: user context bugs, drag and drop in cycles and modules * fix: merge conflicts * fix: user context and create issue modal * refactor: add extra columns for json and html description and script for back migrating old issues * refactor: move all 500 errors to 400 * refractor: removed active project, active workspace, projects, and workspaces from user context * refractor: change from /home to /, added home page redirection logic added explict GET method on fetch request, and fixed invitation page not fetching all invitations * fix: passing project id in command palette * style: home page, feat: image in remirror * fix: bugs * chore: remove test_runner workflow from github actions * dev: update Procfile worker count and python runtime upgrade * refactor: update response from 404 to 403 * feat: filtering using both name and issue identifier in command palette showing my issues instead of project issue in command palette, hiding again according to route in command palette * fix: mutation on different CRUD operations * fix: redirection in my issues pages * feat: added authorization in workspace settings, moved command palette to app-layout * feat: endpoint and column to store my issue props * style: authorization new design, fix: made whole button on authorization page clickable, lib/auth on unsuccessful api call redirecting to error page * feat: return project details on modules and cycles * fix: create cycle and state coming below issue modal, showing loader for rich text editor refractor: changed from sprint to cycle in issue type * fix: issue delete mustation and some code refractor * fix: mutation bugs, remirror bugs, style: consistent droopdowns and buttons * feat: user role in model * dev: added new migrations * fix: add url for workspace availability check * feat: onboarding screens * fix: update url for workspace name check and add authentication layer and fix invitation endpoint * refactor: bulk invitations message * refactor: response on workspace invitarions * refactor: update identifier endpoint * refactor: invitations endpoint * feat: onboarding logic and validations * fix: email striep * dev: added workspace space member unique_together * chore: back populate neccesary data for description field * feat: emoji-picker gets close on select, public will be default option in create project * fix: update error in project creation * fix: mutation error on issue count in kanban view some minor code refractoring * fix: module bugs * fix: issue activities and issue comments mutation handled at issue detail * fix: error message for creating updates without permissions * fix: showing no user left to invite in project invite fix: - mutation in project settings control, style: - showing loader in project settings controller, - showing request pending for user that hasn't accepted invitation * refactor: file asset upload directory * fix: update last workspace id on user invitation accept * style: onboarding screens * style: cycles, issue activity * feat: add json and html column in issue comments * fix: submitting create issue modal on enter click, project not getting deselected * feat: file size validator * fix: emoji picker not closing on all emoji select * feat: added validation in identifier such that it only accept uppercase text * dev: commenting is now richer * fix: shortcuts not getting opened in settings layouts * style: showing sidebar on unauthorized pages * fix: error code on exception * fix: add issue button is working on my issues pages * feat: new way of assets * fix: updated activity content for description field * fix: mutation on project settings control style: blocker and blocked changed to outline button * fix: description activity logging * refactor: check for workspace slug on workspace creation * fix: typo on workspace url check * fix: workspace name uniqueness * fix: remove workspace from read only field * fix: file upload endpoint, workspace slug check * chore: drop unique_together constraint for name and workspace * chore: settings files cleanup and use PubSub backend on django channels * chore: change in channels backend * refactor: issue activity api to combine comments * fix: instance created at key * fix: result list * style: create project, cycle modal, view dropdown * feat: merged issue activities and issue comments into a single section * fix: remirror dynamic update of issue description * fix: removed commented code * fix: issue acitivties mutation * fix: empty comments cant be submitted * fix: workspace avatar has been updated while loading * refactor: update docker-compose to run redis and database in heroku and docker environment * refactor: removesingle docker file configuration * refactor: update take off script to run in asgi * docs: added workspace, quickstart documentation * fix: reading editor values on focus out * refactor: cleanup environment variables and create .env.example * refactor: add extra variables in example env * fix: warning and erros on console lazy loading images with low priority, added validation on onboarding for user to either join or create workspace, on onboarding user can't click button while form is getting submitted, profile page going into loading state when updated, refractor: made some state local, removed unnecessary console logs and comments, changed some variable and function name to make more sence * feat: env examples * fix: workspace member does not exist * fi: remove pagination from issue list api * refactor: remove env example from root * feat: documentation for projects on plane * feat: create code of conduct and contributing guidelines * fix: update docker setup to check handle redis * revert: bring back pagination to avoid breaking * feat: made image uploader modal, used it in profile page and workspace page, delete project from project settings page, join project modal in project list page * feat: create workspace page, style: made ui consistent * style: updated onboarding and create workspace page design * style: responsive sidebar * fix: updated ui imports
This commit is contained in:
parent
a960ddedf7
commit
bef166a65f
395 changed files with 20119 additions and 18322 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import { ArrowLeftIcon, HomeIcon } from "@heroicons/react/24/outline";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import Link from "next/link";
|
||||
|
||||
// icons
|
||||
import { ArrowLeftIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
type BreadcrumbsProps = {
|
||||
children: any;
|
||||
|
|
@ -13,7 +15,7 @@ const Breadcrumbs = ({ children }: BreadcrumbsProps) => {
|
|||
<>
|
||||
<div className="flex items-center">
|
||||
<div
|
||||
className="border hover:bg-gray-100 rounded h-8 w-8 text-sm grid place-items-center text-center cursor-pointer"
|
||||
className="grid h-8 w-8 cursor-pointer place-items-center rounded border border-gray-300 text-center text-sm hover:bg-gray-100"
|
||||
onClick={() => router.back()}
|
||||
>
|
||||
<ArrowLeftIcon className="h-3 w-3" />
|
||||
|
|
@ -35,7 +37,7 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ title, link, icon }) =>
|
|||
<>
|
||||
{link ? (
|
||||
<Link href={link}>
|
||||
<a className="text-sm border-r-2 border-gray-300 px-3">
|
||||
<a className="border-r-2 border-gray-300 px-3 text-sm">
|
||||
<p className={`${icon ? "flex items-center gap-2" : ""}`}>
|
||||
{icon ?? null}
|
||||
{title}
|
||||
|
|
@ -43,7 +45,7 @@ const BreadcrumbItem: React.FC<BreadcrumbItemProps> = ({ title, link, icon }) =>
|
|||
</a>
|
||||
</Link>
|
||||
) : (
|
||||
<div className="text-sm px-3">
|
||||
<div className="px-3 text-sm">
|
||||
<p className={`${icon ? "flex items-center gap-2" : ""}`}>
|
||||
{icon}
|
||||
{title}
|
||||
71
apps/app/ui/button/index.tsx
Normal file
71
apps/app/ui/button/index.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import React from "react";
|
||||
|
||||
type Props = {
|
||||
onClick?: () => void;
|
||||
children: React.ReactNode;
|
||||
type?: "button" | "submit" | "reset";
|
||||
className?: string;
|
||||
theme?: "primary" | "secondary" | "success" | "danger";
|
||||
size?: "sm" | "rg" | "md" | "lg";
|
||||
disabled?: boolean;
|
||||
largePadding?: boolean;
|
||||
};
|
||||
|
||||
// commons
|
||||
import { classNames } from "constants/common";
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, Props>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
onClick,
|
||||
type = "button",
|
||||
size = "sm",
|
||||
className = "",
|
||||
theme = "primary",
|
||||
disabled = false,
|
||||
largePadding,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
onClick={onClick}
|
||||
type={type}
|
||||
disabled={disabled}
|
||||
className={classNames(
|
||||
className,
|
||||
"inline-flex items-center justify-center rounded font-medium duration-300",
|
||||
theme === "primary"
|
||||
? `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} border border-transparent bg-gray-200 shadow-sm hover:bg-gray-300 focus:outline-none`
|
||||
: theme === "secondary"
|
||||
? "border border-gray-300 bg-transparent hover:bg-gray-200"
|
||||
: theme === "success"
|
||||
? `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} border border-transparent bg-green-500 text-white shadow-sm hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500`
|
||||
: `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} border border-transparent bg-red-500 text-white shadow-sm hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500`,
|
||||
size === "sm"
|
||||
? "p-2 text-xs"
|
||||
: size === "md"
|
||||
? "text-md px-3 py-2"
|
||||
: size === "lg"
|
||||
? "text-md px-4 py-2"
|
||||
: "px-2.5 py-2 text-sm",
|
||||
largePadding ? "px-8" : ""
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Button.displayName = "Button";
|
||||
|
||||
export default Button;
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
import React from "react";
|
||||
// headless ui
|
||||
import { Listbox, Transition } from "@headlessui/react";
|
||||
// icons
|
||||
import { CheckIcon } from "@heroicons/react/20/solid";
|
||||
|
||||
import { Props } from "./types";
|
||||
|
||||
|
|
@ -25,25 +23,11 @@ const CustomListbox: React.FC<Props> = ({
|
|||
<>
|
||||
{label && (
|
||||
<Listbox.Label>
|
||||
<div className="text-gray-500 mb-2">{label}</div>
|
||||
<div className="mb-2 text-gray-500">{label}</div>
|
||||
</Listbox.Label>
|
||||
)}
|
||||
<Listbox.Button
|
||||
className={`flex items-center gap-1 hover:bg-gray-100 border rounded-md shadow-sm px-2 py-1 cursor-pointer focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 text-xs duration-300 ${
|
||||
width === "sm"
|
||||
? "w-32"
|
||||
: width === "md"
|
||||
? "w-48"
|
||||
: width === "lg"
|
||||
? "w-64"
|
||||
: width === "xl"
|
||||
? "w-80"
|
||||
: width === "2xl"
|
||||
? "w-96"
|
||||
: width === "w-full"
|
||||
? "w-full"
|
||||
: ""
|
||||
}
|
||||
className={`flex cursor-pointer items-center gap-1 rounded-md border px-2 py-1 text-xs shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500
|
||||
${className || "px-2 py-1"}`}
|
||||
>
|
||||
{icon ?? null}
|
||||
|
|
@ -63,21 +47,7 @@ const CustomListbox: React.FC<Props> = ({
|
|||
leaveTo="opacity-0"
|
||||
>
|
||||
<Listbox.Options
|
||||
className={`absolute mt-1 bg-white shadow-lg max-h-32 overflow-auto ${
|
||||
width === "sm"
|
||||
? "w-32"
|
||||
: width === "md"
|
||||
? "w-48"
|
||||
: width === "lg"
|
||||
? "w-64"
|
||||
: width === "xl"
|
||||
? "w-80"
|
||||
: width === "2xl"
|
||||
? "w-96"
|
||||
: width === "w-full"
|
||||
? "w-full"
|
||||
: ""
|
||||
} ${
|
||||
className={`absolute mt-1 max-h-32 min-w-[8rem] overflow-y-auto whitespace-nowrap bg-white shadow-lg ${
|
||||
optionsFontsize === "sm"
|
||||
? "text-xs"
|
||||
: optionsFontsize === "md"
|
||||
|
|
@ -89,7 +59,7 @@ const CustomListbox: React.FC<Props> = ({
|
|||
: optionsFontsize === "2xl"
|
||||
? "text-2xl"
|
||||
: ""
|
||||
} rounded-md py-1 ring-1 ring-black ring-opacity-5 focus:outline-none z-10`}
|
||||
} z-10 rounded-md py-1 ring-1 ring-black ring-opacity-5 focus:outline-none`}
|
||||
>
|
||||
<div className="py-1">
|
||||
{options ? (
|
||||
|
|
@ -97,62 +67,39 @@ const CustomListbox: React.FC<Props> = ({
|
|||
options.map((option) => (
|
||||
<Listbox.Option
|
||||
key={option.value}
|
||||
className={({ active }) =>
|
||||
className={({ selected, active }) =>
|
||||
`${
|
||||
selected ||
|
||||
(Array.isArray(value)
|
||||
? value.includes(option.value)
|
||||
: value === option.value)
|
||||
? "bg-indigo-50 font-medium"
|
||||
: ""
|
||||
} ${
|
||||
active ? "bg-indigo-50" : ""
|
||||
} text-gray-900 cursor-pointer select-none relative p-2`
|
||||
} relative cursor-pointer select-none p-2 text-gray-900`
|
||||
}
|
||||
value={option.value}
|
||||
>
|
||||
{({ selected, active }) => (
|
||||
<>
|
||||
<span className={` flex items-center gap-2 truncate`}>
|
||||
{option.icon}
|
||||
{option.color && (
|
||||
<span
|
||||
className={`${
|
||||
selected ||
|
||||
(Array.isArray(value)
|
||||
? value.includes(option.value)
|
||||
: value === option.value)
|
||||
? "font-semibold"
|
||||
: "font-normal"
|
||||
} flex items-center gap-2 truncate`}
|
||||
>
|
||||
{option.color && (
|
||||
<span
|
||||
className="flex-shrink-0 h-1.5 w-1.5 rounded-full"
|
||||
style={{
|
||||
backgroundColor: option.color,
|
||||
}}
|
||||
></span>
|
||||
)}
|
||||
{option.display}
|
||||
</span>
|
||||
|
||||
{selected ||
|
||||
(Array.isArray(value)
|
||||
? value.includes(option.value)
|
||||
: value === option.value) ? (
|
||||
<span
|
||||
className={`absolute inset-y-0 right-0 flex items-center pr-4 ${
|
||||
active ||
|
||||
(Array.isArray(value)
|
||||
? value.includes(option.value)
|
||||
: value === option.value)
|
||||
? "text-white"
|
||||
: "text-theme"
|
||||
}`}
|
||||
>
|
||||
<CheckIcon className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
|
||||
style={{
|
||||
backgroundColor: option.color,
|
||||
}}
|
||||
></span>
|
||||
)}
|
||||
{option.display}
|
||||
</span>
|
||||
</Listbox.Option>
|
||||
))
|
||||
) : (
|
||||
<p className="text-sm text-gray-500 text-center">No options</p>
|
||||
<p className="text-center text-sm text-gray-500">No options</p>
|
||||
)
|
||||
) : (
|
||||
<p className="text-sm text-gray-500 text-center">Loading...</p>
|
||||
<p className="text-center text-sm text-gray-500">Loading...</p>
|
||||
)}
|
||||
</div>
|
||||
{footerOption ?? null}
|
||||
|
|
|
|||
4
apps/app/ui/custom-listbox/types.d.ts
vendored
4
apps/app/ui/custom-listbox/types.d.ts
vendored
|
|
@ -1,12 +1,12 @@
|
|||
export type Props = {
|
||||
title?: string;
|
||||
label?: string;
|
||||
options?: Array<{ display: string; value: any; color?: string }>;
|
||||
options?: Array<{ display: string; value: any; color?: string; icon?: JSX.Element }>;
|
||||
icon?: JSX.Element;
|
||||
value: any;
|
||||
onChange: (value: any) => void;
|
||||
multiple?: boolean;
|
||||
width?: "sm" | "md" | "lg" | "xl" | "2xl" | "w-full";
|
||||
width?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "w-full";
|
||||
optionsFontsize?: "sm" | "md" | "lg" | "xl" | "2xl";
|
||||
className?: string;
|
||||
footerOption?: JSX.Element;
|
||||
|
|
|
|||
|
|
@ -17,32 +17,42 @@ const CustomMenu = ({
|
|||
ellipsis = false,
|
||||
width = "auto",
|
||||
textAlignment,
|
||||
withoutBorder = false,
|
||||
noBorder = false,
|
||||
optionsPosition = "right",
|
||||
}: Props) => {
|
||||
return (
|
||||
<Menu as="div" className={`relative w-min whitespace-nowrap text-left ${className}`}>
|
||||
<div>
|
||||
{ellipsis ? (
|
||||
<Menu.Button className="grid relative place-items-center hover:bg-gray-100 rounded p-1 focus:outline-none">
|
||||
<Menu.Button className="relative grid place-items-center rounded p-1 hover:bg-gray-100 focus:outline-none">
|
||||
<EllipsisHorizontalIcon className="h-4 w-4" />
|
||||
</Menu.Button>
|
||||
) : (
|
||||
<Menu.Button
|
||||
className={`flex justify-between items-center gap-1 hover:bg-gray-100 px-2 py-1 cursor-pointer text-xs duration-300 ${
|
||||
className={`flex cursor-pointer items-center justify-between gap-1 px-2 py-1 text-xs duration-300 hover:bg-gray-100 ${
|
||||
textAlignment === "right"
|
||||
? "text-right"
|
||||
: textAlignment === "center"
|
||||
? "text-center"
|
||||
: "text-left"
|
||||
} ${
|
||||
withoutBorder
|
||||
noBorder
|
||||
? "rounded"
|
||||
: "w-full border shadow-sm rounded-md focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500"
|
||||
: "rounded-md border shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
||||
} ${
|
||||
width === "sm"
|
||||
? "w-10"
|
||||
: width === "md"
|
||||
? "w-20"
|
||||
: width === "lg"
|
||||
? "w-32"
|
||||
: width === "xl"
|
||||
? "w-48"
|
||||
: "w-full"
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
{!withoutBorder && <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />}
|
||||
{!noBorder && <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />}
|
||||
</Menu.Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -57,9 +67,19 @@ const CustomMenu = ({
|
|||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
className={`absolute z-20 mt-1 rounded-md bg-white text-xs shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none ${
|
||||
className={`absolute z-20 mt-1 whitespace-nowrap rounded-md bg-white text-xs shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none ${
|
||||
optionsPosition === "left" ? "left-0 origin-top-left" : "right-0 origin-top-right"
|
||||
} ${width === "auto" ? "min-w-full whitespace-nowrap" : "w-56"}`}
|
||||
} ${
|
||||
width === "sm"
|
||||
? "w-10"
|
||||
: width === "md"
|
||||
? "w-20"
|
||||
: width === "lg"
|
||||
? "w-32"
|
||||
: width === "xl"
|
||||
? "w-48"
|
||||
: "min-w-full"
|
||||
}`}
|
||||
>
|
||||
<div className="py-1">{children}</div>
|
||||
</Menu.Items>
|
||||
|
|
@ -68,14 +88,20 @@ const CustomMenu = ({
|
|||
);
|
||||
};
|
||||
|
||||
const MenuItem: React.FC<MenuItemProps> = ({ children, renderAs, href, onClick }) => {
|
||||
const MenuItem: React.FC<MenuItemProps> = ({
|
||||
children,
|
||||
renderAs,
|
||||
href,
|
||||
onClick,
|
||||
className = "",
|
||||
}) => {
|
||||
return (
|
||||
<Menu.Item>
|
||||
{({ active, close }) =>
|
||||
renderAs === "a" ? (
|
||||
<Link href={href ?? ""}>
|
||||
<a
|
||||
className="block p-2 text-gray-700 hover:bg-indigo-50 hover:text-gray-900"
|
||||
className={`${className} block p-2 text-gray-700 hover:bg-indigo-50 hover:text-gray-900`}
|
||||
onClick={close}
|
||||
>
|
||||
{children}
|
||||
|
|
@ -86,6 +112,7 @@ const MenuItem: React.FC<MenuItemProps> = ({ children, renderAs, href, onClick }
|
|||
type="button"
|
||||
onClick={onClick}
|
||||
className={classNames(
|
||||
className,
|
||||
active ? "bg-indigo-50 text-gray-900" : "text-gray-700",
|
||||
"block w-full p-2 text-left"
|
||||
)}
|
||||
|
|
|
|||
7
apps/app/ui/custom-menu/types.d.ts
vendored
7
apps/app/ui/custom-menu/types.d.ts
vendored
|
|
@ -3,15 +3,16 @@ export type Props = {
|
|||
label?: string | JSX.Element;
|
||||
className?: string;
|
||||
ellipsis?: boolean;
|
||||
width?: "auto";
|
||||
width?: "sm" | "md" | "lg" | "xl" | "auto";
|
||||
textAlignment?: "left" | "center" | "right";
|
||||
withoutBorder?: boolean;
|
||||
noBorder?: boolean;
|
||||
optionsPosition?: "left" | "right";
|
||||
};
|
||||
|
||||
export type MenuItemProps = {
|
||||
children: string;
|
||||
children: JSX.Element | string;
|
||||
renderAs?: "button" | "a";
|
||||
href?: string;
|
||||
onClick?: () => void;
|
||||
className?: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ type CustomSelectProps = {
|
|||
children: React.ReactNode;
|
||||
label: string | JSX.Element;
|
||||
textAlignment?: "left" | "center" | "right";
|
||||
maxHeight?: "sm" | "rg" | "md" | "lg" | "none";
|
||||
width?: "auto" | string;
|
||||
input?: boolean;
|
||||
noChevron?: boolean;
|
||||
};
|
||||
|
||||
const CustomSelect = ({
|
||||
|
|
@ -19,18 +22,23 @@ const CustomSelect = ({
|
|||
textAlignment,
|
||||
value,
|
||||
onChange,
|
||||
maxHeight = "none",
|
||||
width = "auto",
|
||||
input = false,
|
||||
noChevron = false,
|
||||
}: CustomSelectProps) => {
|
||||
return (
|
||||
<Listbox
|
||||
as="div"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className="relative text-left flex-shrink-0"
|
||||
className="relative flex-shrink-0 text-left"
|
||||
>
|
||||
<div>
|
||||
<Listbox.Button
|
||||
className={`flex justify-between items-center gap-1 hover:bg-gray-100 border rounded-md shadow-sm px-2 w-full py-1 cursor-pointer focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 text-xs duration-300 ${
|
||||
className={`flex w-full cursor-pointer items-center justify-between gap-1 rounded-md border shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 ${
|
||||
input ? "border-gray-300 px-3 py-2 text-sm" : "px-2 py-1 text-xs"
|
||||
} ${
|
||||
textAlignment === "right"
|
||||
? "text-right"
|
||||
: textAlignment === "center"
|
||||
|
|
@ -39,7 +47,7 @@ const CustomSelect = ({
|
|||
}`}
|
||||
>
|
||||
{label}
|
||||
<ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
|
||||
{!noChevron && <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />}
|
||||
</Listbox.Button>
|
||||
</div>
|
||||
|
||||
|
|
@ -53,8 +61,18 @@ const CustomSelect = ({
|
|||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Listbox.Options
|
||||
className={`absolute right-0 z-10 mt-1 origin-top-right rounded-md bg-white text-xs shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none ${
|
||||
className={`absolute right-0 z-10 mt-1 origin-top-right overflow-y-auto rounded-md bg-white text-xs shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none ${
|
||||
width === "auto" ? "min-w-full whitespace-nowrap" : "w-56"
|
||||
} ${input ? "max-h-48" : ""} ${
|
||||
maxHeight === "lg"
|
||||
? "max-h-60"
|
||||
: maxHeight === "md"
|
||||
? "max-h-48"
|
||||
: maxHeight === "rg"
|
||||
? "max-h-36"
|
||||
: maxHeight === "sm"
|
||||
? "max-h-28"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="py-1">{children}</div>
|
||||
|
|
@ -66,7 +84,7 @@ const CustomSelect = ({
|
|||
|
||||
type OptionProps = {
|
||||
children: string | JSX.Element;
|
||||
value: string;
|
||||
value: any;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
|
|
@ -75,9 +93,9 @@ const Option: React.FC<OptionProps> = ({ children, value, className }) => {
|
|||
<Listbox.Option
|
||||
value={value}
|
||||
className={({ active, selected }) =>
|
||||
`${
|
||||
active || selected ? "bg-indigo-50" : ""
|
||||
} flex items-center gap-2 text-gray-900 cursor-pointer select-none relative p-2 truncate ${className}`
|
||||
`${selected ? "bg-indigo-50 font-medium" : ""} ${
|
||||
active ? "bg-indigo-50" : ""
|
||||
} relative flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900 ${className}`
|
||||
}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
return (
|
||||
<Popover className="relative" ref={ref}>
|
||||
<Popover.Button
|
||||
className="border border-gray-300 p-3 sm:text-sm rounded-md outline-none"
|
||||
className="rounded-md border border-gray-300 p-2 outline-none sm:text-sm"
|
||||
onClick={() => setIsOpen((prev) => !prev)}
|
||||
>
|
||||
{label}
|
||||
|
|
@ -59,15 +59,15 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Popover.Panel className="absolute z-10 w-80 bg-white rounded-md shadow-lg mt-2">
|
||||
<div className="w-80 h-80 p-2 bg-white overflow-auto rounded shadow-2xl border">
|
||||
<Tab.Group as="div" className="w-full h-full flex flex-col">
|
||||
<Tab.List className="-mx-2 flex justify-around p-1 gap-1 border-b rounded flex-0">
|
||||
<Popover.Panel className="absolute z-10 mt-2 w-80 rounded-md bg-white shadow-lg">
|
||||
<div className="h-80 w-80 overflow-auto rounded border bg-white p-2 shadow-2xl">
|
||||
<Tab.Group as="div" className="flex h-full w-full flex-col">
|
||||
<Tab.List className="flex-0 -mx-2 flex justify-around gap-1 rounded border-b p-1">
|
||||
{tabOptions.map((tab) => (
|
||||
<Tab
|
||||
key={tab.key}
|
||||
className={({ selected }) =>
|
||||
`w-1/2 py-2 transition-colors border-b text-sm font-medium text-center outline-none -my-1 ${
|
||||
`-my-1 w-1/2 border-b py-2 text-center text-sm font-medium outline-none transition-colors ${
|
||||
selected ? "border-theme" : "border-transparent"
|
||||
}`
|
||||
}
|
||||
|
|
@ -76,11 +76,11 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
<Tab.Panels className="w-full h-full flex-1 overflow-y-auto overflow-x-hidden">
|
||||
<Tab.Panel className="w-full h-full">
|
||||
<Tab.Panels className="h-full w-full flex-1 overflow-y-auto overflow-x-hidden">
|
||||
<Tab.Panel className="h-full w-full">
|
||||
{recentEmojis.length > 0 && (
|
||||
<div className="py-2 w-full">
|
||||
<h3 className="text-lg mb-2">Recent Emojis</h3>
|
||||
<div className="w-full py-2">
|
||||
<h3 className="mb-2 text-lg">Recent Emojis</h3>
|
||||
<div className="grid grid-cols-9 gap-2">
|
||||
{recentEmojis.map((emoji) => (
|
||||
<button
|
||||
|
|
@ -89,6 +89,7 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
key={emoji}
|
||||
onClick={() => {
|
||||
onChange(emoji);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
>
|
||||
{String.fromCodePoint(parseInt(emoji))}
|
||||
|
|
@ -98,7 +99,7 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
</div>
|
||||
)}
|
||||
<div className="py-3">
|
||||
<h3 className="text-lg mb-2">All Emojis</h3>
|
||||
<h3 className="mb-2 text-lg">All Emojis</h3>
|
||||
<div className="grid grid-cols-9 gap-2">
|
||||
{emojis.map((emoji) => (
|
||||
<button
|
||||
|
|
@ -108,6 +109,7 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
onClick={() => {
|
||||
onChange(emoji);
|
||||
saveRecentEmoji(emoji);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
>
|
||||
{String.fromCodePoint(parseInt(emoji))}
|
||||
|
|
@ -116,7 +118,7 @@ const EmojiIconPicker: React.FC<Props> = ({ label, value, onChange }) => {
|
|||
</div>
|
||||
</div>
|
||||
</Tab.Panel>
|
||||
<Tab.Panel className="w-full h-full flex flex-col justify-center items-center">
|
||||
<Tab.Panel className="flex h-full w-full flex-col items-center justify-center">
|
||||
<p>Coming Soon...</p>
|
||||
</Tab.Panel>
|
||||
</Tab.Panels>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ type EmptySpaceProps = {
|
|||
title: string;
|
||||
description: string;
|
||||
children: any;
|
||||
Icon?: (props: any) => JSX.Element;
|
||||
Icon?: (props: any) => any;
|
||||
link?: { text: string; href: string };
|
||||
};
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ const EmptySpaceItem: React.FC<EmptySpaceItemProps> = ({
|
|||
>
|
||||
<div className="flex-shrink-0">
|
||||
<span
|
||||
className={`inline-flex items-center justify-center h-10 w-10 rounded-lg bg-theme`}
|
||||
className={`inline-flex h-10 w-10 items-center justify-center rounded-lg bg-theme`}
|
||||
>
|
||||
<Icon className="h-6 w-6 text-white" aria-hidden="true" />
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const HeaderButton = ({
|
|||
<>
|
||||
<button
|
||||
type="button"
|
||||
className={`border hover:bg-gray-100 text-gray-600 hover:text-gray-900 text-xs flex items-center gap-x-1 p-2 rounded-md font-medium whitespace-nowrap outline-none ${
|
||||
className={`whitespace-nowraps flex w-min items-center gap-x-1 whitespace-nowrap rounded-md border p-2 text-xs font-medium text-gray-600 outline-none hover:bg-gray-100 hover:text-gray-900 ${
|
||||
position === "reverse" && "flex-row-reverse"
|
||||
} ${className}`}
|
||||
disabled={disabled}
|
||||
21
apps/app/ui/icons/attachment-icon.tsx
Normal file
21
apps/app/ui/icons/attachment-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const AttachmentIcon: React.FC<Props> = ({ width, height, className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M18.75 20C18.4 20 18.1042 19.8792 17.8625 19.6375C17.6208 19.3958 17.5 19.1 17.5 18.75V5.25C17.5 4.9 17.6208 4.60417 17.8625 4.3625C18.1042 4.12083 18.4 4 18.75 4C19.1 4 19.3958 4.12083 19.6375 4.3625C19.8792 4.60417 20 4.9 20 5.25V18.75C20 19.1 19.8792 19.3958 19.6375 19.6375C19.3958 19.8792 19.1 20 18.75 20ZM6.275 20C6.09167 20 5.92083 19.9667 5.7625 19.9C5.60417 19.8333 5.47083 19.7458 5.3625 19.6375C5.25417 19.5292 5.16667 19.3958 5.1 19.2375C5.03333 19.0792 5 18.9167 5 18.75V15.25C5 14.9 5.12083 14.6042 5.3625 14.3625C5.60417 14.1208 5.9 14 6.25 14C6.6 14 6.89583 14.1208 7.1375 14.3625C7.37917 14.6042 7.5 14.9 7.5 15.25V18.75C7.5 18.9167 7.46667 19.0792 7.4 19.2375C7.33333 19.3958 7.24583 19.5292 7.1375 19.6375C7.02917 19.7458 6.9 19.8333 6.75 19.9C6.6 19.9667 6.44167 20 6.275 20ZM12.5 20C12.15 20 11.8542 19.8792 11.6125 19.6375C11.3708 19.3958 11.25 19.1 11.25 18.75V10.25C11.25 9.9 11.3708 9.60417 11.6125 9.3625C11.8542 9.12083 12.15 9 12.5 9C12.85 9 13.1458 9.12083 13.3875 9.3625C13.6292 9.60417 13.75 9.9 13.75 10.25V18.75C13.75 19.1 13.6292 19.3958 13.3875 19.6375C13.1458 19.8792 12.85 20 12.5 20Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
27
apps/app/ui/icons/blocked-icon.tsx
Normal file
27
apps/app/ui/icons/blocked-icon.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const BlockedIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 23 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0.5 4.8C0.5 3.52696 1.00797 2.30606 1.91216 1.40589C2.81636 0.505713 4.04271 0 5.32143 0H21.3929C21.6913 0 21.9839 0.0827435 22.2378 0.238959C22.4917 0.395174 22.6968 0.618689 22.8303 0.884458C22.9638 1.15023 23.0203 1.44775 22.9935 1.74369C22.9667 2.03963 22.8576 2.32229 22.6786 2.56L18.5804 8L22.6786 13.44C22.8576 13.6777 22.9667 13.9604 22.9935 14.2563C23.0203 14.5522 22.9638 14.8498 22.8303 15.1155C22.6968 15.3813 22.4917 15.6048 22.2378 15.761C21.9839 15.9173 21.6913 16 21.3929 16H5.32143C4.89519 16 4.4864 16.1686 4.18501 16.4686C3.88361 16.7687 3.71429 17.1757 3.71429 17.6V22.4C3.71429 22.8243 3.54496 23.2313 3.24356 23.5314C2.94217 23.8314 2.53338 24 2.10714 24C1.6809 24 1.27212 23.8314 0.970721 23.5314C0.669323 23.2313 0.5 22.8243 0.5 22.4V4.8Z"
|
||||
fill="#F76659"
|
||||
/>
|
||||
<path
|
||||
d="M8.5918 20.4812H21.084C21.26 20.4812 21.4056 20.4237 21.5207 20.3086C21.6358 20.1935 21.6934 20.0479 21.6934 19.8719C21.6934 19.6958 21.6358 19.5503 21.5207 19.4352C21.4056 19.3201 21.26 19.2625 21.084 19.2625H8.57148L10.3184 17.5156C10.4267 17.4073 10.4809 17.2719 10.4809 17.1094C10.4809 16.9469 10.4199 16.8047 10.298 16.6828C10.1762 16.5609 10.034 16.5 9.87148 16.5C9.70899 16.5 9.5668 16.5609 9.44492 16.6828L6.68242 19.4453C6.61471 19.513 6.56732 19.5807 6.54023 19.6484C6.51315 19.7161 6.49961 19.7906 6.49961 19.8719C6.49961 19.9531 6.51315 20.0276 6.54023 20.0953C6.56732 20.163 6.61471 20.2307 6.68242 20.2984L9.44492 23.0609C9.58034 23.1964 9.72591 23.2607 9.88164 23.2539C10.0374 23.2471 10.1762 23.1828 10.298 23.0609C10.4199 22.9391 10.4809 22.7935 10.4809 22.6242C10.4809 22.4549 10.4267 22.3161 10.3184 22.2078L8.5918 20.4812Z"
|
||||
fill="#F76659"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
27
apps/app/ui/icons/blocker-icon.tsx
Normal file
27
apps/app/ui/icons/blocker-icon.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const BlockerIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 23 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0 4.8C0 3.52696 0.507971 2.30606 1.41216 1.40589C2.31636 0.505713 3.54271 0 4.82143 0H20.8929C21.1913 0 21.4839 0.0827435 21.7378 0.238959C21.9917 0.395174 22.1968 0.618689 22.3303 0.884458C22.4638 1.15023 22.5203 1.44775 22.4935 1.74369C22.4667 2.03963 22.3576 2.32229 22.1786 2.56L18.0804 8L22.1786 13.44C22.3576 13.6777 22.4667 13.9604 22.4935 14.2563C22.5203 14.5522 22.4638 14.8498 22.3303 15.1155C22.1968 15.3813 21.9917 15.6048 21.7378 15.761C21.4839 15.9173 21.1913 16 20.8929 16H4.82143C4.39519 16 3.9864 16.1686 3.68501 16.4686C3.38361 16.7687 3.21429 17.1757 3.21429 17.6V22.4C3.21429 22.8243 3.04496 23.2313 2.74356 23.5314C2.44217 23.8314 2.03338 24 1.60714 24C1.1809 24 0.772119 23.8314 0.470721 23.5314C0.169323 23.2313 0 22.8243 0 22.4V4.8Z"
|
||||
fill="#F7AE59"
|
||||
/>
|
||||
<path
|
||||
d="M18.5391 20.8797H6.04688C5.87083 20.8797 5.72526 20.8221 5.61016 20.707C5.49505 20.5919 5.4375 20.4464 5.4375 20.2703C5.4375 20.0943 5.49505 19.9487 5.61016 19.8336C5.72526 19.7185 5.87083 19.6609 6.04688 19.6609H18.5594L16.8125 17.9141C16.7042 17.8057 16.65 17.6703 16.65 17.5078C16.65 17.3453 16.7109 17.2031 16.8328 17.0813C16.9547 16.9594 17.0969 16.8984 17.2594 16.8984C17.4219 16.8984 17.5641 16.9594 17.6859 17.0813L20.4484 19.8438C20.5161 19.9115 20.5635 19.9792 20.5906 20.0469C20.6177 20.1146 20.6313 20.1891 20.6313 20.2703C20.6313 20.3516 20.6177 20.426 20.5906 20.4938C20.5635 20.5615 20.5161 20.6292 20.4484 20.6969L17.6859 23.4594C17.5505 23.5948 17.4049 23.6591 17.2492 23.6523C17.0935 23.6456 16.9547 23.5812 16.8328 23.4594C16.7109 23.3375 16.65 23.1919 16.65 23.0227C16.65 22.8534 16.7042 22.7146 16.8125 22.6062L18.5391 20.8797Z"
|
||||
fill="#F7AE59"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/calendar-month-icon.tsx
Normal file
21
apps/app/ui/icons/calendar-month-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const CalendarMonthIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 14C11.7167 14 11.4792 13.9042 11.2875 13.7125C11.0958 13.5208 11 13.2833 11 13C11 12.7167 11.0958 12.4792 11.2875 12.2875C11.4792 12.0958 11.7167 12 12 12C12.2833 12 12.5208 12.0958 12.7125 12.2875C12.9042 12.4792 13 12.7167 13 13C13 13.2833 12.9042 13.5208 12.7125 13.7125C12.5208 13.9042 12.2833 14 12 14ZM8 14C7.71667 14 7.47917 13.9042 7.2875 13.7125C7.09583 13.5208 7 13.2833 7 13C7 12.7167 7.09583 12.4792 7.2875 12.2875C7.47917 12.0958 7.71667 12 8 12C8.28333 12 8.52083 12.0958 8.7125 12.2875C8.90417 12.4792 9 12.7167 9 13C9 13.2833 8.90417 13.5208 8.7125 13.7125C8.52083 13.9042 8.28333 14 8 14ZM16 14C15.7167 14 15.4792 13.9042 15.2875 13.7125C15.0958 13.5208 15 13.2833 15 13C15 12.7167 15.0958 12.4792 15.2875 12.2875C15.4792 12.0958 15.7167 12 16 12C16.2833 12 16.5208 12.0958 16.7125 12.2875C16.9042 12.4792 17 12.7167 17 13C17 13.2833 16.9042 13.5208 16.7125 13.7125C16.5208 13.9042 16.2833 14 16 14ZM12 18C11.7167 18 11.4792 17.9042 11.2875 17.7125C11.0958 17.5208 11 17.2833 11 17C11 16.7167 11.0958 16.4792 11.2875 16.2875C11.4792 16.0958 11.7167 16 12 16C12.2833 16 12.5208 16.0958 12.7125 16.2875C12.9042 16.4792 13 16.7167 13 17C13 17.2833 12.9042 17.5208 12.7125 17.7125C12.5208 17.9042 12.2833 18 12 18ZM8 18C7.71667 18 7.47917 17.9042 7.2875 17.7125C7.09583 17.5208 7 17.2833 7 17C7 16.7167 7.09583 16.4792 7.2875 16.2875C7.47917 16.0958 7.71667 16 8 16C8.28333 16 8.52083 16.0958 8.7125 16.2875C8.90417 16.4792 9 16.7167 9 17C9 17.2833 8.90417 17.5208 8.7125 17.7125C8.52083 17.9042 8.28333 18 8 18ZM16 18C15.7167 18 15.4792 17.9042 15.2875 17.7125C15.0958 17.5208 15 17.2833 15 17C15 16.7167 15.0958 16.4792 15.2875 16.2875C15.4792 16.0958 15.7167 16 16 16C16.2833 16 16.5208 16.0958 16.7125 16.2875C16.9042 16.4792 17 16.7167 17 17C17 17.2833 16.9042 17.5208 16.7125 17.7125C16.5208 17.9042 16.2833 18 16 18ZM4.5 22C4.1 22 3.75 21.85 3.45 21.55C3.15 21.25 3 20.9 3 20.5V5C3 4.6 3.15 4.25 3.45 3.95C3.75 3.65 4.1 3.5 4.5 3.5H6.125V2.8C6.125 2.56667 6.2 2.375 6.35 2.225C6.5 2.075 6.69167 2 6.925 2C7.15833 2 7.35417 2.075 7.5125 2.225C7.67083 2.375 7.75 2.56667 7.75 2.8V3.5H16.25V2.8C16.25 2.56667 16.325 2.375 16.475 2.225C16.625 2.075 16.8167 2 17.05 2C17.2833 2 17.4792 2.075 17.6375 2.225C17.7958 2.375 17.875 2.56667 17.875 2.8V3.5H19.5C19.9 3.5 20.25 3.65 20.55 3.95C20.85 4.25 21 4.6 21 5V20.5C21 20.9 20.85 21.25 20.55 21.55C20.25 21.85 19.9 22 19.5 22H4.5ZM4.5 20.5H19.5V9.75H4.5V20.5ZM4.5 8.25H19.5V5H4.5V8.25ZM4.5 8.25V5V8.25Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
18
apps/app/ui/icons/cancel-icon.tsx
Normal file
18
apps/app/ui/icons/cancel-icon.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const CancelIcon: React.FC<Props> = ({ width, height, className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M7.725 16.275C7.875 16.425 8.05 16.5 8.25 16.5C8.45 16.5 8.625 16.425 8.775 16.275L12 13.05L15.25 16.3C15.3833 16.4333 15.5542 16.4958 15.7625 16.4875C15.9708 16.4792 16.1417 16.4083 16.275 16.275C16.425 16.125 16.5 15.95 16.5 15.75C16.5 15.55 16.425 15.375 16.275 15.225L13.05 12L16.3 8.75C16.4333 8.61667 16.4958 8.44583 16.4875 8.2375C16.4792 8.02917 16.4083 7.85833 16.275 7.725C16.125 7.575 15.95 7.5 15.75 7.5C15.55 7.5 15.375 7.575 15.225 7.725L12 10.95L8.75 7.7C8.61667 7.56667 8.44583 7.50417 8.2375 7.5125C8.02917 7.52083 7.85833 7.59167 7.725 7.725C7.575 7.875 7.5 8.05 7.5 8.25C7.5 8.45 7.575 8.625 7.725 8.775L10.95 12L7.7 15.25C7.56667 15.3833 7.50417 15.5542 7.5125 15.7625C7.52083 15.9708 7.59167 16.1417 7.725 16.275ZM12 22C10.5833 22 9.26667 21.7458 8.05 21.2375C6.83333 20.7292 5.775 20.025 4.875 19.125C3.975 18.225 3.27083 17.1667 2.7625 15.95C2.25417 14.7333 2 13.4167 2 12C2 10.6 2.25417 9.29167 2.7625 8.075C3.27083 6.85833 3.975 5.8 4.875 4.9C5.775 4 6.83333 3.29167 8.05 2.775C9.26667 2.25833 10.5833 2 12 2C13.4 2 14.7083 2.25833 15.925 2.775C17.1417 3.29167 18.2 4 19.1 4.9C20 5.8 20.7083 6.85833 21.225 8.075C21.7417 9.29167 22 10.6 22 12C22 13.4167 21.7417 14.7333 21.225 15.95C20.7083 17.1667 20 18.225 19.1 19.125C18.2 20.025 17.1417 20.7292 15.925 21.2375C14.7083 21.7458 13.4 22 12 22ZM12 20.5C14.3333 20.5 16.3333 19.6667 18 18C19.6667 16.3333 20.5 14.3333 20.5 12C20.5 9.66667 19.6667 7.66667 18 6C16.3333 4.33333 14.3333 3.5 12 3.5C9.66667 3.5 7.66667 4.33333 6 6C4.33333 7.66667 3.5 9.66667 3.5 12C3.5 14.3333 4.33333 16.3333 6 18C7.66667 19.6667 9.66667 20.5 12 20.5Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/clipboard-icon.tsx
Normal file
21
apps/app/ui/icons/clipboard-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const ClipboardIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M4.5 21C4.08333 21 3.72917 20.8542 3.4375 20.5625C3.14583 20.2708 3 19.9167 3 19.5V4.5C3 4.08333 3.14583 3.72917 3.4375 3.4375C3.72917 3.14583 4.08333 3 4.5 3H9.625C9.70833 2.41667 9.975 1.9375 10.425 1.5625C10.875 1.1875 11.4 1 12 1C12.6 1 13.125 1.1875 13.575 1.5625C14.025 1.9375 14.2917 2.41667 14.375 3H19.5C19.9167 3 20.2708 3.14583 20.5625 3.4375C20.8542 3.72917 21 4.08333 21 4.5V19.5C21 19.9167 20.8542 20.2708 20.5625 20.5625C20.2708 20.8542 19.9167 21 19.5 21H4.5ZM4.5 19.5H19.5V4.5H4.5V19.5ZM7 17H13.825V15.5H7V17ZM7 12.75H17V11.25H7V12.75ZM7 8.5H17V7H7V8.5ZM12 4.075C12.2333 4.075 12.4375 3.9875 12.6125 3.8125C12.7875 3.6375 12.875 3.43333 12.875 3.2C12.875 2.96667 12.7875 2.7625 12.6125 2.5875C12.4375 2.4125 12.2333 2.325 12 2.325C11.7667 2.325 11.5625 2.4125 11.3875 2.5875C11.2125 2.7625 11.125 2.96667 11.125 3.2C11.125 3.43333 11.2125 3.6375 11.3875 3.8125C11.5625 3.9875 11.7667 4.075 12 4.075ZM4.5 19.5V4.5V19.5Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
19
apps/app/ui/icons/completed-cycle-icon.tsx
Normal file
19
apps/app/ui/icons/completed-cycle-icon.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const CompletedCycleIcon: React.FC<Props> = ({
|
||||
width = "24",
|
||||
height = "24",
|
||||
className,
|
||||
color = "black",
|
||||
}) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height={height} width={width} className={className}>
|
||||
<path
|
||||
d="m21.65 36.6-6.9-6.85 2.1-2.1 4.8 4.7 9.2-9.2 2.1 2.15ZM6 44V7h6.25V4h3.25v3h17V4h3.25v3H42v37Zm3-3h30V19.5H9Zm0-24.5h30V10H9Zm0 0V10v6.5Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
19
apps/app/ui/icons/current-cycle-icon.tsx
Normal file
19
apps/app/ui/icons/current-cycle-icon.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const CurrentCycleIcon: React.FC<Props> = ({
|
||||
width = "24",
|
||||
height = "24",
|
||||
className,
|
||||
color = "black",
|
||||
}) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height={height} width={width} className={className}>
|
||||
<path
|
||||
d="M15.3 28.3q-.85 0-1.425-.575-.575-.575-.575-1.425 0-.85.575-1.425.575-.575 1.425-.575.85 0 1.425.575.575.575.575 1.425 0 .85-.575 1.425-.575.575-1.425.575Zm8.85 0q-.85 0-1.425-.575-.575-.575-.575-1.425 0-.85.575-1.425.575-.575 1.425-.575.85 0 1.425.575.575.575.575 1.425 0 .85-.575 1.425-.575.575-1.425.575Zm8.5 0q-.85 0-1.425-.575-.575-.575-.575-1.425 0-.85.575-1.425.575-.575 1.425-.575.85 0 1.425.575.575.575.575 1.425 0 .85-.575 1.425-.575.575-1.425.575ZM6 44V7h6.25V4h3.25v3h17V4h3.25v3H42v37Zm3-3h30V19.5H9Zm0-24.5h30V10H9Zm0 0V10v6.5Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
36
apps/app/ui/icons/cycle-icon.tsx
Normal file
36
apps/app/ui/icons/cycle-icon.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const CyclesIcon: React.FC<Props> = ({
|
||||
width = "24",
|
||||
height = "24",
|
||||
className,
|
||||
color = "black",
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.5 17.5H3.5V20.5M20.5 20.5H17.5V17.5M17.5 6.5H20.5V3.5M3.5 3.5H6.5V6.5"
|
||||
stroke={color}
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M6.5 3.647C3.789 5.4355 2 8.509 2 12C2 12.51 2.038 13.0105 2.1115 13.5M13.5 21.888C13.0035 21.9626 12.5021 22.0001 12 22C8.509 22 5.4355 20.211 3.647 17.5M21.888 10.5C21.962 10.9895 22 11.49 22 12C22 15.491 20.211 18.5645 17.5 20.353M10.5 2.1115C10.9965 2.03703 11.4979 1.99976 12 2C15.491 2 18.5645 3.789 20.353 6.5"
|
||||
stroke={color}
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/edit-icon.tsx
Normal file
21
apps/app/ui/icons/edit-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const EditIcon: React.FC<Props> = ({ width, height, className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 11.9751C10.9 11.9751 10 11.6251 9.3 10.9251C8.6 10.2251 8.25 9.3251 8.25 8.2251C8.25 7.1251 8.6 6.2251 9.3 5.5251C10 4.8251 10.9 4.4751 12 4.4751C13.1 4.4751 14 4.8251 14.7 5.5251C15.4 6.2251 15.75 7.1251 15.75 8.2251C15.75 9.3251 15.4 10.2251 14.7 10.9251C14 11.6251 13.1 11.9751 12 11.9751ZM18.5 20.0001H5.5C5.08333 20.0001 4.72917 19.8543 4.4375 19.5626C4.14583 19.2709 4 18.9168 4 18.5001V17.6501C4 17.0168 4.15833 16.4751 4.475 16.0251C4.79167 15.5751 5.2 15.2334 5.7 15.0001C6.81667 14.5001 7.8875 14.1251 8.9125 13.8751C9.9375 13.6251 10.9667 13.5001 12 13.5001C13.0333 13.5001 14.0583 13.6293 15.075 13.8876C16.0917 14.1459 17.1583 14.5168 18.275 15.0001C18.7917 15.2334 19.2083 15.5751 19.525 16.0251C19.8417 16.4751 20 17.0168 20 17.6501V18.5001C20 18.9168 19.8542 19.2709 19.5625 19.5626C19.2708 19.8543 18.9167 20.0001 18.5 20.0001ZM5.5 18.5001H18.5V17.6501C18.5 17.3834 18.4208 17.1293 18.2625 16.8876C18.1042 16.6459 17.9083 16.4668 17.675 16.3501C16.6083 15.8334 15.6333 15.4793 14.75 15.2876C13.8667 15.0959 12.95 15.0001 12 15.0001C11.05 15.0001 10.125 15.0959 9.225 15.2876C8.325 15.4793 7.35 15.8334 6.3 16.3501C6.06667 16.4668 5.875 16.6459 5.725 16.8876C5.575 17.1293 5.5 17.3834 5.5 17.6501V18.5001ZM12 10.4751C12.65 10.4751 13.1875 10.2626 13.6125 9.8376C14.0375 9.4126 14.25 8.8751 14.25 8.2251C14.25 7.5751 14.0375 7.0376 13.6125 6.6126C13.1875 6.1876 12.65 5.9751 12 5.9751C11.35 5.9751 10.8125 6.1876 10.3875 6.6126C9.9625 7.0376 9.75 7.5751 9.75 8.2251C9.75 8.8751 9.9625 9.4126 10.3875 9.8376C10.8125 10.2626 11.35 10.4751 12 10.4751Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/ellipsis-horizontal-icon.tsx
Normal file
21
apps/app/ui/icons/ellipsis-horizontal-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const EllipsisHorizontalIcon: React.FC<Props> = ({ width, height, className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M5.2 13.1998C4.86667 13.1998 4.58333 13.0831 4.35 12.8498C4.11667 12.6165 4 12.3331 4 11.9998C4 11.6665 4.11667 11.3831 4.35 11.1498C4.58333 10.9165 4.86667 10.7998 5.2 10.7998C5.53333 10.7998 5.81667 10.9165 6.05 11.1498C6.28333 11.3831 6.4 11.6665 6.4 11.9998C6.4 12.3331 6.28333 12.6165 6.05 12.8498C5.81667 13.0831 5.53333 13.1998 5.2 13.1998ZM12 13.1998C11.6667 13.1998 11.3833 13.0831 11.15 12.8498C10.9167 12.6165 10.8 12.3331 10.8 11.9998C10.8 11.6665 10.9167 11.3831 11.15 11.1498C11.3833 10.9165 11.6667 10.7998 12 10.7998C12.3333 10.7998 12.6167 10.9165 12.85 11.1498C13.0833 11.3831 13.2 11.6665 13.2 11.9998C13.2 12.3331 13.0833 12.6165 12.85 12.8498C12.6167 13.0831 12.3333 13.1998 12 13.1998ZM18.8 13.1998C18.4667 13.1998 18.1833 13.0831 17.95 12.8498C17.7167 12.6165 17.6 12.3331 17.6 11.9998C17.6 11.6665 17.7167 11.3831 17.95 11.1498C18.1833 10.9165 18.4667 10.7998 18.8 10.7998C19.1333 10.7998 19.4167 10.9165 19.65 11.1498C19.8833 11.3831 20 11.6665 20 11.9998C20 12.3331 19.8833 12.6165 19.65 12.8498C19.4167 13.0831 19.1333 13.1998 18.8 13.1998Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
24
apps/app/ui/icons/heartbeat-icon.tsx
Normal file
24
apps/app/ui/icons/heartbeat-icon.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const HeartbeatIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 12H7.5L9 6L13 18L15 9L16.5 12H21"
|
||||
stroke="black"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
24
apps/app/ui/icons/index.ts
Normal file
24
apps/app/ui/icons/index.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
export * from "./attachment-icon";
|
||||
export * from "./blocked-icon";
|
||||
export * from "./blocker-icon";
|
||||
export * from "./calendar-month-icon";
|
||||
export * from "./cancel-icon";
|
||||
export * from "./clipboard-icon";
|
||||
export * from "./completed-cycle-icon";
|
||||
export * from "./current-cycle-icon";
|
||||
export * from "./cycle-icon";
|
||||
export * from "./edit-icon";
|
||||
export * from "./ellipsis-horizontal-icon";
|
||||
export * from "./heartbeat-icon";
|
||||
export * from "./layer-diagonal-icon";
|
||||
export * from "./lock-icon";
|
||||
export * from "./menu-icon";
|
||||
export * from "./plus-icon";
|
||||
export * from "./setting-icon";
|
||||
export * from "./signal-cellular-icon";
|
||||
export * from "./tag-icon";
|
||||
export * from "./tune-icon";
|
||||
export * from "./upcoming-cycle-icon";
|
||||
export * from "./user-group-icon";
|
||||
export * from "./user-icon-circle";
|
||||
export * from "./user-icon";
|
||||
26
apps/app/ui/icons/layer-diagonal-icon.tsx
Normal file
26
apps/app/ui/icons/layer-diagonal-icon.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const LayerDiagonalIcon: React.FC<Props> = ({
|
||||
width = "24",
|
||||
height = "24",
|
||||
className,
|
||||
color = "black",
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12.6004 4.20111C12.6005 4.10308 12.5766 4.00653 12.5307 3.91989C12.4849 3.83325 12.4185 3.75916 12.3374 3.7041C12.2563 3.64905 12.1629 3.6147 12.0655 3.60407C11.968 3.59343 11.8695 3.60684 11.7784 3.64311L4.73799 6.43191C4.4024 6.56473 4.11449 6.79536 3.91163 7.09387C3.70877 7.39239 3.60033 7.74499 3.60039 8.10591V14.9963C3.60037 15.0942 3.6243 15.1906 3.67009 15.2771C3.71587 15.3636 3.78212 15.4376 3.86306 15.4926C3.94401 15.5476 4.03718 15.582 4.13446 15.5928C4.23175 15.6035 4.33018 15.5903 4.42119 15.5543L4.80039 15.4043V16.6943C4.52882 16.7903 4.23817 16.8198 3.95286 16.7802C3.66755 16.7405 3.39592 16.633 3.16077 16.4667C2.92563 16.3003 2.73385 16.0799 2.60153 15.8241C2.46922 15.5682 2.40024 15.2844 2.40039 14.9963V8.10591C2.40029 7.50438 2.58101 6.91671 2.91912 6.41919C3.25722 5.92166 3.73707 5.53727 4.29639 5.31591L11.3368 2.52711C11.6011 2.42232 11.8864 2.38163 12.1695 2.40837C12.4526 2.43511 12.7252 2.52852 12.9652 2.68095C13.2052 2.83337 13.4057 3.04049 13.5503 3.28532C13.6948 3.53015 13.7793 3.80574 13.7968 4.08951L12.5992 4.56231V4.20111H12.6004ZM16.2004 6.60111C16.2003 6.50318 16.1762 6.40677 16.1303 6.32029C16.0844 6.23381 16.018 6.15988 15.9369 6.10496C15.8558 6.05005 15.7625 6.01581 15.6652 6.00523C15.5678 5.99466 15.4694 6.00808 15.3784 6.04431L7.95879 8.98311C7.73506 9.07165 7.54312 9.22541 7.40788 9.42442C7.27264 9.62343 7.20035 9.8585 7.20039 10.0991V17.3975C7.20037 17.4954 7.2243 17.5918 7.27009 17.6783C7.31587 17.7648 7.38212 17.8388 7.46306 17.8938C7.54401 17.9488 7.63718 17.9832 7.73446 17.994C7.83175 18.0047 7.93018 17.9915 8.02119 17.9555L9.60039 17.3279V18.6191L8.46399 19.0691C8.1911 19.1773 7.89587 19.2172 7.60405 19.1852C7.31223 19.1531 7.03267 19.0502 6.78974 18.8854C6.54681 18.7206 6.34788 18.4988 6.2103 18.2395C6.07272 17.9801 6.00065 17.6911 6.00039 17.3975V10.0979C6.00031 9.61668 6.14489 9.14655 6.41537 8.74853C6.68585 8.35051 7.06974 8.043 7.51719 7.86591L14.9368 4.92831C15.2096 4.82033 15.5047 4.78068 15.7964 4.81283C16.088 4.84497 16.3674 4.94793 16.6102 5.11273C16.8529 5.27753 17.0517 5.49919 17.1893 5.75839C17.3268 6.01759 17.3989 6.30648 17.3992 6.59991V6.72351L16.2004 7.19991V6.59991V6.60111ZM19.5796 8.44311C19.6705 8.40713 19.7688 8.39391 19.866 8.4046C19.9632 8.4153 20.0563 8.44958 20.1372 8.50447C20.2181 8.55936 20.2844 8.63319 20.3303 8.71954C20.3761 8.80589 20.4002 8.90213 20.4004 8.99991V16.9487C20.4002 17.0688 20.3639 17.1861 20.2963 17.2853C20.2287 17.3846 20.1329 17.4613 20.0212 17.5055L12.8212 20.3579C12.7302 20.3939 12.6317 20.4071 12.5345 20.3964C12.4372 20.3856 12.344 20.3512 12.2631 20.2962C12.1821 20.2412 12.1159 20.1672 12.0701 20.0807C12.0243 19.9942 12.0004 19.8978 12.0004 19.7999V11.8523C12.0004 11.732 12.0365 11.6145 12.1041 11.515C12.1718 11.4155 12.2677 11.3386 12.3796 11.2943L19.5796 8.44311ZM21.6004 8.99991C21.6002 8.70638 21.5283 8.41735 21.3909 8.15799C21.2535 7.89863 21.0547 7.67681 20.8119 7.51187C20.5691 7.34693 20.2896 7.24386 19.9979 7.21166C19.7061 7.17946 19.4109 7.21909 19.138 7.32711L11.938 10.1783C11.6024 10.3111 11.3145 10.5418 11.1116 10.8403C10.9088 11.1388 10.8003 11.4914 10.8004 11.8523V19.7999C10.8003 20.0935 10.8721 20.3827 11.0095 20.6422C11.1468 20.9018 11.3456 21.1237 11.5884 21.2888C11.8312 21.4539 12.1108 21.5571 12.4026 21.5893C12.6945 21.6216 12.9898 21.582 13.2628 21.4739L20.4628 18.6215C20.7982 18.4888 21.086 18.2583 21.2888 17.96C21.4917 17.6618 21.6002 17.3094 21.6004 16.9487V8.99991Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
18
apps/app/ui/icons/lock-icon.tsx
Normal file
18
apps/app/ui/icons/lock-icon.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const LockIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 25 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M6 22C5.58333 22 5.22917 21.8542 4.9375 21.5625C4.64583 21.2708 4.5 20.9167 4.5 20.5V9.65C4.5 9.23333 4.64583 8.87917 4.9375 8.5875C5.22917 8.29583 5.58333 8.15 6 8.15H7.75V5.75C7.75 4.43333 8.2125 3.3125 9.1375 2.3875C10.0625 1.4625 11.1833 1 12.5 1C13.8167 1 14.9375 1.4625 15.8625 2.3875C16.7875 3.3125 17.25 4.43333 17.25 5.75V8.15H19C19.4167 8.15 19.7708 8.29583 20.0625 8.5875C20.3542 8.87917 20.5 9.23333 20.5 9.65V20.5C20.5 20.9167 20.3542 21.2708 20.0625 21.5625C19.7708 21.8542 19.4167 22 19 22H6ZM6 20.5H19V9.65H6V20.5ZM12.5 17C13.0333 17 13.4875 16.8167 13.8625 16.45C14.2375 16.0833 14.425 15.6417 14.425 15.125C14.425 14.625 14.2375 14.1708 13.8625 13.7625C13.4875 13.3542 13.0333 13.15 12.5 13.15C11.9667 13.15 11.5125 13.3542 11.1375 13.7625C10.7625 14.1708 10.575 14.625 10.575 15.125C10.575 15.6417 10.7625 16.0833 11.1375 16.45C11.5125 16.8167 11.9667 17 12.5 17ZM9.25 8.15H15.75V5.75C15.75 4.85 15.4333 4.08333 14.8 3.45C14.1667 2.81667 13.4 2.5 12.5 2.5C11.6 2.5 10.8333 2.81667 10.2 3.45C9.56667 4.08333 9.25 4.85 9.25 5.75V8.15ZM6 20.5V9.65V20.5Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/menu-icon.tsx
Normal file
21
apps/app/ui/icons/menu-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const MenuIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3.75 18C3.53333 18 3.35417 17.9292 3.2125 17.7875C3.07083 17.6458 3 17.4667 3 17.25C3 17.0333 3.07083 16.8542 3.2125 16.7125C3.35417 16.5708 3.53333 16.5 3.75 16.5H20.25C20.4667 16.5 20.6458 16.5708 20.7875 16.7125C20.9292 16.8542 21 17.0333 21 17.25C21 17.4667 20.9292 17.6458 20.7875 17.7875C20.6458 17.9292 20.4667 18 20.25 18H3.75ZM3.75 12.75C3.53333 12.75 3.35417 12.6792 3.2125 12.5375C3.07083 12.3958 3 12.2167 3 12C3 11.7833 3.07083 11.6042 3.2125 11.4625C3.35417 11.3208 3.53333 11.25 3.75 11.25H20.25C20.4667 11.25 20.6458 11.3208 20.7875 11.4625C20.9292 11.6042 21 11.7833 21 12C21 12.2167 20.9292 12.3958 20.7875 12.5375C20.6458 12.6792 20.4667 12.75 20.25 12.75H3.75ZM3.75 7.5C3.53333 7.5 3.35417 7.42917 3.2125 7.2875C3.07083 7.14583 3 6.96667 3 6.75C3 6.53333 3.07083 6.35417 3.2125 6.2125C3.35417 6.07083 3.53333 6 3.75 6H20.25C20.4667 6 20.6458 6.07083 20.7875 6.2125C20.9292 6.35417 21 6.53333 21 6.75C21 6.96667 20.9292 7.14583 20.7875 7.2875C20.6458 7.42917 20.4667 7.5 20.25 7.5H3.75Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/plus-icon.tsx
Normal file
21
apps/app/ui/icons/plus-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const PlusIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 19C11.7833 19 11.6042 18.9292 11.4625 18.7875C11.3208 18.6458 11.25 18.4667 11.25 18.25V12.75H5.75C5.53333 12.75 5.35417 12.6792 5.2125 12.5375C5.07083 12.3958 5 12.2167 5 12C5 11.7833 5.07083 11.6042 5.2125 11.4625C5.35417 11.3208 5.53333 11.25 5.75 11.25H11.25V5.75C11.25 5.53333 11.3208 5.35417 11.4625 5.2125C11.6042 5.07083 11.7833 5 12 5C12.2167 5 12.3958 5.07083 12.5375 5.2125C12.6792 5.35417 12.75 5.53333 12.75 5.75V11.25H18.25C18.4667 11.25 18.6458 11.3208 18.7875 11.4625C18.9292 11.6042 19 11.7833 19 12C19 12.2167 18.9292 12.3958 18.7875 12.5375C18.6458 12.6792 18.4667 12.75 18.25 12.75H12.75V18.25C12.75 18.4667 12.6792 18.6458 12.5375 18.7875C12.3958 18.9292 12.2167 19 12 19Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/setting-icon.tsx
Normal file
21
apps/app/ui/icons/setting-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const SettingIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M14.0794 1.5C14.2382 1.50001 14.3929 1.55041 14.5212 1.64394C14.6495 1.73748 14.7448 1.86933 14.7934 2.0205L15.6184 4.584C15.9649 4.7535 16.2964 4.944 16.6129 5.1585L19.2469 4.5915C19.4022 4.55834 19.564 4.57534 19.7091 4.64003C19.8541 4.70473 19.9748 4.81379 20.0539 4.9515L22.1329 8.55C22.2123 8.68763 22.2459 8.84693 22.2289 9.0049C22.212 9.16288 22.1452 9.31139 22.0384 9.429L20.2309 11.424C20.2572 11.8065 20.2572 12.1905 20.2309 12.573L22.0384 14.571C22.1452 14.6886 22.212 14.8371 22.2289 14.9951C22.2459 15.1531 22.2123 15.3124 22.1329 15.45L20.0539 19.05C19.9746 19.1874 19.8538 19.2962 19.7088 19.3606C19.5638 19.425 19.4021 19.4418 19.2469 19.4085L16.6129 18.8415C16.2979 19.0545 15.9649 19.2465 15.6199 19.416L14.7934 21.9795C14.7448 22.1307 14.6495 22.2625 14.5212 22.3561C14.3929 22.4496 14.2382 22.5 14.0794 22.5H9.92141C9.76262 22.5 9.60793 22.4496 9.47962 22.3561C9.35131 22.2625 9.256 22.1307 9.20741 21.9795L8.38391 19.4175C8.03834 19.2485 7.70502 19.0555 7.38641 18.84L4.75391 19.4085C4.5986 19.4417 4.43678 19.4247 4.29176 19.36C4.14673 19.2953 4.02598 19.1862 3.94691 19.0485L1.86791 15.45C1.78852 15.3124 1.75489 15.1531 1.77188 14.9951C1.78886 14.8371 1.85558 14.6886 1.96241 14.571L3.76991 12.573C3.74372 12.1914 3.74372 11.8086 3.76991 11.427L1.96241 9.429C1.85558 9.31139 1.78886 9.16288 1.77188 9.0049C1.75489 8.84693 1.78852 8.68763 1.86791 8.55L3.94691 4.95C4.0262 4.81256 4.14704 4.70381 4.29205 4.63939C4.43706 4.57497 4.59876 4.55821 4.75391 4.5915L7.38641 5.16C7.70441 4.9455 8.03741 4.752 8.38391 4.5825L9.20891 2.0205C9.25734 1.86982 9.3522 1.73832 9.47991 1.64482C9.60762 1.55133 9.76163 1.50064 9.91991 1.5H14.0779H14.0794ZM13.5304 3H10.4704L9.61841 5.6505L9.04391 5.931C8.76148 6.06921 8.48885 6.22657 8.22791 6.402L7.69691 6.762L4.97291 6.174L3.44291 8.826L5.31041 10.893L5.26541 11.529C5.24385 11.8426 5.24385 12.1574 5.26541 12.471L5.31041 13.107L3.43991 15.174L4.97141 17.826L7.69541 17.2395L8.22641 17.598C8.48735 17.7734 8.75998 17.9308 9.04241 18.069L9.61691 18.3495L10.4704 21H13.5334L14.3884 18.348L14.9614 18.069C15.2435 17.9311 15.5157 17.7737 15.7759 17.598L16.3054 17.2395L19.0309 17.826L20.5609 15.174L18.6919 13.107L18.7369 12.471C18.7585 12.1569 18.7585 11.8416 18.7369 11.5275L18.6919 10.8915L20.5624 8.826L19.0309 6.174L16.3054 6.759L15.7759 6.402C15.5157 6.22622 15.2435 6.06884 14.9614 5.931L14.3884 5.652L13.5319 3H13.5304ZM12.0004 7.5C13.1939 7.5 14.3385 7.97411 15.1824 8.81802C16.0263 9.66193 16.5004 10.8065 16.5004 12C16.5004 13.1935 16.0263 14.3381 15.1824 15.182C14.3385 16.0259 13.1939 16.5 12.0004 16.5C10.8069 16.5 9.66234 16.0259 8.81843 15.182C7.97451 14.3381 7.50041 13.1935 7.50041 12C7.50041 10.8065 7.97451 9.66193 8.81843 8.81802C9.66234 7.97411 10.8069 7.5 12.0004 7.5ZM12.0004 9C11.2048 9 10.4417 9.31607 9.87909 9.87868C9.31648 10.4413 9.00041 11.2044 9.00041 12C9.00041 12.7956 9.31648 13.5587 9.87909 14.1213C10.4417 14.6839 11.2048 15 12.0004 15C12.7961 15 13.5591 14.6839 14.1217 14.1213C14.6843 13.5587 15.0004 12.7956 15.0004 12C15.0004 11.2044 14.6843 10.4413 14.1217 9.87868C13.5591 9.31607 12.7961 9 12.0004 9Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/signal-cellular-icon.tsx
Normal file
21
apps/app/ui/icons/signal-cellular-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const SignalCellularIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M18.75 20C18.4 20 18.1042 19.8792 17.8625 19.6375C17.6208 19.3958 17.5 19.1 17.5 18.75V5.25C17.5 4.9 17.6208 4.60417 17.8625 4.3625C18.1042 4.12083 18.4 4 18.75 4C19.1 4 19.3958 4.12083 19.6375 4.3625C19.8792 4.60417 20 4.9 20 5.25V18.75C20 19.1 19.8792 19.3958 19.6375 19.6375C19.3958 19.8792 19.1 20 18.75 20ZM6.275 20C6.09167 20 5.92083 19.9667 5.7625 19.9C5.60417 19.8333 5.47083 19.7458 5.3625 19.6375C5.25417 19.5292 5.16667 19.3958 5.1 19.2375C5.03333 19.0792 5 18.9167 5 18.75V15.25C5 14.9 5.12083 14.6042 5.3625 14.3625C5.60417 14.1208 5.9 14 6.25 14C6.6 14 6.89583 14.1208 7.1375 14.3625C7.37917 14.6042 7.5 14.9 7.5 15.25V18.75C7.5 18.9167 7.46667 19.0792 7.4 19.2375C7.33333 19.3958 7.24583 19.5292 7.1375 19.6375C7.02917 19.7458 6.9 19.8333 6.75 19.9C6.6 19.9667 6.44167 20 6.275 20ZM12.5 20C12.15 20 11.8542 19.8792 11.6125 19.6375C11.3708 19.3958 11.25 19.1 11.25 18.75V10.25C11.25 9.9 11.3708 9.60417 11.6125 9.3625C11.8542 9.12083 12.15 9 12.5 9C12.85 9 13.1458 9.12083 13.3875 9.3625C13.6292 9.60417 13.75 9.9 13.75 10.25V18.75C13.75 19.1 13.6292 19.3958 13.3875 19.6375C13.1458 19.8792 12.85 20 12.5 20Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
26
apps/app/ui/icons/tag-icon.tsx
Normal file
26
apps/app/ui/icons/tag-icon.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const TagIcon: React.FC<Props> = ({
|
||||
width = "24",
|
||||
height = "24",
|
||||
className,
|
||||
color = "black",
|
||||
}) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M13.975 21.575C13.675 21.875 13.3125 22.025 12.8875 22.025C12.4625 22.025 12.1 21.875 11.8 21.575L2.425 12.2C2.25833 12.0333 2.14583 11.8583 2.0875 11.675C2.02917 11.4917 2 11.3 2 11.1V3.5C2 3.06667 2.14167 2.70833 2.425 2.425C2.70833 2.14167 3.06667 2 3.5 2H11.1C11.3 2 11.5 2.02917 11.7 2.0875C11.9 2.14583 12.0833 2.25833 12.25 2.425L21.575 11.75C21.8917 12.0667 22.05 12.4375 22.05 12.8625C22.05 13.2875 21.8917 13.6583 21.575 13.975L13.975 21.575ZM12.95 20.55L20.55 12.95L11.1 3.5H3.5V11.1L12.95 20.55ZM6.125 7.4C6.475 7.4 6.77917 7.27083 7.0375 7.0125C7.29583 6.75417 7.425 6.45 7.425 6.1C7.425 5.75 7.29583 5.44583 7.0375 5.1875C6.77917 4.92917 6.475 4.8 6.125 4.8C5.775 4.8 5.47083 4.92917 5.2125 5.1875C4.95417 5.44583 4.825 5.75 4.825 6.1C4.825 6.45 4.95417 6.75417 5.2125 7.0125C5.47083 7.27083 5.775 7.4 6.125 7.4Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/tune-icon.tsx
Normal file
21
apps/app/ui/icons/tune-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const TuneIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3.75 18.95C3.53333 18.95 3.35417 18.8792 3.2125 18.7375C3.07083 18.5958 3 18.4167 3 18.2C3 17.9833 3.07083 17.8042 3.2125 17.6625C3.35417 17.5208 3.53333 17.45 3.75 17.45H8.425C8.64167 17.45 8.82083 17.5208 8.9625 17.6625C9.10417 17.8042 9.175 17.9833 9.175 18.2C9.175 18.4167 9.10417 18.5958 8.9625 18.7375C8.82083 18.8792 8.64167 18.95 8.425 18.95H3.75ZM3.75 6.55C3.53333 6.55 3.35417 6.47917 3.2125 6.3375C3.07083 6.19583 3 6.01667 3 5.8C3 5.58333 3.07083 5.40417 3.2125 5.2625C3.35417 5.12083 3.53333 5.05 3.75 5.05H12.575C12.7917 5.05 12.9708 5.12083 13.1125 5.2625C13.2542 5.40417 13.325 5.58333 13.325 5.8C13.325 6.01667 13.2542 6.19583 13.1125 6.3375C12.9708 6.47917 12.7917 6.55 12.575 6.55H3.75ZM11.425 21C11.2083 21 11.0292 20.9292 10.8875 20.7875C10.7458 20.6458 10.675 20.4667 10.675 20.25V16.125C10.675 15.9083 10.7458 15.7292 10.8875 15.5875C11.0292 15.4458 11.2083 15.375 11.425 15.375C11.6417 15.375 11.8208 15.4458 11.9625 15.5875C12.1042 15.7292 12.175 15.9083 12.175 16.125V17.45H20.25C20.4667 17.45 20.6458 17.5208 20.7875 17.6625C20.9292 17.8042 21 17.9833 21 18.2C21 18.4167 20.9292 18.5958 20.7875 18.7375C20.6458 18.8792 20.4667 18.95 20.25 18.95H12.175V20.25C12.175 20.4667 12.1042 20.6458 11.9625 20.7875C11.8208 20.9292 11.6417 21 11.425 21ZM8.425 14.8C8.20833 14.8 8.02917 14.7292 7.8875 14.5875C7.74583 14.4458 7.675 14.2667 7.675 14.05V12.75H3.75C3.53333 12.75 3.35417 12.6792 3.2125 12.5375C3.07083 12.3958 3 12.2167 3 12C3 11.7833 3.07083 11.6042 3.2125 11.4625C3.35417 11.3208 3.53333 11.25 3.75 11.25H7.675V9.9C7.675 9.68333 7.74583 9.50417 7.8875 9.3625C8.02917 9.22083 8.20833 9.15 8.425 9.15C8.64167 9.15 8.82083 9.22083 8.9625 9.3625C9.10417 9.50417 9.175 9.68333 9.175 9.9V14.05C9.175 14.2667 9.10417 14.4458 8.9625 14.5875C8.82083 14.7292 8.64167 14.8 8.425 14.8ZM11.425 12.75C11.2083 12.75 11.0292 12.6792 10.8875 12.5375C10.7458 12.3958 10.675 12.2167 10.675 12C10.675 11.7833 10.7458 11.6042 10.8875 11.4625C11.0292 11.3208 11.2083 11.25 11.425 11.25H20.25C20.4667 11.25 20.6458 11.3208 20.7875 11.4625C20.9292 11.6042 21 11.7833 21 12C21 12.2167 20.9292 12.3958 20.7875 12.5375C20.6458 12.6792 20.4667 12.75 20.25 12.75H11.425ZM15.575 8.625C15.3583 8.625 15.1792 8.55417 15.0375 8.4125C14.8958 8.27083 14.825 8.09167 14.825 7.875V3.75C14.825 3.53333 14.8958 3.35417 15.0375 3.2125C15.1792 3.07083 15.3583 3 15.575 3C15.7917 3 15.9708 3.07083 16.1125 3.2125C16.2542 3.35417 16.325 3.53333 16.325 3.75V5.05H20.25C20.4667 5.05 20.6458 5.12083 20.7875 5.2625C20.9292 5.40417 21 5.58333 21 5.8C21 6.01667 20.9292 6.19583 20.7875 6.3375C20.6458 6.47917 20.4667 6.55 20.25 6.55H16.325V7.875C16.325 8.09167 16.2542 8.27083 16.1125 8.4125C15.9708 8.55417 15.7917 8.625 15.575 8.625Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
6
apps/app/ui/icons/types.d.ts
vendored
Normal file
6
apps/app/ui/icons/types.d.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export type Props = {
|
||||
className?: string;
|
||||
width?: string | number;
|
||||
height?: string | number;
|
||||
color?: string;
|
||||
};
|
||||
19
apps/app/ui/icons/upcoming-cycle-icon.tsx
Normal file
19
apps/app/ui/icons/upcoming-cycle-icon.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const UpcomingCycleIcon: React.FC<Props> = ({
|
||||
width = "24",
|
||||
height = "24",
|
||||
className,
|
||||
color = "black",
|
||||
}) => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height={height} width={width} className={className}>
|
||||
<path
|
||||
d="M28.3 44v-3H39V19.5H9v11H6V10q0-1.2.9-2.1Q7.8 7 9 7h3.25V4h3.25v3h17V4h3.25v3H39q1.2 0 2.1.9.9.9.9 2.1v31q0 1.2-.9 2.1-.9.9-2.1.9ZM16 47.3l-2.1-2.1 5.65-5.7H2.5v-3h17.05l-5.65-5.7 2.1-2.1 9.3 9.3ZM9 16.5h30V10H9Zm0 0V10v6.5Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/user-group-icon.tsx
Normal file
21
apps/app/ui/icons/user-group-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const UserGroupIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M14.754 10C15.72 10 16.504 10.784 16.504 11.75V16.499C16.504 17.6927 16.0298 18.8376 15.1857 19.6817C14.3416 20.5258 13.1967 21 12.003 21C10.8093 21 9.66441 20.5258 8.82031 19.6817C7.97621 18.8376 7.502 17.6927 7.502 16.499V11.75C7.502 10.784 8.285 10 9.252 10H14.754ZM14.754 11.5H9.252C9.1857 11.5 9.12211 11.5263 9.07522 11.5732C9.02834 11.6201 9.002 11.6837 9.002 11.75V16.499C9.002 17.2949 9.31818 18.0582 9.88097 18.621C10.4438 19.1838 11.2071 19.5 12.003 19.5C12.7989 19.5 13.5622 19.1838 14.125 18.621C14.6878 18.0582 15.004 17.2949 15.004 16.499V11.75C15.004 11.6837 14.9777 11.6201 14.9308 11.5732C14.8839 11.5263 14.8203 11.5 14.754 11.5ZM3.75 10H7.131C6.7782 10.4261 6.56274 10.949 6.513 11.5H3.75C3.6837 11.5 3.62011 11.5263 3.57322 11.5732C3.52634 11.6201 3.5 11.6837 3.5 11.75V14.999C3.49994 15.3769 3.5855 15.7499 3.75027 16.0899C3.91504 16.43 4.15473 16.7283 4.45133 16.9625C4.74793 17.1966 5.09374 17.3605 5.46277 17.4418C5.83179 17.5231 6.21445 17.5198 6.582 17.432C6.667 17.936 6.822 18.417 7.035 18.864C6.44228 19.0226 5.82103 19.0427 5.21929 18.9228C4.61756 18.8029 4.05145 18.5463 3.56475 18.1727C3.07805 17.7991 2.68379 17.3185 2.41246 16.7682C2.14114 16.2179 2.00001 15.6126 2 14.999V11.75C2 10.784 2.784 10 3.75 10ZM16.875 10H20.25C21.216 10 22 10.784 22 11.75V15C22.0001 15.6132 21.8593 16.2182 21.5884 16.7682C21.3175 17.3183 20.9237 17.7987 20.4376 18.1724C19.9514 18.546 19.3858 18.8029 18.7846 18.9232C18.1833 19.0435 17.5625 19.0239 16.97 18.866C17.184 18.418 17.339 17.937 17.425 17.433C17.7921 17.5198 18.174 17.5223 18.5423 17.4405C18.9105 17.3587 19.2554 17.1946 19.5512 16.9606C19.847 16.7265 20.086 16.4286 20.2503 16.089C20.4147 15.7495 20.5 15.3772 20.5 15V11.75C20.5 11.6837 20.4737 11.6201 20.4268 11.5732C20.3799 11.5263 20.3163 11.5 20.25 11.5H17.493C17.4433 10.949 17.2278 10.4261 16.875 10ZM12 3C12.7956 3 13.5587 3.31607 14.1213 3.87868C14.6839 4.44129 15 5.20435 15 6C15 6.79565 14.6839 7.55871 14.1213 8.12132C13.5587 8.68393 12.7956 9 12 9C11.2044 9 10.4413 8.68393 9.87868 8.12132C9.31607 7.55871 9 6.79565 9 6C9 5.20435 9.31607 4.44129 9.87868 3.87868C10.4413 3.31607 11.2044 3 12 3ZM18.5 4C19.163 4 19.7989 4.26339 20.2678 4.73223C20.7366 5.20107 21 5.83696 21 6.5C21 7.16304 20.7366 7.79893 20.2678 8.26777C19.7989 8.73661 19.163 9 18.5 9C17.837 9 17.2011 8.73661 16.7322 8.26777C16.2634 7.79893 16 7.16304 16 6.5C16 5.83696 16.2634 5.20107 16.7322 4.73223C17.2011 4.26339 17.837 4 18.5 4ZM5.5 4C6.16304 4 6.79893 4.26339 7.26777 4.73223C7.73661 5.20107 8 5.83696 8 6.5C8 7.16304 7.73661 7.79893 7.26777 8.26777C6.79893 8.73661 6.16304 9 5.5 9C4.83696 9 4.20107 8.73661 3.73223 8.26777C3.26339 7.79893 3 7.16304 3 6.5C3 5.83696 3.26339 5.20107 3.73223 4.73223C4.20107 4.26339 4.83696 4 5.5 4ZM12 4.5C11.6022 4.5 11.2206 4.65804 10.9393 4.93934C10.658 5.22064 10.5 5.60218 10.5 6C10.5 6.39782 10.658 6.77936 10.9393 7.06066C11.2206 7.34196 11.6022 7.5 12 7.5C12.3978 7.5 12.7794 7.34196 13.0607 7.06066C13.342 6.77936 13.5 6.39782 13.5 6C13.5 5.60218 13.342 5.22064 13.0607 4.93934C12.7794 4.65804 12.3978 4.5 12 4.5ZM18.5 5.5C18.2348 5.5 17.9804 5.60536 17.7929 5.79289C17.6054 5.98043 17.5 6.23478 17.5 6.5C17.5 6.76522 17.6054 7.01957 17.7929 7.20711C17.9804 7.39464 18.2348 7.5 18.5 7.5C18.7652 7.5 19.0196 7.39464 19.2071 7.20711C19.3946 7.01957 19.5 6.76522 19.5 6.5C19.5 6.23478 19.3946 5.98043 19.2071 5.79289C19.0196 5.60536 18.7652 5.5 18.5 5.5ZM5.5 5.5C5.23478 5.5 4.98043 5.60536 4.79289 5.79289C4.60536 5.98043 4.5 6.23478 4.5 6.5C4.5 6.76522 4.60536 7.01957 4.79289 7.20711C4.98043 7.39464 5.23478 7.5 5.5 7.5C5.76522 7.5 6.01957 7.39464 6.20711 7.20711C6.39464 7.01957 6.5 6.76522 6.5 6.5C6.5 6.23478 6.39464 5.98043 6.20711 5.79289C6.01957 5.60536 5.76522 5.5 5.5 5.5Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
18
apps/app/ui/icons/user-icon-circle.tsx
Normal file
18
apps/app/ui/icons/user-icon-circle.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const UserCircleIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M5.55 17.625C6.6 16.8917 7.64167 16.3292 8.675 15.9375C9.70833 15.5458 10.8167 15.35 12 15.35C13.1833 15.35 14.2958 15.5458 15.3375 15.9375C16.3792 16.3292 17.425 16.8917 18.475 17.625C19.2083 16.725 19.7292 15.8167 20.0375 14.9C20.3458 13.9833 20.5 13.0167 20.5 12C20.5 9.58333 19.6875 7.5625 18.0625 5.9375C16.4375 4.3125 14.4167 3.5 12 3.5C9.58333 3.5 7.5625 4.3125 5.9375 5.9375C4.3125 7.5625 3.5 9.58333 3.5 12C3.5 13.0167 3.65833 13.9833 3.975 14.9C4.29167 15.8167 4.81667 16.725 5.55 17.625ZM12 12.75C11.0333 12.75 10.2208 12.4208 9.5625 11.7625C8.90417 11.1042 8.575 10.2917 8.575 9.325C8.575 8.35833 8.90417 7.54583 9.5625 6.8875C10.2208 6.22917 11.0333 5.9 12 5.9C12.9667 5.9 13.7792 6.22917 14.4375 6.8875C15.0958 7.54583 15.425 8.35833 15.425 9.325C15.425 10.2917 15.0958 11.1042 14.4375 11.7625C13.7792 12.4208 12.9667 12.75 12 12.75ZM12 22C10.6333 22 9.34167 21.7375 8.125 21.2125C6.90833 20.6875 5.84583 19.9708 4.9375 19.0625C4.02917 18.1542 3.3125 17.0917 2.7875 15.875C2.2625 14.6583 2 13.3667 2 12C2 10.6167 2.2625 9.32083 2.7875 8.1125C3.3125 6.90417 4.02917 5.84583 4.9375 4.9375C5.84583 4.02917 6.90833 3.3125 8.125 2.7875C9.34167 2.2625 10.6333 2 12 2C13.3833 2 14.6792 2.2625 15.8875 2.7875C17.0958 3.3125 18.1542 4.02917 19.0625 4.9375C19.9708 5.84583 20.6875 6.90417 21.2125 8.1125C21.7375 9.32083 22 10.6167 22 12C22 13.3667 21.7375 14.6583 21.2125 15.875C20.6875 17.0917 19.9708 18.1542 19.0625 19.0625C18.1542 19.9708 17.0958 20.6875 15.8875 21.2125C14.6792 21.7375 13.3833 22 12 22ZM12 20.5C12.9167 20.5 13.8125 20.3667 14.6875 20.1C15.5625 19.8333 16.425 19.3667 17.275 18.7C16.425 18.1 15.5583 17.6417 14.675 17.325C13.7917 17.0083 12.9 16.85 12 16.85C11.1 16.85 10.2083 17.0083 9.325 17.325C8.44167 17.6417 7.575 18.1 6.725 18.7C7.575 19.3667 8.4375 19.8333 9.3125 20.1C10.1875 20.3667 11.0833 20.5 12 20.5ZM12 11.25C12.5667 11.25 13.0292 11.0708 13.3875 10.7125C13.7458 10.3542 13.925 9.89167 13.925 9.325C13.925 8.75833 13.7458 8.29583 13.3875 7.9375C13.0292 7.57917 12.5667 7.4 12 7.4C11.4333 7.4 10.9708 7.57917 10.6125 7.9375C10.2542 8.29583 10.075 8.75833 10.075 9.325C10.075 9.89167 10.2542 10.3542 10.6125 10.7125C10.9708 11.0708 11.4333 11.25 12 11.25Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
21
apps/app/ui/icons/user-icon.tsx
Normal file
21
apps/app/ui/icons/user-icon.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from "react";
|
||||
|
||||
import type { Props } from "./types";
|
||||
|
||||
export const UserIcon: React.FC<Props> = ({ width = "24", height = "24", className }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 11.9751C10.9 11.9751 10 11.6251 9.3 10.9251C8.6 10.2251 8.25 9.3251 8.25 8.2251C8.25 7.1251 8.6 6.2251 9.3 5.5251C10 4.8251 10.9 4.4751 12 4.4751C13.1 4.4751 14 4.8251 14.7 5.5251C15.4 6.2251 15.75 7.1251 15.75 8.2251C15.75 9.3251 15.4 10.2251 14.7 10.9251C14 11.6251 13.1 11.9751 12 11.9751ZM18.5 20.0001H5.5C5.08333 20.0001 4.72917 19.8543 4.4375 19.5626C4.14583 19.2709 4 18.9168 4 18.5001V17.6501C4 17.0168 4.15833 16.4751 4.475 16.0251C4.79167 15.5751 5.2 15.2334 5.7 15.0001C6.81667 14.5001 7.8875 14.1251 8.9125 13.8751C9.9375 13.6251 10.9667 13.5001 12 13.5001C13.0333 13.5001 14.0583 13.6293 15.075 13.8876C16.0917 14.1459 17.1583 14.5168 18.275 15.0001C18.7917 15.2334 19.2083 15.5751 19.525 16.0251C19.8417 16.4751 20 17.0168 20 17.6501V18.5001C20 18.9168 19.8542 19.2709 19.5625 19.5626C19.2708 19.8543 18.9167 20.0001 18.5 20.0001ZM5.5 18.5001H18.5V17.6501C18.5 17.3834 18.4208 17.1293 18.2625 16.8876C18.1042 16.6459 17.9083 16.4668 17.675 16.3501C16.6083 15.8334 15.6333 15.4793 14.75 15.2876C13.8667 15.0959 12.95 15.0001 12 15.0001C11.05 15.0001 10.125 15.0959 9.225 15.2876C8.325 15.4793 7.35 15.8334 6.3 16.3501C6.06667 16.4668 5.875 16.6459 5.725 16.8876C5.575 17.1293 5.5 17.3834 5.5 17.6501V18.5001ZM12 10.4751C12.65 10.4751 13.1875 10.2626 13.6125 9.8376C14.0375 9.4126 14.25 8.8751 14.25 8.2251C14.25 7.5751 14.0375 7.0376 13.6125 6.6126C13.1875 6.1876 12.65 5.9751 12 5.9751C11.35 5.9751 10.8125 6.1876 10.3875 6.6126C9.9625 7.0376 9.75 7.5751 9.75 8.2251C9.75 8.8751 9.9625 9.4126 10.3875 9.8376C10.8125 10.2626 11.35 10.4751 12 10.4751Z"
|
||||
fill="#212529"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
export { default as Button } from "./Button";
|
||||
export { default as Input } from "./Input";
|
||||
export { default as Select } from "./Select";
|
||||
export { default as TextArea } from "./TextArea";
|
||||
export * from "./breadcrumbs";
|
||||
export { default as Button } from "./button";
|
||||
export { default as CustomListbox } from "./custom-listbox";
|
||||
export { default as CustomMenu } from "./custom-menu";
|
||||
export { default as CustomSelect } from "./custom-select";
|
||||
export { default as Spinner } from "./Spinner";
|
||||
export { default as Tooltip } from "./Tooltip";
|
||||
export { default as SearchListbox } from "./search-listbox";
|
||||
export { default as HeaderButton } from "./HeaderButton";
|
||||
export * from "./Breadcrumbs";
|
||||
export * from "./empty-space";
|
||||
export { default as EmojiIconPicker } from "./emoji-icon-picker";
|
||||
export * from "./empty-space";
|
||||
export { default as HeaderButton } from "./header-button";
|
||||
export { default as Input } from "./input";
|
||||
export { default as Loader } from "./loader";
|
||||
export { default as OutlineButton } from "./outline-button";
|
||||
export { default as SearchListbox } from "./search-listbox";
|
||||
export { default as Select } from "./select";
|
||||
export { default as Spinner } from "./spinner";
|
||||
export { default as TextArea } from "./text-area";
|
||||
export { default as Tooltip } from "./tooltip";
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const Input: React.FC<Props> = ({
|
|||
return (
|
||||
<>
|
||||
{label && (
|
||||
<label htmlFor={id} className="text-gray-500 mb-2">
|
||||
<label htmlFor={id} className="mb-2 text-gray-500">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
|
|
@ -37,10 +37,10 @@ const Input: React.FC<Props> = ({
|
|||
onChange && onChange(e);
|
||||
}}
|
||||
className={classNames(
|
||||
"block text-base focus:outline-none sm:text-sm rounded-md bg-transparent",
|
||||
mode === "primary" ? "border border-gray-300 rounded-md" : "",
|
||||
"block rounded-md bg-transparent text-sm focus:outline-none",
|
||||
mode === "primary" ? "rounded-md border border-gray-300" : "",
|
||||
mode === "transparent"
|
||||
? "bg-transparent border-none transition-all ring-0 focus:ring-1 focus:ring-indigo-500 rounded"
|
||||
? "rounded border-none bg-transparent ring-0 transition-all focus:ring-1 focus:ring-indigo-500"
|
||||
: "",
|
||||
error ? "border-red-500" : "",
|
||||
error && mode === "primary" ? "bg-red-100" : "",
|
||||
|
|
@ -50,7 +50,7 @@ const Input: React.FC<Props> = ({
|
|||
)}
|
||||
{...rest}
|
||||
/>
|
||||
{error?.message && <div className="text-red-500 text-sm">{error.message}</div>}
|
||||
{error?.message && <div className="text-sm text-red-500">{error.message}</div>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
33
apps/app/ui/loader/index.tsx
Normal file
33
apps/app/ui/loader/index.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import React from "react";
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const Loader = ({ children, className = "" }: Props) => {
|
||||
return (
|
||||
<div className={`${className} animate-pulse`} role="status">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
type ItemProps = {
|
||||
height?: string;
|
||||
width?: string;
|
||||
light?: boolean;
|
||||
};
|
||||
|
||||
const Item: React.FC<ItemProps> = ({ height = "auto", width = "auto", light }) => {
|
||||
return (
|
||||
<div
|
||||
className={`rounded-md ${light ? "bg-gray-200" : "bg-gray-300"}`}
|
||||
style={{ height: height, width: width }}
|
||||
></div>
|
||||
);
|
||||
};
|
||||
|
||||
Loader.Item = Item;
|
||||
|
||||
export default Loader;
|
||||
|
|
@ -2,7 +2,7 @@ import { Fragment, ReactNode } from "react";
|
|||
// Headless ui imports
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// Design components
|
||||
import Button from "ui/Button";
|
||||
import { Button } from "ui";
|
||||
// Icons
|
||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
|
|
@ -73,11 +73,11 @@ const Modal = (props: ModalProps) => {
|
|||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel
|
||||
className={`transform rounded-2xl ${width} bg-white p-8 text-left max-h-full shadow-xl transition-all`}
|
||||
className={`transform rounded-2xl ${width} max-h-full bg-white p-8 text-left shadow-xl transition-all`}
|
||||
>
|
||||
<Dialog.Title
|
||||
as="h3"
|
||||
className="text-lg font-medium leading-6 text-gray-900 relative"
|
||||
className="relative text-lg font-medium leading-6 text-gray-900"
|
||||
>
|
||||
<div
|
||||
className="absolute top-[-1rem] right-[-1rem] cursor-pointer"
|
||||
|
|
@ -89,13 +89,11 @@ const Modal = (props: ModalProps) => {
|
|||
</Dialog.Title>
|
||||
<div className="mt-2">{props.children}</div>
|
||||
<div className="mt-4">
|
||||
<div className={`flex gap-2 justify-end`}>
|
||||
<div className={`flex justify-end gap-2`}>
|
||||
<Button theme="secondary" onClick={closeModal}>
|
||||
{props.closeButton}
|
||||
</Button>
|
||||
<Button onClick={closeModal}>
|
||||
{props.continueButton}
|
||||
</Button>
|
||||
<Button onClick={closeModal}>{props.continueButton}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
81
apps/app/ui/multi-input/index.tsx
Normal file
81
apps/app/ui/multi-input/index.tsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
// react
|
||||
import React from "react";
|
||||
// common
|
||||
import { classNames } from "constants/common";
|
||||
|
||||
const isEmailValid = (email: string) => {
|
||||
return String(email)
|
||||
.toLowerCase()
|
||||
.match(
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
);
|
||||
};
|
||||
|
||||
const MultiInput = ({ label, name, placeholder, setValue, watch }: any) => {
|
||||
const handleKeyDown = (e: any) => {
|
||||
if (e.key !== "Enter") return;
|
||||
const value = e.target.value;
|
||||
if (!value.trim()) return;
|
||||
if (isEmailValid(value) && !watch(name)?.find((item: any) => item.email === value)) {
|
||||
setValue(name, [...(watch(name) || []), { email: value }]);
|
||||
e.target.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = (e: React.FocusEvent<HTMLInputElement, Element>) => {
|
||||
const value = e.target.value;
|
||||
if (!value.trim()) return;
|
||||
if (isEmailValid(value) && !watch(name)?.find((item: any) => item.email === value)) {
|
||||
setValue(name, [...(watch(name) || []), { email: value }]);
|
||||
e.target.value = "";
|
||||
} else {
|
||||
e.target.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value.trim();
|
||||
if (!value) return;
|
||||
if (value.includes(",")) {
|
||||
const tags = value.split(",");
|
||||
tags.forEach((tag: string) => {
|
||||
if (isEmailValid(tag) && !watch(name)?.find((item: any) => item.email === tag)) {
|
||||
setValue(name, [...(watch(name) || []), { email: tag }]);
|
||||
}
|
||||
});
|
||||
e.target.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
const removeTag = (index: Number) => {
|
||||
setValue(
|
||||
name,
|
||||
watch(name).filter((_: string, i: any) => i !== index)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{label && <label className="mb-2 text-gray-500">{label}</label>}
|
||||
<div className="rounded-md border p-2">
|
||||
{watch(name)?.map((tag: any, index: number) => (
|
||||
<button type="button" className="m-1.5 rounded-full bg-slate-300 p-1.5" key={index}>
|
||||
{tag.email} <span onClick={() => removeTag(index)}>×</span>
|
||||
</button>
|
||||
))}
|
||||
<input
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={handleBlur}
|
||||
onChange={handleChange}
|
||||
type="text"
|
||||
placeholder={placeholder}
|
||||
className={classNames(
|
||||
"block w-full rounded-md bg-transparent p-1.5 text-sm focus:outline-none"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MultiInput;
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
import React from "react";
|
||||
// commons
|
||||
import { classNames } from "constants/common";
|
||||
|
||||
type Props = {
|
||||
onClick?: () => void;
|
||||
|
|
@ -10,10 +12,7 @@ type Props = {
|
|||
disabled?: boolean;
|
||||
};
|
||||
|
||||
// commons
|
||||
import { classNames } from "constants/common";
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, Props>(
|
||||
const OutlineButton = React.forwardRef<HTMLButtonElement, Props>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
|
|
@ -28,32 +27,32 @@ const Button = React.forwardRef<HTMLButtonElement, Props>(
|
|||
) => {
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
ref={ref}
|
||||
onClick={onClick}
|
||||
type={type}
|
||||
disabled={disabled}
|
||||
className={classNames(
|
||||
className,
|
||||
"inline-flex items-center rounded justify-center font-medium",
|
||||
"inline-flex items-center justify-center rounded font-medium duration-300",
|
||||
theme === "primary"
|
||||
? `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} text-white shadow-sm bg-theme hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 border border-transparent`
|
||||
} border border-theme text-white shadow-sm hover:bg-theme focus:outline-none`
|
||||
: theme === "secondary"
|
||||
? "border bg-transparent hover:bg-gray-100"
|
||||
: theme === "success"
|
||||
? `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} text-white shadow-sm bg-green-500 hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 border border-transparent`
|
||||
} border border-transparent bg-green-500 text-white shadow-sm hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500`
|
||||
: `${
|
||||
disabled ? "opacity-70" : ""
|
||||
} text-white shadow-sm bg-red-500 hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 border border-transparent`,
|
||||
} border border-red-500 text-red-500 shadow-sm hover:bg-red-500 hover:text-white focus:outline-none focus:ring-2 focus:ring-red-500`,
|
||||
size === "sm"
|
||||
? "p-2 text-xs"
|
||||
: size === "md"
|
||||
? "px-3 py-2 text-base"
|
||||
? "text-md px-3 py-2"
|
||||
: size === "lg"
|
||||
? "px-4 py-2 text-base"
|
||||
? "text-md px-4 py-2"
|
||||
: "px-2.5 py-2 text-sm"
|
||||
)}
|
||||
>
|
||||
|
|
@ -63,6 +62,6 @@ const Button = React.forwardRef<HTMLButtonElement, Props>(
|
|||
}
|
||||
);
|
||||
|
||||
Button.displayName = "Button";
|
||||
OutlineButton.displayName = "Button";
|
||||
|
||||
export default Button;
|
||||
export default OutlineButton;
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
import React, { useState } from "react";
|
||||
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import useSWR from "swr";
|
||||
// services
|
||||
import workspaceService from "lib/services/workspace.service";
|
||||
// headless ui
|
||||
import { Transition, Combobox } from "@headlessui/react";
|
||||
// common
|
||||
import { classNames } from "constants/common";
|
||||
// types
|
||||
import type { Props } from "./types";
|
||||
// common
|
||||
import { classNames } from "constants/common";
|
||||
// fetch-keys
|
||||
import { WORKSPACE_MEMBERS } from "constants/fetch-keys";
|
||||
|
||||
const SearchListbox: React.FC<Props> = ({
|
||||
title,
|
||||
|
|
@ -17,9 +26,13 @@ const SearchListbox: React.FC<Props> = ({
|
|||
optionsFontsize,
|
||||
buttonClassName,
|
||||
optionsClassName,
|
||||
assignee = false,
|
||||
}) => {
|
||||
const [query, setQuery] = useState("");
|
||||
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
const filteredOptions =
|
||||
query === ""
|
||||
? options
|
||||
|
|
@ -38,13 +51,45 @@ const SearchListbox: React.FC<Props> = ({
|
|||
props.multiple = true;
|
||||
}
|
||||
|
||||
const { data: people } = useSWR(
|
||||
workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug as string) : null,
|
||||
workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null
|
||||
);
|
||||
|
||||
const userAvatar = (userId: string) => {
|
||||
const user = people?.find((p) => p.member.id === userId);
|
||||
|
||||
if (!user) return;
|
||||
|
||||
if (user.member.avatar && user.member.avatar !== "") {
|
||||
return (
|
||||
<div className="relative h-4 w-4">
|
||||
<Image
|
||||
src={user.member.avatar}
|
||||
alt="avatar"
|
||||
className="rounded-full"
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else
|
||||
return (
|
||||
<div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white">
|
||||
{user.member.first_name && user.member.first_name !== ""
|
||||
? user.member.first_name.charAt(0)
|
||||
: user.member.email.charAt(0)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Combobox as="div" {...props} className="relative flex-shrink-0">
|
||||
{({ open }: any) => (
|
||||
<>
|
||||
<Combobox.Label className="sr-only">{title}</Combobox.Label>
|
||||
<Combobox.Button
|
||||
className={`flex items-center gap-1 hover:bg-gray-100 border rounded-md shadow-sm px-2 py-1 cursor-pointer focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 text-xs duration-300 ${
|
||||
className={`flex cursor-pointer items-center gap-1 rounded-md border px-2 py-1 text-xs shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 ${
|
||||
buttonClassName || ""
|
||||
}`}
|
||||
>
|
||||
|
|
@ -71,21 +116,7 @@ const SearchListbox: React.FC<Props> = ({
|
|||
leaveTo="opacity-0"
|
||||
>
|
||||
<Combobox.Options
|
||||
className={`absolute z-10 mt-1 bg-white shadow-lg rounded-md py-1 ring-1 ring-black ring-opacity-5 focus:outline-none max-h-32 overflow-auto ${
|
||||
width === "xs"
|
||||
? "w-20"
|
||||
: width === "sm"
|
||||
? "w-32"
|
||||
: width === "md"
|
||||
? "w-48"
|
||||
: width === "lg"
|
||||
? "w-64"
|
||||
: width === "xl"
|
||||
? "w-80"
|
||||
: width === "2xl"
|
||||
? "w-96"
|
||||
: ""
|
||||
}} ${
|
||||
className={`absolute z-10 mt-1 max-h-32 min-w-[8rem] overflow-auto rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none ${
|
||||
optionsFontsize === "sm"
|
||||
? "text-xs"
|
||||
: optionsFontsize === "md"
|
||||
|
|
@ -100,7 +131,7 @@ const SearchListbox: React.FC<Props> = ({
|
|||
} ${optionsClassName || ""}`}
|
||||
>
|
||||
<Combobox.Input
|
||||
className="w-full bg-transparent border-b p-2 focus:outline-none text-xs"
|
||||
className="w-full border-b bg-transparent p-2 text-xs focus:outline-none"
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
placeholder="Search"
|
||||
displayValue={(assigned: any) => assigned?.name}
|
||||
|
|
@ -114,10 +145,11 @@ const SearchListbox: React.FC<Props> = ({
|
|||
className={({ active }) =>
|
||||
`${
|
||||
active ? "bg-indigo-50" : ""
|
||||
} cursor-pointer select-none truncate text-gray-900 p-2`
|
||||
} flex cursor-pointer select-none items-center gap-2 truncate p-2 text-gray-900`
|
||||
}
|
||||
value={option.value}
|
||||
>
|
||||
{assignee && userAvatar(option.value)}
|
||||
{option.element ?? option.display}
|
||||
</Combobox.Option>
|
||||
))
|
||||
|
|
|
|||
1
apps/app/ui/search-listbox/types.d.ts
vendored
1
apps/app/ui/search-listbox/types.d.ts
vendored
|
|
@ -11,4 +11,5 @@ export type Props = {
|
|||
optionsClassName?: string;
|
||||
width?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
||||
optionsFontsize?: "sm" | "md" | "lg" | "xl" | "2xl";
|
||||
assignee?: boolean;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ const Spinner: React.FC = () => {
|
|||
<div role="status">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600"
|
||||
className="mr-2 h-8 w-8 animate-spin fill-blue-600 text-gray-200 dark:text-gray-600"
|
||||
viewBox="0 0 100 101"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -32,7 +32,7 @@ const TextArea: React.FC<Props> = ({
|
|||
return (
|
||||
<>
|
||||
{label && (
|
||||
<label htmlFor={id} className="text-gray-500 mb-2">
|
||||
<label htmlFor={id} className="mb-2 text-gray-500">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
|
|
@ -54,10 +54,10 @@ const TextArea: React.FC<Props> = ({
|
|||
setTextareaValue(e.target.value);
|
||||
}}
|
||||
className={classNames(
|
||||
"w-full outline-none px-3 py-2 bg-transparent",
|
||||
mode === "primary" ? "border border-gray-300 rounded-md" : "",
|
||||
"no-scrollbar w-full bg-transparent px-3 py-2 outline-none",
|
||||
mode === "primary" ? "rounded-md border border-gray-300" : "",
|
||||
mode === "transparent"
|
||||
? "bg-transparent border-none transition-all ring-0 focus:ring-1 focus:ring-theme rounded"
|
||||
? "rounded border-none bg-transparent ring-0 transition-all focus:ring-1 focus:ring-theme"
|
||||
: "",
|
||||
error ? "border-red-500" : "",
|
||||
error && mode === "primary" ? "bg-red-100" : "",
|
||||
|
|
@ -65,7 +65,7 @@ const TextArea: React.FC<Props> = ({
|
|||
)}
|
||||
{...rest}
|
||||
></textarea>
|
||||
{error?.message && <div className="text-red-500 text-sm">{error.message}</div>}
|
||||
{error?.message && <div className="text-sm text-red-500">{error.message}</div>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue