mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2026-09-24 15:00:31 +08:00
* wip: custom roadmap renderer * wip: custom roadmap events * wip: roadmap content * wip: svg styles * wip: custom roadmap progress * Render progress * Shortcut progress * Progress Tracking styles * wip: edit and share button * fix: disabled the share button * wip: content links rendering * Fix progress share * Replace disabled with `canShare` * wip: show custom roadmaps * wip: users all roadmaps * fix: create roadmap api * chore: roadmap sidebar icon * wip: content links * Update links color * Create roadmap home * Create Roadmap button * Roadmap type * chore: share progress modal * wip: share roadmap * wip: change visibility * chore: custom roadmap progress in activity * wip: custom roadmap share progress * chore: friend's roadmap * wip: custom roadmap skeleton * chore: roadmap title * Restricted Page * fix: skeleton loading width * Fix create roadmap button * chore: remove user id * chore: pick roadmap and share * chore: open new tab on create roadmap * chore: change share title * chore: use team id from params * chore: team roadmap create modal * chore: create team roadmap * chore: custom roadmap modal * chore: placeholde roadmaps * chore: roadmap hint * chore: visibility label * chore: public roadmap * chore: empty screen * chore: team progress * chore: create roadmap responsive * chore: form error * chore: multi user history * wip: manage custom roadmap * chore: empty roadmap list * chore: custom roadmap visit * chore: shared roadmaps * chore: shared roadmaps * chore: empty screen and topic title * chore: show progress bar * Implement Error in topic details * Add Modal close button * fix: link groups * Refactor roadmap creation * Refactor roadmap creation * Refactor team creation * Refactor team roadmaps * Refactor team creation roadmap selection * Refactor * Refactor team roadmap loading * Refactor team roadmaps * Refactor team roadmaps listing * Refactor Account dropdown * Updates * Refactor Account dropdown * Fix Team name overflow * Change Icon color * Update team dropdown * Minor UI fixes * Fix minor UI * Flicker fix in team dropdown * Roadmap action dropdown with responsiveness * Team roadmaps listing * Update team settings * Team roadmaps listing * fix: remove visibility change * Update roadmap options modal * Add dummy renderer * Add renderer script * Add generate renderer script * Add generate renderer * wip: add share settings * Update * Update UI * Update Minor UI * Fix team issue * Update Personal roadmaps UI * Add Roadmap Secret * Update teams type * Rearrange sections * Change Secret name * Add action button on roadmap detail page --------- Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
175 lines
5.8 KiB
TypeScript
175 lines
5.8 KiB
TypeScript
import { useRef, useState } from 'react';
|
|
import { useOutsideClick } from '../hooks/use-outside-click';
|
|
import { type OptionType, SearchSelector } from './SearchSelector';
|
|
import type { PageType } from './CommandMenu/CommandMenu';
|
|
import { CheckIcon } from './ReactIcons/CheckIcon';
|
|
import { httpPut } from '../lib/http';
|
|
import type { TeamResourceConfig } from './CreateTeam/RoadmapSelector';
|
|
import { Spinner } from './ReactIcons/Spinner';
|
|
|
|
type AddTeamRoadmapProps = {
|
|
teamId: string;
|
|
allRoadmaps: PageType[];
|
|
availableRoadmaps: PageType[];
|
|
onClose: () => void;
|
|
onMakeChanges: (roadmapId: string) => void;
|
|
setResourceConfigs: (config: TeamResourceConfig) => void;
|
|
};
|
|
|
|
export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
|
const {
|
|
teamId,
|
|
onMakeChanges,
|
|
onClose,
|
|
allRoadmaps,
|
|
availableRoadmaps,
|
|
setResourceConfigs,
|
|
} = props;
|
|
const [error, setError] = useState('');
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [selectedRoadmap, setSelectedRoadmap] = useState<string>('');
|
|
const popupBodyEl = useRef<HTMLDivElement>(null);
|
|
|
|
async function addTeamResource(roadmapId: string) {
|
|
if (!teamId) {
|
|
return;
|
|
}
|
|
|
|
setIsLoading(true);
|
|
const { error, response } = await httpPut<TeamResourceConfig>(
|
|
`${
|
|
import.meta.env.PUBLIC_API_URL
|
|
}/v1-update-team-resource-config/${teamId}`,
|
|
{
|
|
teamId: teamId,
|
|
resourceId: roadmapId,
|
|
resourceType: 'roadmap',
|
|
removed: [],
|
|
}
|
|
);
|
|
|
|
if (error || !response) {
|
|
setError(error?.message || 'Error adding roadmap');
|
|
return;
|
|
}
|
|
|
|
setResourceConfigs(response);
|
|
}
|
|
|
|
useOutsideClick(popupBodyEl, () => {
|
|
onClose();
|
|
});
|
|
|
|
const selectedRoadmapTitle = allRoadmaps.find(
|
|
(roadmap) => roadmap.id === selectedRoadmap
|
|
)?.title;
|
|
|
|
return (
|
|
<div className="popup fixed left-0 right-0 top-0 z-50 flex h-full items-center justify-center overflow-y-auto overflow-x-hidden bg-black/50">
|
|
<div className="relative h-full w-full max-w-md p-4 md:h-auto">
|
|
<div
|
|
ref={popupBodyEl}
|
|
className="popup-body relative rounded-lg bg-white p-4 shadow"
|
|
>
|
|
{isLoading && (
|
|
<>
|
|
<div className="flex items-center justify-center gap-2 py-8">
|
|
<Spinner isDualRing={false} className="h-4 w-4" />
|
|
<h2 className="font-medium">Loading...</h2>
|
|
</div>
|
|
</>
|
|
)}
|
|
{!isLoading && !error && selectedRoadmap && (
|
|
<div className={'text-center'}>
|
|
<CheckIcon additionalClasses="h-10 w-10 mx-auto opacity-20 mb-3 mt-4" />
|
|
<h3 className="mb-1.5 text-2xl font-medium">
|
|
{selectedRoadmapTitle} Added
|
|
</h3>
|
|
<p className="mb-4 text-sm leading-none text-gray-400">
|
|
<button
|
|
onClick={() => onMakeChanges(selectedRoadmap)}
|
|
className="underline underline-offset-2 hover:text-gray-900"
|
|
>
|
|
Click here
|
|
</button>{' '}
|
|
to make changes to the roadmap.
|
|
</p>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={onClose}
|
|
type="button"
|
|
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
|
>
|
|
Done
|
|
</button>
|
|
<button
|
|
onClick={() => {
|
|
setSelectedRoadmap('');
|
|
setError('');
|
|
setIsLoading(false);
|
|
}}
|
|
type="button"
|
|
className="flex-grow cursor-pointer rounded-lg bg-black py-2 text-center text-white"
|
|
>
|
|
+ Add More
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{!isLoading && error && (
|
|
<>
|
|
<h3 className="mb-1.5 text-2xl font-medium">Error</h3>
|
|
<p className="mb-3 text-sm leading-none text-red-400">{error}</p>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={onClose}
|
|
type="button"
|
|
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</>
|
|
)}
|
|
{!isLoading && !error && !selectedRoadmap && (
|
|
<>
|
|
<h3 className="mb-1.5 text-2xl font-medium">Add Roadmap</h3>
|
|
<p className="mb-3 text-sm leading-none text-gray-400">
|
|
Search and add a roadmap
|
|
</p>
|
|
|
|
<SearchSelector
|
|
options={availableRoadmaps.map((roadmap) => ({
|
|
value: roadmap.id,
|
|
label: roadmap.title,
|
|
}))}
|
|
onSelect={(option: OptionType) => {
|
|
const roadmapId = option.value;
|
|
addTeamResource(roadmapId).finally(() => {
|
|
setIsLoading(false);
|
|
setSelectedRoadmap(roadmapId);
|
|
});
|
|
}}
|
|
inputClassName="mt-2 mb-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:border-gray-400"
|
|
placeholder={'Search for roadmap'}
|
|
/>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
onClick={onClose}
|
|
type="button"
|
|
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|