diff --git a/frontend/web/src/components/CreateShortcutDrawer.tsx b/frontend/web/src/components/CreateShortcutDrawer.tsx index da93ebc..8e481bb 100644 --- a/frontend/web/src/components/CreateShortcutDrawer.tsx +++ b/frontend/web/src/components/CreateShortcutDrawer.tsx @@ -20,6 +20,7 @@ import { useAppSelector } from "@/stores"; import useLoading from "../hooks/useLoading"; import { shortcutService } from "../services"; import Icon from "./Icon"; +import ShortcutNameInput from "./ShortcutNameInput"; interface Props { shortcutId?: ShortcutId; @@ -57,8 +58,9 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { const [showOpenGraphMetadata, setShowOpenGraphMetadata] = useState(false); const [tag, setTag] = useState(""); const tagSuggestions = uniq(shortcutList.map((shortcut) => shortcut.tags).flat()); - const requestState = useLoading(false); const isCreating = isUndefined(shortcutId); + const loadingState = useLoading(!isCreating); + const requestState = useLoading(false); useEffect(() => { if (shortcutId) { @@ -76,10 +78,15 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { }), }); setTag(shortcut.tags.join(" ")); + loadingState.setFinish(); } } }, [shortcutId]); + if (loadingState.isLoading) { + return; + } + const setPartialState = (partialState: Partial) => { setState({ ...state, @@ -87,10 +94,10 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { }); }; - const handleNameInputChange = (e: React.ChangeEvent) => { + const handleNameChange = (name: string) => { setPartialState({ shortcutCreate: Object.assign(state.shortcutCreate, { - name: e.target.value.replace(/\s+/g, "-"), + name: name.replace(/\s+/g, "-"), }), }); }; @@ -215,20 +222,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => {
-
- - Name * - -
- -
-
+
Link * diff --git a/frontend/web/src/components/ShortcutNameInput.tsx b/frontend/web/src/components/ShortcutNameInput.tsx new file mode 100644 index 0000000..9b88e4f --- /dev/null +++ b/frontend/web/src/components/ShortcutNameInput.tsx @@ -0,0 +1,65 @@ +import { IconButton, Input } from "@mui/joy"; +import classNames from "classnames"; +import { useEffect, useState } from "react"; +import { generateRandomString } from "@/helpers/utils"; +import Icon from "./Icon"; + +interface Props { + name: string; + onChange: (name: string) => void; +} + +const ShortcutNameInput = (props: Props) => { + const { name, onChange } = props; + const [modified, setModified] = useState(false); + const [editingName, setEditingName] = useState(name || generateRandomString().toLowerCase()); + + useEffect(() => { + onChange(editingName); + }, [editingName]); + + const handleNameInputChange = (e: React.ChangeEvent) => { + if (!modified) { + return; + } + + setEditingName(e.target.value); + }; + + return ( +
+
+ Name + {modified ? ( + * + ) : ( + <> + : + {editingName} +
+ setModified(true)}> + + + setEditingName(generateRandomString().toLowerCase())}> + + +
+ + )} +
+ {modified && ( +
+ +
+ )} +
+ ); +}; + +export default ShortcutNameInput; diff --git a/frontend/web/src/helpers/utils.ts b/frontend/web/src/helpers/utils.ts index d82e4b0..dd7f03a 100644 --- a/frontend/web/src/helpers/utils.ts +++ b/frontend/web/src/helpers/utils.ts @@ -22,3 +22,13 @@ export const getFaviconWithGoogleS2 = (url: string) => { return undefined; } }; + +export const generateRandomString = () => { + const characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + let randomString = ""; + for (let i = 0; i < 6; i++) { + const randomIndex = Math.floor(Math.random() * characters.length); + randomString += characters.charAt(randomIndex); + } + return randomString; +};