diff --git a/web/src/components/CreateDocumentModal/CreateDocModal.tsx b/web/src/components/CreateDocumentModal/CreateDocModal.tsx index b9cec5d..d938d1c 100644 --- a/web/src/components/CreateDocumentModal/CreateDocModal.tsx +++ b/web/src/components/CreateDocumentModal/CreateDocModal.tsx @@ -7,7 +7,6 @@ import data from "@emoji-mart/data"; import { EmojiMartData } from "@emoji-mart/data"; import Picker from "@emoji-mart/react"; import EmojiClickData from "@emoji-mart/react"; -import { Field, Label, Switch } from "@headlessui/react"; import { Icon } from "@iconify/react"; import { AnimatePresence, motion } from "framer-motion"; import React, { useContext, useEffect, useRef, useState } from "react"; @@ -23,10 +22,15 @@ import { } from "../../api/Requests"; import { ModalContext } from "../../context/ModalContext"; import { ThemeContext, ThemeContextType } from "../../context/ThemeContext"; +import AddButton from "../../lib/components/AddButton"; +import DeleteButton from "../../lib/components/DeleteButton"; +import ToggleSwitch from "../../lib/components/ToggleSwitch"; import { Documentation, Features, FooterLabelLinks, + FormData, + FormFieldData, LanderDetails, MoreLabelLinks, } from "../../types/doc"; @@ -42,18 +46,6 @@ import { toastMessage } from "../../utils/Toast"; import { customCSSInitial, SocialLinkIcon } from "../../utils/Utils"; import Breadcrumb from "../Breadcrumb/Breadcrumb"; -interface FormFieldData { - label: string; - placeholder: string; - value?: string; - onChange: (e: React.ChangeEvent) => void; - name: string; - type?: string; - required?: boolean; - ref?: React.Ref; -} - - const FormField: React.FC = ({ label, placeholder, @@ -109,156 +101,43 @@ type HandleArrayFieldChange = ( saveField: "moreFooter" | "socialPlatform", ) => void; -interface OnClick { - onClick: () => Promise; -} - -interface LabelAndCommunity { - index: number; - labelId: string; - linkId: string; - data: { - label: string; - link: string; - }; - onChange: HandleArrayFieldChange; - state: { - label: string; - link: string; - }[]; -} - -const LabelAndCommunityComponent = ({ - index, - labelId, - linkId, - data, - onChange, - state, -}: LabelAndCommunity) => { - const { t } = useTranslation(); - return ( - -
- - {t("label")} - - - onChange(index, "label", e.target.value, state, "moreFooter") - } - placeholder={t("label_placeholder")} - className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" - /> -
-
- - {t("link")} - - - onChange(index, "link", e.target.value, state, "moreFooter") - } - placeholder={t("more_footer_link_placeholder")} - className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" - /> -
-
- ); -}; - -const AddButton: React.FC = ({ onClick }) => { - const { t } = useTranslation(); - return ( - - ); -}; - -const DeleteButton: React.FC = ({ onClick }) => { - const { t } = useTranslation(); - return ( - - ); -}; - -interface FormData { - name: string; - description: string; - version: string; - baseURL: string; - url: string; - organizationName: string; - projectName: string; - customCSS: string; - favicon: string; - navImageDark: string; - navImage: string; - copyrightText: string; - metaImage: string; - gitUser: string | undefined; - gitRepo: string | undefined; - gitEmail: string | undefined; - gitPassword: string | undefined; - gitBranch: string | undefined; -} - type LanderDetailsKeys = keyof LanderDetails; export default function CreateDocModal() { + // Contexts const { t } = useTranslation(); const navigate = useNavigate(); const [searchParam] = useSearchParams(); - const docIdString = searchParam.get("id"); - const docId: number | null = docIdString ? parseInt(docIdString) : null; - const mode = searchParam.get("mode"); const { openModal, closeModal, setLoadingMessage } = useContext(ModalContext); const themeContext = useContext(ThemeContext); const { darkMode } = themeContext as ThemeContextType; + + // Search Parameters + const docIdString = searchParam.get("id"); + const docId: number | null = docIdString ? parseInt(docIdString) : null; + const mode = searchParam.get("mode"); + + // State Variables const [isAuthenticationToggleOn, SetIsAuthenticationToggleOn] = useState< boolean | undefined >(false); - const [isToggleOn, SetIsToggleOn] = useState(false); - const [gitDeployOn, SetGitDeployOn] = useState(false); + const [isToggleOn, SetIsToggleOn] = useState(false); + const [gitDeployOn, SetGitDeployOn] = useState(false); const [activeFieldIndex, setActiveFieldIndex] = useState(null); const [showEmojiPicker, setShowEmojiPicker] = useState(false); - const inputRefs = useRef<(HTMLInputElement | null)[]>([]); - const titleRef = useRef(null); const [openDropdownIndex, setOpenDropdownIndex] = useState( null, ); + const [isIconSelectOpen, setIsIconSelectOpen] = useState(false); + + // Refs + const inputRefs = useRef<(HTMLInputElement | null)[]>([]); + const titleRef = useRef(null); + const pickerRef = useRef(null); const socialMediaRef = useRef(null); - const [isIconSelectOpen, setIsIconSelectOpen] = useState(false); + // Form Data const [formData, setFormData] = useState({ name: "", description: "", @@ -303,6 +182,7 @@ export default function CreateDocModal() { useOutsideAlerter(pickerRef, () => setShowEmojiPicker(false)); useOutsideAlerter(socialMediaRef, () => setIsIconSelectOpen(false)); + useEffect(() => { if (isToggleOn || gitDeployOn) { window.scrollTo({ @@ -377,6 +257,7 @@ export default function CreateDocModal() { } } else { console.error("docId is null"); + return; } }; fetchDoc(); @@ -594,7 +475,7 @@ export default function CreateDocModal() { if (saveField === "moreFooter") { setMoreField(updatedFields as MoreLabelLinks[]); - } else { + } else if (saveField === "socialPlatform") { setSocialPlatformField(updatedFields as FooterLabelLinks[]); } }; @@ -662,20 +543,11 @@ export default function CreateDocModal() {
- +
(
- + +
+ + {t("label")} + + + handleArrayFieldChange( + index, + "label", + e.target.value, + moreField, + "moreFooter", + ) + } + placeholder={t("label_placeholder")} + className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" + /> +
+
+ + {t("link")} + + + handleArrayFieldChange( + index, + "link", + e.target.value, + moreField, + "moreFooter", + ) + } + placeholder={t("more_footer_link_placeholder")} + className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" + /> +
+
))}
@@ -964,20 +880,11 @@ export default function CreateDocModal() {
- + {isToggleOn && (
@@ -1147,19 +1054,12 @@ export default function CreateDocModal() { )}
-
- - - - - - +
+ {gitDeployOn && (
diff --git a/web/src/lib/components/AddButton.tsx b/web/src/lib/components/AddButton.tsx new file mode 100644 index 0000000..5fa5e1a --- /dev/null +++ b/web/src/lib/components/AddButton.tsx @@ -0,0 +1,21 @@ +import { Icon } from "@iconify/react/dist/iconify.js"; +import { useTranslation } from "react-i18next"; + +/* eslint-disable react/prop-types */ +interface OnClick { + onClick: () => Promise; +} +const AddButton: React.FC = ({ onClick }) => { + const { t } = useTranslation(); + return ( + + ); +}; + +export default AddButton; diff --git a/web/src/lib/components/DeleteButton.tsx b/web/src/lib/components/DeleteButton.tsx new file mode 100644 index 0000000..1c3ea84 --- /dev/null +++ b/web/src/lib/components/DeleteButton.tsx @@ -0,0 +1,25 @@ +import { Icon } from "@iconify/react/dist/iconify.js"; +import { useTranslation } from "react-i18next"; + +/* eslint-disable react/prop-types */ +interface OnClick { + onClick: () => Promise; +} + +const DeleteButton: React.FC = ({ onClick }) => { + const { t } = useTranslation(); + return ( + + ); +}; + +export default DeleteButton; diff --git a/web/src/lib/components/ToggleSwitch.tsx b/web/src/lib/components/ToggleSwitch.tsx new file mode 100644 index 0000000..e4e86c2 --- /dev/null +++ b/web/src/lib/components/ToggleSwitch.tsx @@ -0,0 +1,32 @@ +import { Field, Label, Switch } from "@headlessui/react"; +import { Dispatch, SetStateAction } from "react"; +import { useTranslation } from "react-i18next"; + +interface ToggleSwitchProps { + name: string; + checked: boolean | undefined; + setChange: Dispatch>; +} + +export default function ToggleSwitch({ + name, + checked, + setChange, +}: ToggleSwitchProps): JSX.Element { + const { t } = useTranslation(); + + return ( + + + + + + + ); +} diff --git a/web/src/types/doc.ts b/web/src/types/doc.ts index f0b5adf..8b6dcec 100644 --- a/web/src/types/doc.ts +++ b/web/src/types/doc.ts @@ -121,6 +121,38 @@ export interface FormField { ref: React.RefObject; } +export interface FormFieldData { + label: string; + placeholder: string; + value?: string; + onChange: (e: React.ChangeEvent) => void; + name: string; + type?: string; + required?: boolean; + ref?: React.Ref; +} + +export interface FormData { + name: string; + description: string; + version: string; + baseURL: string; + url: string; + organizationName: string; + projectName: string; + customCSS: string; + favicon: string; + navImageDark: string; + navImage: string; + copyrightText: string; + metaImage: string; + gitUser: string | undefined; + gitRepo: string | undefined; + gitEmail: string | undefined; + gitPassword: string | undefined; + gitBranch: string | undefined; +} + export function isPage(item: PageOrGroup): item is Page { return (item as Page).title !== undefined; }