Allow embedding of roadmaps

pull/3460/head
Kamran Ahmed 1 year ago
parent 9d05c64f50
commit b35a169315
  1. 26
      src/components/CustomRoadmap/CustomRoadmap.tsx
  2. 15
      src/components/CustomRoadmap/FlowRoadmapRenderer.tsx
  3. 11
      src/components/TopicDetail/TopicDetail.tsx
  4. 29
      src/pages/r/embed.astro

@ -53,14 +53,20 @@ export type GetRoadmapResponse = RoadmapDocument & {
export function hideRoadmapLoader() {
const loaderEl = document.querySelector(
'[data-roadmap-loader]'
'[data-roadmap-loader]',
) as HTMLElement;
if (loaderEl) {
loaderEl.remove();
}
}
export function CustomRoadmap() {
type CustomRoadmapProps = {
isEmbed?: boolean;
};
export function CustomRoadmap(props: CustomRoadmapProps) {
const { isEmbed = false } = props;
const { id, secret } = getUrlParams() as { id: string; secret: string };
const [isLoading, setIsLoading] = useState(true);
@ -71,14 +77,15 @@ export function CustomRoadmap() {
setIsLoading(true);
const roadmapUrl = new URL(
`${import.meta.env.PUBLIC_API_URL}/v1-get-roadmap/${id}`
`${import.meta.env.PUBLIC_API_URL}/v1-get-roadmap/${id}`,
);
if (secret) {
roadmapUrl.searchParams.set('secret', secret);
}
const { response, error } = await httpGet<GetRoadmapResponse>(
roadmapUrl.toString()
roadmapUrl.toString(),
);
if (error || !response) {
@ -95,7 +102,10 @@ export function CustomRoadmap() {
}
async function trackVisit() {
if (!isLoggedIn()) return;
if (!isLoggedIn() || isEmbed) {
return;
}
await httpPost(`${import.meta.env.PUBLIC_API_URL}/v1-visit`, {
resourceId: id,
resourceType: 'roadmap',
@ -119,9 +129,9 @@ export function CustomRoadmap() {
return (
<>
<RoadmapHeader />
<FlowRoadmapRenderer roadmap={roadmap!} />
<TopicDetail canSubmitContribution={false} />
{!isEmbed && <RoadmapHeader />}
<FlowRoadmapRenderer isEmbed={isEmbed} roadmap={roadmap!} />
<TopicDetail isEmbed={isEmbed} canSubmitContribution={false} />
</>
);
}

@ -1,26 +1,27 @@
import { ReadonlyEditor } from '../../../editor/readonly-editor';
import type { RoadmapDocument } from './CreateRoadmap/CreateRoadmapModal';
import {
refreshProgressCounters,
renderResourceProgress,
updateResourceProgress,
type ResourceProgressType,
renderTopicProgress,
refreshProgressCounters,
type ResourceProgressType,
updateResourceProgress,
} from '../../lib/resource-progress';
import { pageProgressMessage } from '../../stores/page';
import { useToast } from '../../hooks/use-toast';
import type { Node } from 'reactflow';
import { useCallback, type MouseEvent, useMemo, useState, useRef } from 'react';
import { type MouseEvent, useCallback, useRef, useState } from 'react';
import { EmptyRoadmap } from './EmptyRoadmap';
import { cn } from '../../lib/classname';
import { totalRoadmapNodes } from '../../stores/roadmap.ts';
type FlowRoadmapRendererProps = {
isEmbed?: boolean;
roadmap: RoadmapDocument;
};
export function FlowRoadmapRenderer(props: FlowRoadmapRendererProps) {
const { roadmap } = props;
const { roadmap, isEmbed = false } = props;
const roadmapId = String(roadmap._id!);
const [hideRenderer, setHideRenderer] = useState(false);
@ -32,6 +33,10 @@ export function FlowRoadmapRenderer(props: FlowRoadmapRendererProps) {
topicId: string,
newStatus: ResourceProgressType,
) {
if (isEmbed) {
return;
}
pageProgressMessage.set('Updating progress');
updateResourceProgress(
{

@ -29,6 +29,7 @@ import { Spinner } from '../ReactIcons/Spinner';
import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx';
type TopicDetailProps = {
isEmbed?: boolean;
canSubmitContribution: boolean;
};
@ -42,7 +43,7 @@ const linkTypes: Record<AllowedLinkTypes, string> = {
};
export function TopicDetail(props: TopicDetailProps) {
const { canSubmitContribution } = props;
const { canSubmitContribution, isEmbed = false } = props;
const [hasEnoughLinks, setHasEnoughLinks] = useState(false);
const [contributionUrl, setContributionUrl] = useState('');
@ -163,9 +164,9 @@ export function TopicDetail(props: TopicDetailProps) {
);
const links = topicDom.querySelectorAll('a');
const contributionUrl =
topicDom.querySelector('[data-github-url]')?.dataset?.githubUrl ||
'';
const urlElem: HTMLElement =
topicDom.querySelector('[data-github-url]')!;
const contributionUrl = urlElem?.dataset?.githubUrl || '';
setContributionUrl(contributionUrl);
setHasEnoughLinks(links.length >= 3);
@ -218,6 +219,7 @@ export function TopicDetail(props: TopicDetailProps) {
<>
{/* Actions for the topic */}
<div className="mb-2">
{!isEmbed && (
<TopicProgressButton
topicId={topicId}
resourceId={resourceId}
@ -226,6 +228,7 @@ export function TopicDetail(props: TopicDetailProps) {
setIsActive(false);
}}
/>
)}
<button
type="button"

@ -0,0 +1,29 @@
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import { CustomRoadmap } from '../../components/CustomRoadmap/CustomRoadmap';
import { SkeletonRoadmapHeader } from '../../components/CustomRoadmap/SkeletonRoadmapHeader';
import Loader from '../../components/Loader.astro';
import ProgressHelpPopup from '../../components/ProgressHelpPopup.astro';
import SkeletonLayout from '../../layouts/SkeletonLayout.astro';
---
<SkeletonLayout title='Roadmaps' noIndex={true}>
<div class='relative flex min-h-[550px] flex-col'>
<div data-roadmap-loader class='flex w-full grow flex-col'>
<div class='flex grow items-center justify-center'>
<Loader />
</div>
</div>
<CustomRoadmap isEmbed={true} client:only='react' />
<div class='fixed bottom-5 right-4'>
<a
target='_blank'
class='rounded-md bg-gray-600 p-2 text-white hover:bg-black'
href='https://roadmap.sh'
>
roadmap.sh
</a>
</div>
</div>
</SkeletonLayout>
Loading…
Cancel
Save