import { Button, Group, InputWrapper, Slider, Stack, Switch, TextInput } from "@mantine/core"; import { useDebouncedValue } from "@mantine/hooks"; import { IconAlertTriangle, IconCircleCheck } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; import { revalidatePathActionAsync } from "@homarr/common/client"; import { useZodForm } from "@homarr/form"; import { createModal } from "@homarr/modals"; import { showErrorNotification, showSuccessNotification } from "@homarr/notifications"; import { useI18n } from "@homarr/translation/client"; import { validation } from "@homarr/validation"; export const AddBoardModal = createModal(({ actions }) => { const t = useI18n(); const form = useZodForm(validation.board.create, { mode: "controlled", initialValues: { name: "", columnCount: 10, isPublic: false, }, }); const { mutate, isPending } = clientApi.board.createBoard.useMutation({ onSettled: async () => { await revalidatePathActionAsync("/manage/boards"); }, }); const boardNameStatus = useBoardNameStatus(form.values.name); const columnCountChecks = validation.board.create.shape.columnCount._def.checks; const minColumnCount = columnCountChecks.find((check) => check.kind === "min")?.value; const maxColumnCount = columnCountChecks.find((check) => check.kind === "max")?.value; return (
); }).withOptions({ defaultTitle: (t) => t("management.page.board.action.new.label"), }); export const useBoardNameStatus = (name: string) => { const t = useI18n(); const [debouncedName] = useDebouncedValue(name, 250); const { data: boardExists, isLoading } = clientApi.board.exists.useQuery(debouncedName, { enabled: validation.board.create.shape.name.safeParse(debouncedName).success, }); return { canSubmit: !boardExists && !isLoading, description: debouncedName.trim() === "" ? undefined : isLoading ? { label: "Checking availability...", } : boardExists === undefined ? undefined : boardExists ? { icon: IconAlertTriangle, label: t("common.zod.errors.custom.boardAlreadyExists"), // The board ${debouncedName} already exists color: "red", } : { icon: IconCircleCheck, label: `${debouncedName} is available`, color: "green", }, }; };