Add embed roadmap functionalityg

pull/4868/head^2
Kamran Ahmed 1 year ago
parent aca3163ba9
commit 13d1879977
  1. 81
      src/components/CustomRoadmap/EmbedRoadmapModal.tsx
  2. 18
      src/components/ShareRoadmapButton.tsx

@ -0,0 +1,81 @@
import { useStore } from '@nanostores/react';
import { Check, Copy } from 'lucide-react';
import { Modal } from '../Modal';
import { useToast } from '../../hooks/use-toast';
import { useCopyText } from '../../hooks/use-copy-text';
import { currentRoadmap, isCurrentRoadmapPersonal } from '../../stores/roadmap';
import { cn } from '../../lib/classname.ts';
type ShareRoadmapModalProps = {
onClose: () => void;
};
export function EmbedRoadmapModal(props: ShareRoadmapModalProps) {
const { onClose } = props;
const toast = useToast();
const $currentRoadmap = useStore(currentRoadmap);
const $isCurrentRoadmapPersonal = useStore(isCurrentRoadmapPersonal);
const roadmapId = $currentRoadmap?._id!;
const { copyText, isCopied } = useCopyText();
const isDev = import.meta.env.DEV;
const baseUrl = isDev ? 'http://localhost:3000' : 'https://roadmap.sh';
const embedHtml = `<iframe src="${baseUrl}/r/embed?id=${roadmapId}" width="100%" height="500px" frameBorder="0"\n></iframe>`;
return (
<Modal onClose={onClose} wrapperClassName={'max-w-[500px]'}>
<div className="p-4 pb-0">
<h1 className="text-xl font-semibold leading-5 text-gray-900">
Embed Roadmap
</h1>
</div>
<div className="px-4 pt-3">
<p className={'mb-2 text-sm text-gray-500'}>
Copy the following HTML code and paste it into your website.
</p>
<input
type="text"
value={embedHtml}
readOnly={true}
onClick={(e) => {
e.currentTarget.select();
copyText(embedHtml);
}}
className="w-full resize-none rounded-md border bg-gray-50 p-2 text-sm"
/>
</div>
<div className="flex items-center justify-between px-4 pb-4 pt-2">
<button
className={cn(
'flex h-9 w-full items-center justify-center rounded-md border border-transparent px-4 py-2 text-sm font-medium text-white outline-none',
{
'bg-green-500 hover:bg-green-600 focus:bg-green-600': isCopied,
'bg-gray-900 hover:bg-gray-800 focus:bg-gray-800': !isCopied,
},
)}
onClick={() => {
copyText(embedHtml);
}}
>
{isCopied ? (
<>
<Check size={14} className="mr-2 stroke-[2.5]" />
Copied
</>
) : (
<>
<Copy size={14} className="mr-2 stroke-[2.5]" />
Copy Link
</>
)}
</button>
</div>
</Modal>
);
}

@ -1,6 +1,6 @@
import { import {
Check, Check,
Code, Code, Code2,
Copy, Copy,
Facebook, Facebook,
Linkedin, Linkedin,
@ -12,6 +12,7 @@ import { useOutsideClick } from '../hooks/use-outside-click.ts';
import { useCopyText } from '../hooks/use-copy-text.ts'; import { useCopyText } from '../hooks/use-copy-text.ts';
import { cn } from '../lib/classname.ts'; import { cn } from '../lib/classname.ts';
import { TwitterIcon } from './ReactIcons/TwitterIcon.tsx'; import { TwitterIcon } from './ReactIcons/TwitterIcon.tsx';
import { EmbedRoadmapModal } from './CustomRoadmap/EmbedRoadmapModal.tsx';
type ShareRoadmapButtonProps = { type ShareRoadmapButtonProps = {
roadmapId?: string; roadmapId?: string;
@ -25,6 +26,8 @@ export function ShareRoadmapButton(props: ShareRoadmapButtonProps) {
const { isCopied, copyText } = useCopyText(); const { isCopied, copyText } = useCopyText();
const [isEmbedModalOpen, setIsEmbedModalOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [isDropdownOpen, setIsDropdownOpen] = useState(false);
@ -42,6 +45,13 @@ export function ShareRoadmapButton(props: ShareRoadmapButtonProps) {
return ( return (
<div className="relative" ref={containerRef}> <div className="relative" ref={containerRef}>
{isEmbedModalOpen && (
<EmbedRoadmapModal
onClose={() => {
setIsEmbedModalOpen(false);
}}
/>
)}
<button <button
onClick={() => setIsDropdownOpen(!isDropdownOpen)} onClick={() => setIsDropdownOpen(!isDropdownOpen)}
className={cn( className={cn(
@ -85,15 +95,15 @@ export function ShareRoadmapButton(props: ShareRoadmapButtonProps) {
{allowEmbed && roadmapId && ( {allowEmbed && roadmapId && (
<button <button
onClick={() => { onClick={() => {
copyText(embedHtml);
setIsDropdownOpen(false); setIsDropdownOpen(false);
setIsEmbedModalOpen(true);
}} }}
className="flex w-full items-center gap-2 rounded-sm px-2 py-2 text-sm text-slate-100 hover:bg-slate-700" className="flex w-full items-center gap-2 rounded-sm px-2 py-2 text-sm text-slate-100 hover:bg-slate-700"
> >
<div className="flex w-[20px] items-center justify-center"> <div className="flex w-[20px] items-center justify-center">
<Code size="15px" className="text-slate-400" /> <Code2 size="15px" className="text-slate-400" />
</div> </div>
Copy Embed Code Embed Roadmap
</button> </button>
)} )}
<a <a

Loading…
Cancel
Save