mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-11 19:53:59 +02:00
Topic links contribution functionality
This commit is contained in:
@@ -13,7 +13,7 @@ export function GitHubIcon(props: GitHubIconProps) {
|
|||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362l-.08-9.127c-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126l-.08 13.526c0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
|
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362l-.08-9.127c-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126l-.08 13.526c0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
|
||||||
fill="#24292f"
|
fill={ className?.indexOf('text-') !== -1 ? 'currentColor' : '#24292f' }
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
@@ -15,7 +15,6 @@ import {
|
|||||||
} from '../../lib/resource-progress';
|
} from '../../lib/resource-progress';
|
||||||
import { pageProgressMessage, sponsorHidden } from '../../stores/page';
|
import { pageProgressMessage, sponsorHidden } from '../../stores/page';
|
||||||
import { TopicProgressButton } from './TopicProgressButton';
|
import { TopicProgressButton } from './TopicProgressButton';
|
||||||
import { ContributionForm } from './ContributionForm';
|
|
||||||
import { showLoginPopup } from '../../lib/popup';
|
import { showLoginPopup } from '../../lib/popup';
|
||||||
import { useToast } from '../../hooks/use-toast';
|
import { useToast } from '../../hooks/use-toast';
|
||||||
import type {
|
import type {
|
||||||
@@ -27,6 +26,7 @@ import { cn } from '../../lib/classname';
|
|||||||
import { Ban, FileText, X } from 'lucide-react';
|
import { Ban, FileText, X } from 'lucide-react';
|
||||||
import { getUrlParams } from '../../lib/browser';
|
import { getUrlParams } from '../../lib/browser';
|
||||||
import { Spinner } from '../ReactIcons/Spinner';
|
import { Spinner } from '../ReactIcons/Spinner';
|
||||||
|
import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx';
|
||||||
|
|
||||||
type TopicDetailProps = {
|
type TopicDetailProps = {
|
||||||
canSubmitContribution: boolean;
|
canSubmitContribution: boolean;
|
||||||
@@ -44,7 +44,7 @@ const linkTypes: Record<AllowedLinkTypes, string> = {
|
|||||||
export function TopicDetail(props: TopicDetailProps) {
|
export function TopicDetail(props: TopicDetailProps) {
|
||||||
const { canSubmitContribution } = props;
|
const { canSubmitContribution } = props;
|
||||||
|
|
||||||
const [contributionAlertMessage, setContributionAlertMessage] = useState('');
|
const [hasEnoughLinks, setHasEnoughLinks] = useState(false);
|
||||||
const [isActive, setIsActive] = useState(false);
|
const [isActive, setIsActive] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [isContributing, setIsContributing] = useState(false);
|
const [isContributing, setIsContributing] = useState(false);
|
||||||
@@ -66,12 +66,10 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
// Close the topic detail when user clicks outside the topic detail
|
// Close the topic detail when user clicks outside the topic detail
|
||||||
useOutsideClick(topicRef, () => {
|
useOutsideClick(topicRef, () => {
|
||||||
setIsActive(false);
|
setIsActive(false);
|
||||||
setIsContributing(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
useKeydown('Escape', () => {
|
useKeydown('Escape', () => {
|
||||||
setIsActive(false);
|
setIsActive(false);
|
||||||
setIsContributing(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Toggle topic is available even if the component UI is not active
|
// Toggle topic is available even if the component UI is not active
|
||||||
@@ -120,7 +118,6 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
setIsActive(true);
|
setIsActive(true);
|
||||||
sponsorHidden.set(true);
|
sponsorHidden.set(true);
|
||||||
|
|
||||||
setContributionAlertMessage('');
|
|
||||||
setTopicId(topicId);
|
setTopicId(topicId);
|
||||||
setResourceType(resourceType);
|
setResourceType(resourceType);
|
||||||
setResourceId(resourceId);
|
setResourceId(resourceId);
|
||||||
@@ -159,6 +156,13 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
let topicHtml = '';
|
let topicHtml = '';
|
||||||
if (!isCustomResource) {
|
if (!isCustomResource) {
|
||||||
topicHtml = response as string;
|
topicHtml = response as string;
|
||||||
|
const topicDom = new DOMParser().parseFromString(
|
||||||
|
topicHtml,
|
||||||
|
'text/html',
|
||||||
|
);
|
||||||
|
const links = topicDom.querySelectorAll('a');
|
||||||
|
|
||||||
|
setHasEnoughLinks(links.length >= 3);
|
||||||
} else {
|
} else {
|
||||||
setLinks((response as RoadmapContentDocument)?.links || []);
|
setLinks((response as RoadmapContentDocument)?.links || []);
|
||||||
setTopicTitle((response as RoadmapContentDocument)?.title || '');
|
setTopicTitle((response as RoadmapContentDocument)?.title || '');
|
||||||
@@ -186,6 +190,8 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hasContent = topicHtml?.length > 0 || links?.length > 0 || topicTitle;
|
const hasContent = topicHtml?.length > 0 || links?.length > 0 || topicTitle;
|
||||||
|
const dataDir = resourceType === 'roadmap' ? 'roadmaps' : 'best-practices';
|
||||||
|
const githubBaseUrl = `https://github.com/kamranahmedse/developer-roadmap/tree/master/src/data/${dataDir}/${resourceId}/content`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'relative z-50'}>
|
<div className={'relative z-50'}>
|
||||||
@@ -204,21 +210,6 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isLoading && isContributing && (
|
|
||||||
<ContributionForm
|
|
||||||
resourceType={resourceType}
|
|
||||||
resourceId={resourceId}
|
|
||||||
topicId={topicId}
|
|
||||||
onClose={(message?: string) => {
|
|
||||||
if (message) {
|
|
||||||
setContributionAlertMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsContributing(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isContributing && !isLoading && !error && (
|
{!isContributing && !isLoading && !error && (
|
||||||
<>
|
<>
|
||||||
{/* Actions for the topic */}
|
{/* Actions for the topic */}
|
||||||
@@ -229,7 +220,6 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
resourceType={resourceType}
|
resourceType={resourceType}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setIsActive(false);
|
setIsActive(false);
|
||||||
setIsContributing(false);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -239,7 +229,6 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
className="absolute right-2.5 top-2.5 inline-flex items-center rounded-lg bg-transparent p-1.5 text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900"
|
className="absolute right-2.5 top-2.5 inline-flex items-center rounded-lg bg-transparent p-1.5 text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsActive(false);
|
setIsActive(false);
|
||||||
setIsContributing(false);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<X className="h-5 w-5" />
|
<X className="h-5 w-5" />
|
||||||
@@ -292,29 +281,21 @@ export function TopicDetail(props: TopicDetailProps) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Contribution */}
|
{/* Contribution */}
|
||||||
{canSubmitContribution && (
|
{canSubmitContribution && !hasEnoughLinks && (
|
||||||
<div className="mt-8 flex-1 border-t">
|
<div className="mt-8 flex-1 border-t">
|
||||||
<p className="mb-2 mt-2 text-sm leading-relaxed text-gray-400">
|
<p className="mb-2 mt-2 text-sm leading-relaxed text-gray-400">
|
||||||
Help others learn by submitting links to learn more about this
|
Help us improve this introduction and submit a link to a good
|
||||||
topic{' '}
|
article, podcast, video, or any other resource that helped you
|
||||||
|
understand this topic better.
|
||||||
</p>
|
</p>
|
||||||
<button
|
<a
|
||||||
onClick={() => {
|
href={githubBaseUrl}
|
||||||
if (isGuest) {
|
target={'_blank'}
|
||||||
setIsActive(false);
|
className="flex w-full items-center justify-center rounded-md bg-gray-800 p-2 text-sm text-white transition-colors hover:bg-black hover:text-white disabled:bg-green-200 disabled:text-black"
|
||||||
showLoginPopup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsContributing(true);
|
|
||||||
}}
|
|
||||||
disabled={!!contributionAlertMessage}
|
|
||||||
className="block w-full rounded-md bg-gray-800 p-2 text-sm text-white transition-colors hover:bg-black hover:text-white disabled:bg-green-200 disabled:text-black"
|
|
||||||
>
|
>
|
||||||
{contributionAlertMessage
|
<GitHubIcon className="mr-2 inline-block h-4 w-4 text-white" />
|
||||||
? contributionAlertMessage
|
Edit this Content
|
||||||
: 'Submit a Link'}
|
</a>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
Reference in New Issue
Block a user