mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-18 21:19:44 +00:00
feat: add inputs for og metadata
This commit is contained in:
parent
a91997683b
commit
04c0f47559
@ -29,9 +29,15 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
description: "",
|
description: "",
|
||||||
visibility: "PRIVATE",
|
visibility: "PRIVATE",
|
||||||
tags: [],
|
tags: [],
|
||||||
|
openGraphMetadata: {
|
||||||
|
title: "",
|
||||||
|
description: "",
|
||||||
|
image: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const [showDescriptionAndTag, setShowDescriptionAndTag] = useState<boolean>(false);
|
const [showDescriptionAndTag, setShowDescriptionAndTag] = useState<boolean>(false);
|
||||||
|
const [showOpenGraphMetadata, setShowOpenGraphMetadata] = useState<boolean>(false);
|
||||||
const [tag, setTag] = useState<string>("");
|
const [tag, setTag] = useState<string>("");
|
||||||
const requestState = useLoading(false);
|
const requestState = useLoading(false);
|
||||||
const isCreating = isUndefined(shortcutId);
|
const isCreating = isUndefined(shortcutId);
|
||||||
@ -47,12 +53,10 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
link: shortcut.link,
|
link: shortcut.link,
|
||||||
description: shortcut.description,
|
description: shortcut.description,
|
||||||
visibility: shortcut.visibility,
|
visibility: shortcut.visibility,
|
||||||
|
openGraphMetadata: shortcut.openGraphMetadata,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
setTag(shortcut.tags.join(" "));
|
setTag(shortcut.tags.join(" "));
|
||||||
if (shortcut.description !== "" || shortcut.tags.length > 0) {
|
|
||||||
setShowDescriptionAndTag(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [shortcutId]);
|
}, [shortcutId]);
|
||||||
@ -80,6 +84,14 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleVisibilityInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setPartialState({
|
||||||
|
shortcutCreate: Object.assign(state.shortcutCreate, {
|
||||||
|
visibility: e.target.value,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleDescriptionInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleDescriptionInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setPartialState({
|
setPartialState({
|
||||||
shortcutCreate: Object.assign(state.shortcutCreate, {
|
shortcutCreate: Object.assign(state.shortcutCreate, {
|
||||||
@ -93,10 +105,35 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
setTag(text);
|
setTag(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleVisibilityInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleOpenGraphMetadataImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setPartialState({
|
setPartialState({
|
||||||
shortcutCreate: Object.assign(state.shortcutCreate, {
|
shortcutCreate: Object.assign(state.shortcutCreate, {
|
||||||
visibility: e.target.value,
|
openGraphMetadata: {
|
||||||
|
...state.shortcutCreate.openGraphMetadata,
|
||||||
|
image: e.target.value,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenGraphMetadataTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setPartialState({
|
||||||
|
shortcutCreate: Object.assign(state.shortcutCreate, {
|
||||||
|
openGraphMetadata: {
|
||||||
|
...state.shortcutCreate.openGraphMetadata,
|
||||||
|
title: e.target.value,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenGraphMetadataDescriptionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setPartialState({
|
||||||
|
shortcutCreate: Object.assign(state.shortcutCreate, {
|
||||||
|
openGraphMetadata: {
|
||||||
|
...state.shortcutCreate.openGraphMetadata,
|
||||||
|
description: e.target.value,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -116,6 +153,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
description: state.shortcutCreate.description,
|
description: state.shortcutCreate.description,
|
||||||
visibility: state.shortcutCreate.visibility,
|
visibility: state.shortcutCreate.visibility,
|
||||||
tags: tag.split(" "),
|
tags: tag.split(" "),
|
||||||
|
openGraphMetadata: state.shortcutCreate.openGraphMetadata,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await shortcutService.createShortcut({
|
await shortcutService.createShortcut({
|
||||||
@ -144,7 +182,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
<Icon.X className="w-5 h-auto text-gray-600" />
|
<Icon.X className="w-5 h-auto text-gray-600" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="overflow-y-auto">
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
<span className="mb-2">
|
<span className="mb-2">
|
||||||
Name <span className="text-red-600">*</span>
|
Name <span className="text-red-600">*</span>
|
||||||
@ -187,33 +225,84 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Divider className="text-gray-500">Optional</Divider>
|
<Divider className="text-gray-500">Optional</Divider>
|
||||||
<div
|
<div className="w-full flex flex-col justify-start items-start border rounded-md overflow-hidden my-2">
|
||||||
className="w-full flex flex-row justify-between items-center my-3"
|
<div
|
||||||
onClick={() => setShowDescriptionAndTag(!showDescriptionAndTag)}
|
className={`w-full flex flex-row justify-between items-center px-2 py-1 cursor-pointer hover:bg-gray-100 ${
|
||||||
>
|
showDescriptionAndTag ? "bg-gray-100" : ""
|
||||||
<span className={`${showDescriptionAndTag ? "" : "text-gray-500"}`}>Description and tags</span>
|
}`}
|
||||||
<button className="w-7 h-7 p-1 rounded-md hover:bg-gray-100">
|
onClick={() => setShowDescriptionAndTag(!showDescriptionAndTag)}
|
||||||
<Icon.ChevronDown className={`w-5 h-auto text-gray-500 ${showDescriptionAndTag ? "transform rotate-180" : ""}`} />
|
>
|
||||||
</button>
|
<span className="text-sm">Description and tags</span>
|
||||||
|
<button className="w-7 h-7 p-1 rounded-md">
|
||||||
|
<Icon.ChevronDown className={`w-4 h-auto text-gray-500 ${showDescriptionAndTag ? "transform rotate-180" : ""}`} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{showDescriptionAndTag && (
|
||||||
|
<div className="w-full px-2 py-1">
|
||||||
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
|
<span className="mb-2">Description</span>
|
||||||
|
<Input
|
||||||
|
className="w-full"
|
||||||
|
type="text"
|
||||||
|
placeholder="Something to describe the url"
|
||||||
|
value={state.shortcutCreate.description}
|
||||||
|
onChange={handleDescriptionInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
|
<span className="mb-2">Tags</span>
|
||||||
|
<Input className="w-full" type="text" placeholder="Separated by spaces" value={tag} onChange={handleTagsInputChange} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{showDescriptionAndTag && (
|
<div className="w-full flex flex-col justify-start items-start border rounded-md overflow-hidden">
|
||||||
<>
|
<div
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
className={`w-full flex flex-row justify-between items-center px-2 py-1 cursor-pointer hover:bg-gray-100 ${
|
||||||
<span className="mb-2">Description</span>
|
showOpenGraphMetadata ? "bg-gray-100" : ""
|
||||||
<Input
|
}`}
|
||||||
className="w-full"
|
onClick={() => setShowOpenGraphMetadata(!showOpenGraphMetadata)}
|
||||||
type="text"
|
>
|
||||||
placeholder="Something to describe the url"
|
<span className="text-sm">Social media metadata</span>
|
||||||
value={state.shortcutCreate.description}
|
<button className="w-7 h-7 p-1 rounded-md">
|
||||||
onChange={handleDescriptionInputChange}
|
<Icon.ChevronDown className={`w-5 h-auto text-gray-500 ${showOpenGraphMetadata ? "transform rotate-180" : ""}`} />
|
||||||
/>
|
</button>
|
||||||
|
</div>
|
||||||
|
{showOpenGraphMetadata && (
|
||||||
|
<div className="w-full px-2 py-1">
|
||||||
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
|
<span className="mb-2">Image URL</span>
|
||||||
|
<Input
|
||||||
|
className="w-full"
|
||||||
|
type="text"
|
||||||
|
placeholder="The image url"
|
||||||
|
value={state.shortcutCreate.openGraphMetadata.image}
|
||||||
|
onChange={handleOpenGraphMetadataImageChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
|
<span className="mb-2">Title</span>
|
||||||
|
<Input
|
||||||
|
className="w-full"
|
||||||
|
type="text"
|
||||||
|
placeholder="Slash - A bookmarking and url shortener"
|
||||||
|
value={state.shortcutCreate.openGraphMetadata.title}
|
||||||
|
onChange={handleOpenGraphMetadataTitleChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
|
<span className="mb-2">Description</span>
|
||||||
|
<Input
|
||||||
|
className="w-full"
|
||||||
|
type="text"
|
||||||
|
placeholder="A bookmarking and url shortener, save and share your links very easily."
|
||||||
|
value={state.shortcutCreate.openGraphMetadata.description}
|
||||||
|
onChange={handleOpenGraphMetadataDescriptionChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
)}
|
||||||
<span className="mb-2">Tags</span>
|
</div>
|
||||||
<Input className="w-full" type="text" placeholder="Separated by spaces" value={tag} onChange={handleTagsInputChange} />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
|
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
|
||||||
<Button color="neutral" variant="plain" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={onClose}>
|
<Button color="neutral" variant="plain" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={onClose}>
|
||||||
|
9
web/src/types/modules/shortcut.d.ts
vendored
9
web/src/types/modules/shortcut.d.ts
vendored
@ -2,6 +2,12 @@ type ShortcutId = number;
|
|||||||
|
|
||||||
type Visibility = "PRIVATE" | "WORKSPACE" | "PUBLIC";
|
type Visibility = "PRIVATE" | "WORKSPACE" | "PUBLIC";
|
||||||
|
|
||||||
|
interface OpenGraphMetadata {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface Shortcut {
|
interface Shortcut {
|
||||||
id: ShortcutId;
|
id: ShortcutId;
|
||||||
|
|
||||||
@ -16,6 +22,7 @@ interface Shortcut {
|
|||||||
description: string;
|
description: string;
|
||||||
visibility: Visibility;
|
visibility: Visibility;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
|
openGraphMetadata: OpenGraphMetadata;
|
||||||
view: number;
|
view: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +32,7 @@ interface ShortcutCreate {
|
|||||||
description: string;
|
description: string;
|
||||||
visibility: Visibility;
|
visibility: Visibility;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
|
openGraphMetadata: OpenGraphMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ShortcutPatch {
|
interface ShortcutPatch {
|
||||||
@ -35,6 +43,7 @@ interface ShortcutPatch {
|
|||||||
description?: string;
|
description?: string;
|
||||||
visibility?: Visibility;
|
visibility?: Visibility;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
|
openGraphMetadata?: OpenGraphMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ShortcutFind {
|
interface ShortcutFind {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user