feat: add feedback button and modal
This commit is contained in:
@@ -9,8 +9,11 @@ import {
|
|||||||
import { authClient } from "@kan/auth/client";
|
import { authClient } from "@kan/auth/client";
|
||||||
|
|
||||||
import { useClickOutside } from "~/hooks/useClickOutside";
|
import { useClickOutside } from "~/hooks/useClickOutside";
|
||||||
|
import { useModal } from "~/providers/modal";
|
||||||
import { useTheme } from "~/providers/theme";
|
import { useTheme } from "~/providers/theme";
|
||||||
import { WorkspaceProvider } from "~/providers/workspace";
|
import { WorkspaceProvider } from "~/providers/workspace";
|
||||||
|
import FeedbackModal from "./FeedbackModal";
|
||||||
|
import Modal from "./modal";
|
||||||
import SideNavigation from "./SideNavigation";
|
import SideNavigation from "./SideNavigation";
|
||||||
|
|
||||||
interface DashboardProps {
|
interface DashboardProps {
|
||||||
@@ -39,6 +42,7 @@ export default function Dashboard({
|
|||||||
hasRightPanel = false,
|
hasRightPanel = false,
|
||||||
}: DashboardProps) {
|
}: DashboardProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const { modalContentType } = useModal();
|
||||||
|
|
||||||
const { data: session, isPending: sessionLoading } = authClient.useSession();
|
const { data: session, isPending: sessionLoading } = authClient.useSession();
|
||||||
|
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
import Link from "next/link";
|
|
||||||
import { Menu, Transition } from "@headlessui/react";
|
|
||||||
import { t } from "@lingui/core/macro";
|
|
||||||
import { Fragment, useRef, useState } from "react";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
|
|
||||||
import chatIconDark from "~/assets/chat-dark.json";
|
|
||||||
import chatIconLight from "~/assets/chat-light.json";
|
|
||||||
import Button from "~/components/Button";
|
|
||||||
import Input from "~/components/Input";
|
|
||||||
import LottieIcon from "~/components/LottieIcon";
|
|
||||||
import { usePopup } from "~/providers/popup";
|
|
||||||
import { useTheme } from "~/providers/theme";
|
|
||||||
import { api } from "~/utils/api";
|
|
||||||
|
|
||||||
interface NewFeedbackFormInput {
|
|
||||||
feedback: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FeedbackButton: React.FC = () => {
|
|
||||||
const outsideRef = useRef<HTMLDivElement>(null);
|
|
||||||
const { activeTheme } = useTheme();
|
|
||||||
const { showPopup } = usePopup();
|
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
|
||||||
const [index, setIndex] = useState(0);
|
|
||||||
|
|
||||||
const { handleSubmit, setValue, watch, reset } =
|
|
||||||
useForm<NewFeedbackFormInput>({
|
|
||||||
defaultValues: {
|
|
||||||
feedback: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const createFeedback = api.feedback.create.useMutation({
|
|
||||||
onSuccess: async () => {
|
|
||||||
reset();
|
|
||||||
showPopup({
|
|
||||||
header: t`Feedback sent`,
|
|
||||||
message: t`Thank you for your feedback!`,
|
|
||||||
icon: "success",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onError: async () => {
|
|
||||||
showPopup({
|
|
||||||
header: t`Unable to send feedback`,
|
|
||||||
message: t`Please try again later, or contact customer support.`,
|
|
||||||
icon: "error",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleMouseEnter = () => {
|
|
||||||
setIsHovered(true);
|
|
||||||
setIndex((index) => index + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = (values: NewFeedbackFormInput) => {
|
|
||||||
createFeedback.mutate({
|
|
||||||
feedback: values.feedback,
|
|
||||||
url: window.location.href,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div ref={outsideRef} />
|
|
||||||
<Menu as="div" className="relative inline-block text-left">
|
|
||||||
<div>
|
|
||||||
<Menu.Button
|
|
||||||
onMouseEnter={handleMouseEnter}
|
|
||||||
className="flex items-center rounded-md border-[1px] border-light-600 bg-light-50 px-2.5 py-1.5 text-sm font-normal text-neutral-900 shadow-sm dark:border-dark-400 dark:bg-dark-50 dark:text-dark-1000"
|
|
||||||
>
|
|
||||||
<LottieIcon
|
|
||||||
index={index}
|
|
||||||
json={activeTheme === "dark" ? chatIconDark : chatIconLight}
|
|
||||||
isPlaying={isHovered}
|
|
||||||
/>
|
|
||||||
<span className="ml-1">{t`Feedback`}</span>
|
|
||||||
</Menu.Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Transition
|
|
||||||
as={Fragment}
|
|
||||||
enter="transition ease-out duration-100"
|
|
||||||
enterFrom="transform opacity-0 scale-95"
|
|
||||||
enterTo="transform opacity-100 scale-100"
|
|
||||||
leave="transition ease-in duration-75"
|
|
||||||
leaveFrom="transform opacity-100 scale-100"
|
|
||||||
leaveTo="transform opacity-0 scale-95"
|
|
||||||
>
|
|
||||||
<Menu.Items
|
|
||||||
as="div"
|
|
||||||
static
|
|
||||||
className="absolute right-0 z-30 mt-2 w-[350px] origin-top-right rounded-md border border-light-200 bg-light-50 p-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-400 dark:bg-dark-300"
|
|
||||||
>
|
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="p-1">
|
|
||||||
<Input
|
|
||||||
placeholder={t`Ideas to improve this page...`}
|
|
||||||
onChange={(e) => {
|
|
||||||
setValue("feedback", e.target.value);
|
|
||||||
}}
|
|
||||||
value={watch("feedback")}
|
|
||||||
contentEditable
|
|
||||||
className="max-h-[300px] min-h-[100px]"
|
|
||||||
onKeyDown={async (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
if (e.key === "Enter" && e.shiftKey) {
|
|
||||||
e.preventDefault();
|
|
||||||
await handleSubmit(onSubmit)();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-row items-center justify-between pt-2">
|
|
||||||
<div>
|
|
||||||
<p className="ml-2 text-xs text-neutral-900 dark:text-dark-1000">
|
|
||||||
{t`Need help?`}{" "}
|
|
||||||
<Link
|
|
||||||
href="mailto:support@kan.bn"
|
|
||||||
className="text-blue-600 underline dark:text-blue-300"
|
|
||||||
>
|
|
||||||
{t`Contact us`}
|
|
||||||
</Link>
|
|
||||||
{t`, or see our`}{" "}
|
|
||||||
<Link
|
|
||||||
href="https://docs.kan.bn"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="text-blue-600 underline dark:text-blue-300"
|
|
||||||
>
|
|
||||||
{t`docs`}
|
|
||||||
</Link>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="justify-end">
|
|
||||||
<Button size="sm" isLoading={createFeedback.isPending}>
|
|
||||||
{t`Send`}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Menu.Items>
|
|
||||||
</Transition>
|
|
||||||
</Menu>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FeedbackButton;
|
|
||||||
122
apps/web/src/components/FeedbackModal.tsx
Normal file
122
apps/web/src/components/FeedbackModal.tsx
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { t } from "@lingui/core/macro";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { HiXMark } from "react-icons/hi2";
|
||||||
|
|
||||||
|
import Button from "~/components/Button";
|
||||||
|
import Input from "~/components/Input";
|
||||||
|
import { useModal } from "~/providers/modal";
|
||||||
|
import { usePopup } from "~/providers/popup";
|
||||||
|
import { api } from "~/utils/api";
|
||||||
|
|
||||||
|
interface NewFeedbackFormInput {
|
||||||
|
feedback: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FeedbackModal() {
|
||||||
|
const { closeModal } = useModal();
|
||||||
|
const { showPopup } = usePopup();
|
||||||
|
|
||||||
|
const { handleSubmit, setValue, watch, reset } =
|
||||||
|
useForm<NewFeedbackFormInput>({
|
||||||
|
defaultValues: {
|
||||||
|
feedback: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const createFeedback = api.feedback.create.useMutation({
|
||||||
|
onSuccess: async () => {
|
||||||
|
reset();
|
||||||
|
closeModal();
|
||||||
|
showPopup({
|
||||||
|
header: t`Feedback sent`,
|
||||||
|
message: t`Thank you for your feedback!`,
|
||||||
|
icon: "success",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: async () => {
|
||||||
|
showPopup({
|
||||||
|
header: t`Unable to send feedback`,
|
||||||
|
message: t`Please try again later, or contact customer support.`,
|
||||||
|
icon: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = (values: NewFeedbackFormInput) => {
|
||||||
|
createFeedback.mutate({
|
||||||
|
feedback: values.feedback,
|
||||||
|
url: window.location.href,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div className="px-5 pt-5">
|
||||||
|
<div className="flex w-full items-center justify-between pb-4">
|
||||||
|
<h2 className="text-sm font-bold text-neutral-900 dark:text-dark-1000">
|
||||||
|
{t`Feedback`}
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="rounded p-1 hover:bg-light-200 focus:outline-none dark:hover:bg-dark-300"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
closeModal();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HiXMark size={18} className="text-light-900 dark:text-dark-900" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
id="feedback"
|
||||||
|
placeholder={t`Ideas to improve this page...`}
|
||||||
|
onChange={(e) => setValue("feedback", e.target.value)}
|
||||||
|
contentEditable
|
||||||
|
value={watch("feedback")}
|
||||||
|
className="min-h-[120px]"
|
||||||
|
onKeyDown={async (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (e.key === "Enter" && e.shiftKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
await handleSubmit(onSubmit)();
|
||||||
|
}
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mt-6 flex items-center justify-between border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||||
|
<div className="text-xs text-neutral-600 dark:text-dark-800">
|
||||||
|
<p>
|
||||||
|
{t`Need help?`}{" "}
|
||||||
|
<Link
|
||||||
|
href="mailto:support@kan.bn"
|
||||||
|
className="text-blue-600 underline dark:text-blue-300"
|
||||||
|
>
|
||||||
|
{t`Contact us`}
|
||||||
|
</Link>
|
||||||
|
{t`, or see our`}{" "}
|
||||||
|
<Link
|
||||||
|
href="https://docs.kan.bn"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="text-blue-600 underline dark:text-blue-300"
|
||||||
|
>
|
||||||
|
{t`docs`}
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button type="submit" isLoading={createFeedback.isPending}>
|
||||||
|
{t`Send feedback`}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ import ReactiveButton from "~/components/ReactiveButton";
|
|||||||
import UserMenu from "~/components/UserMenu";
|
import UserMenu from "~/components/UserMenu";
|
||||||
import WorkspaceMenu from "~/components/WorkspaceMenu";
|
import WorkspaceMenu from "~/components/WorkspaceMenu";
|
||||||
import { useTheme } from "~/providers/theme";
|
import { useTheme } from "~/providers/theme";
|
||||||
import FeedbackButton from "./FeedbackButton";
|
|
||||||
|
|
||||||
interface SideNavigationProps {
|
interface SideNavigationProps {
|
||||||
user: UserType;
|
user: UserType;
|
||||||
@@ -140,11 +139,6 @@ export default function SideNavigation({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{/* Feedback button above user menu */}
|
|
||||||
{/* <div className="flex justify-start">
|
|
||||||
<FeedbackButton />
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<UserMenu
|
<UserMenu
|
||||||
email={user.email ?? ""}
|
email={user.email ?? ""}
|
||||||
imageUrl={user.image ?? undefined}
|
imageUrl={user.image ?? undefined}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Menu, Transition } from "@headlessui/react";
|
import { Menu, Transition } from "@headlessui/react";
|
||||||
import { t } from "@lingui/core/macro";
|
import { t } from "@lingui/core/macro";
|
||||||
@@ -6,6 +7,7 @@ import { Fragment } from "react";
|
|||||||
|
|
||||||
import { authClient } from "@kan/auth/client";
|
import { authClient } from "@kan/auth/client";
|
||||||
|
|
||||||
|
import { useModal } from "~/providers/modal";
|
||||||
import { useTheme } from "~/providers/theme";
|
import { useTheme } from "~/providers/theme";
|
||||||
import { getAvatarUrl } from "~/utils/helpers";
|
import { getAvatarUrl } from "~/utils/helpers";
|
||||||
|
|
||||||
@@ -28,10 +30,10 @@ export default function UserMenu({
|
|||||||
}: UserMenuProps) {
|
}: UserMenuProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { themePreference, switchTheme } = useTheme();
|
const { themePreference, switchTheme } = useTheme();
|
||||||
|
const { openModal } = useModal();
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
await authClient.signOut();
|
await authClient.signOut();
|
||||||
|
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,6 +143,36 @@ export default function UserMenu({
|
|||||||
</button>
|
</button>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="light-border-600 border-t-[1px] p-1 dark:border-dark-600">
|
||||||
|
<Menu.Item>
|
||||||
|
<Link
|
||||||
|
href="mailto:support@kan.bn"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="flex w-full items-center rounded-[5px] px-3 py-2 text-left text-xs hover:bg-light-200 dark:hover:bg-dark-400"
|
||||||
|
>
|
||||||
|
{t`Support`}
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
<Link
|
||||||
|
href="https://docs.kan.bn"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="flex w-full items-center rounded-[5px] px-3 py-2 text-left text-xs hover:bg-light-200 dark:hover:bg-dark-400"
|
||||||
|
>
|
||||||
|
{t`Documentation`}
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
<button
|
||||||
|
onClick={() => openModal("NEW_FEEDBACK")}
|
||||||
|
className="flex w-full items-center rounded-[5px] px-3 py-2 text-left text-xs hover:bg-light-200 dark:hover:bg-dark-400"
|
||||||
|
>
|
||||||
|
{t`Feedback`}
|
||||||
|
</button>
|
||||||
|
</Menu.Item>
|
||||||
|
</div>
|
||||||
<div className="light-border-600 border-t-[1px] p-1 dark:border-dark-600">
|
<div className="light-border-600 border-t-[1px] p-1 dark:border-dark-600">
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import type { UpdateBoardInput } from "@kan/api/types";
|
|||||||
|
|
||||||
import Button from "~/components/Button";
|
import Button from "~/components/Button";
|
||||||
import { DeleteLabelConfirmation } from "~/components/DeleteLabelConfirmation";
|
import { DeleteLabelConfirmation } from "~/components/DeleteLabelConfirmation";
|
||||||
|
import FeedbackModal from "~/components/FeedbackModal";
|
||||||
import { LabelForm } from "~/components/LabelForm";
|
import { LabelForm } from "~/components/LabelForm";
|
||||||
import Modal from "~/components/modal";
|
import Modal from "~/components/modal";
|
||||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||||
@@ -421,7 +422,15 @@ export default function BoardPage() {
|
|||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<Modal modalSize={modalContentType === "NEW_CARD" ? "md" : "sm"}>
|
<Modal
|
||||||
|
modalSize={
|
||||||
|
modalContentType === "NEW_CARD" ||
|
||||||
|
modalContentType === "NEW_FEEDBACK"
|
||||||
|
? "md"
|
||||||
|
: "sm"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{modalContentType === "NEW_FEEDBACK" && <FeedbackModal />}
|
||||||
{modalContentType === "DELETE_BOARD" && (
|
{modalContentType === "DELETE_BOARD" && (
|
||||||
<DeleteBoardConfirmation boardPublicId={boardId ?? ""} />
|
<DeleteBoardConfirmation boardPublicId={boardId ?? ""} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { t } from "@lingui/core/macro";
|
|||||||
import { HiArrowDownTray, HiOutlinePlusSmall } from "react-icons/hi2";
|
import { HiArrowDownTray, HiOutlinePlusSmall } from "react-icons/hi2";
|
||||||
|
|
||||||
import Button from "~/components/Button";
|
import Button from "~/components/Button";
|
||||||
|
import FeedbackModal from "~/components/FeedbackModal";
|
||||||
import Modal from "~/components/modal";
|
import Modal from "~/components/modal";
|
||||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||||
import { PageHead } from "~/components/PageHead";
|
import { PageHead } from "~/components/PageHead";
|
||||||
@@ -51,7 +52,8 @@ export default function BoardsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal>
|
<Modal modalSize={modalContentType === "NEW_FEEDBACK" ? "md" : "sm"}>
|
||||||
|
{modalContentType === "NEW_FEEDBACK" && <FeedbackModal />}
|
||||||
{modalContentType === "NEW_BOARD" && <NewBoardForm />}
|
{modalContentType === "NEW_BOARD" && <NewBoardForm />}
|
||||||
{modalContentType === "IMPORT_BOARDS" && <ImportBoardsForm />}
|
{modalContentType === "IMPORT_BOARDS" && <ImportBoardsForm />}
|
||||||
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
|
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import { IoChevronForwardSharp } from "react-icons/io5";
|
|||||||
|
|
||||||
import Avatar from "~/components/Avatar";
|
import Avatar from "~/components/Avatar";
|
||||||
import Editor from "~/components/Editor";
|
import Editor from "~/components/Editor";
|
||||||
|
import FeedbackModal from "~/components/FeedbackModal";
|
||||||
import { LabelForm } from "~/components/LabelForm";
|
import { LabelForm } from "~/components/LabelForm";
|
||||||
import LabelIcon from "~/components/LabelIcon";
|
import LabelIcon from "~/components/LabelIcon";
|
||||||
import Modal from "~/components/modal";
|
import Modal from "~/components/modal";
|
||||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||||
import { PageHead } from "~/components/PageHead";
|
import { PageHead } from "~/components/PageHead";
|
||||||
import PatternedBackground from "~/components/PatternedBackground";
|
|
||||||
import { useModal } from "~/providers/modal";
|
import { useModal } from "~/providers/modal";
|
||||||
import { usePopup } from "~/providers/popup";
|
import { usePopup } from "~/providers/popup";
|
||||||
import { useWorkspace } from "~/providers/workspace";
|
import { useWorkspace } from "~/providers/workspace";
|
||||||
@@ -272,7 +272,8 @@ export default function CardPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal>
|
<Modal modalSize={modalContentType === "NEW_FEEDBACK" ? "md" : "sm"}>
|
||||||
|
{modalContentType === "NEW_FEEDBACK" && <FeedbackModal />}
|
||||||
{modalContentType === "NEW_LABEL" && (
|
{modalContentType === "NEW_LABEL" && (
|
||||||
<LabelForm boardPublicId={boardId ?? ""} refetch={refetchCard} />
|
<LabelForm boardPublicId={boardId ?? ""} refetch={refetchCard} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { authClient } from "@kan/auth/client";
|
|||||||
import Avatar from "~/components/Avatar";
|
import Avatar from "~/components/Avatar";
|
||||||
import Button from "~/components/Button";
|
import Button from "~/components/Button";
|
||||||
import Dropdown from "~/components/Dropdown";
|
import Dropdown from "~/components/Dropdown";
|
||||||
|
import FeedbackModal from "~/components/FeedbackModal";
|
||||||
import Modal from "~/components/modal";
|
import Modal from "~/components/modal";
|
||||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||||
import { PageHead } from "~/components/PageHead";
|
import { PageHead } from "~/components/PageHead";
|
||||||
@@ -221,7 +222,8 @@ export default function MembersPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal>
|
<Modal modalSize={modalContentType === "NEW_FEEDBACK" ? "md" : "sm"}>
|
||||||
|
{modalContentType === "NEW_FEEDBACK" && <FeedbackModal />}
|
||||||
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
|
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
|
||||||
{modalContentType === "INVITE_MEMBER" && <InviteMemberForm />}
|
{modalContentType === "INVITE_MEMBER" && <InviteMemberForm />}
|
||||||
{modalContentType === "REMOVE_MEMBER" && <DeleteMemberConfirmation />}
|
{modalContentType === "REMOVE_MEMBER" && <DeleteMemberConfirmation />}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useEffect, useRef } from "react";
|
|||||||
import { HiMiniArrowTopRightOnSquare } from "react-icons/hi2";
|
import { HiMiniArrowTopRightOnSquare } from "react-icons/hi2";
|
||||||
|
|
||||||
import Button from "~/components/Button";
|
import Button from "~/components/Button";
|
||||||
|
import FeedbackModal from "~/components/FeedbackModal";
|
||||||
import { LanguageSelector } from "~/components/LanguageSelector";
|
import { LanguageSelector } from "~/components/LanguageSelector";
|
||||||
import Modal from "~/components/modal";
|
import Modal from "~/components/modal";
|
||||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||||
@@ -300,7 +301,8 @@ export default function SettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal>
|
<Modal modalSize={modalContentType === "NEW_FEEDBACK" ? "md" : "sm"}>
|
||||||
|
{modalContentType === "NEW_FEEDBACK" && <FeedbackModal />}
|
||||||
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
|
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
|
||||||
{modalContentType === "DELETE_WORKSPACE" && (
|
{modalContentType === "DELETE_WORKSPACE" && (
|
||||||
<DeleteWorkspaceConfirmation />
|
<DeleteWorkspaceConfirmation />
|
||||||
|
|||||||
Reference in New Issue
Block a user