Minor Improvement for Custom Roadmap (#4590)

* Add Edit button in the roadmap list

* Add share with others button

* Fix editor link
pull/4622/head
Arik Chakma 1 year ago committed by GitHub
parent b06e82de5f
commit d46cf26812
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      src/components/CustomRoadmap/PersonalRoadmapList.tsx
  2. 145
      src/components/CustomRoadmap/RoadmapHeader.tsx
  3. 29
      src/components/ShareOptions/ShareSuccess.tsx
  4. 20
      src/components/TeamRoadmapsList/TeamRoadmaps.tsx

@ -7,6 +7,7 @@ import {
Globe, Globe,
LockIcon, LockIcon,
Users, Users,
PenSquare,
} from 'lucide-react'; } from 'lucide-react';
import { useToast } from '../../hooks/use-toast'; import { useToast } from '../../hooks/use-toast';
import { import {
@ -142,7 +143,7 @@ function CustomRoadmapItem(props: CustomRoadmapItemProps) {
return ( return (
<li <li
className="grid grid-cols-1 p-2.5 sm:grid-cols-[auto_110px]" className="grid grid-cols-1 p-2.5 sm:grid-cols-[auto_172px]"
key={roadmap._id!} key={roadmap._id!}
> >
<div className="mb-3 grid grid-cols-1 sm:mb-0"> <div className="mb-3 grid grid-cols-1 sm:mb-0">
@ -184,6 +185,16 @@ function CustomRoadmapItem(props: CustomRoadmapItemProps) {
<ExternalLink className="inline-block h-4 w-4" /> <ExternalLink className="inline-block h-4 w-4" />
Visit Visit
</a> </a>
<a
href={editorLink}
className={
'ml-2 flex items-center gap-2 rounded-md border border-gray-800 bg-gray-900 px-2.5 py-1.5 text-xs text-white hover:bg-gray-800 focus:outline-none'
}
target={'_blank'}
>
<PenSquare className="inline-block h-4 w-4" />
Edit
</a>
</div> </div>
</li> </li>
); );

@ -9,6 +9,8 @@ import { type TeamResourceConfig } from '../CreateTeam/RoadmapSelector';
import { useToast } from '../../hooks/use-toast'; import { useToast } from '../../hooks/use-toast';
import { RoadmapActionButton } from './RoadmapActionButton'; import { RoadmapActionButton } from './RoadmapActionButton';
import { Lock, Shapes } from 'lucide-react'; import { Lock, Shapes } from 'lucide-react';
import { Modal } from '../Modal';
import { ShareSuccess } from '../ShareOptions/ShareSuccess';
type RoadmapHeaderProps = {}; type RoadmapHeaderProps = {};
@ -22,9 +24,11 @@ export function RoadmapHeader(props: RoadmapHeaderProps) {
_id: roadmapId, _id: roadmapId,
creator, creator,
team, team,
visibility,
} = useStore(currentRoadmap) || {}; } = useStore(currentRoadmap) || {};
const [isSharing, setIsSharing] = useState(false); const [isSharing, setIsSharing] = useState(false);
const [isSharingWithOthers, setIsSharingWithOthers] = useState(false);
const toast = useToast(); const toast = useToast();
async function deleteResource() { async function deleteResource() {
@ -65,6 +69,22 @@ export function RoadmapHeader(props: RoadmapHeaderProps) {
? `${import.meta.env.PUBLIC_AVATAR_BASE_URL}/${creator?.avatar}` ? `${import.meta.env.PUBLIC_AVATAR_BASE_URL}/${creator?.avatar}`
: '/images/default-avatar.png'; : '/images/default-avatar.png';
const sharingWithOthersModal = isSharingWithOthers && (
<Modal
onClose={() => setIsSharingWithOthers(false)}
wrapperClassName="max-w-lg"
bodyClassName="p-4 flex flex-col"
>
<ShareSuccess
visibility="public"
roadmapId={roadmapId!}
description={description}
onClose={() => setIsSharingWithOthers(false)}
isSharingWithOthers={true}
/>
</Modal>
);
return ( return (
<div className="border-b"> <div className="border-b">
<div className="container relative py-5 sm:py-12"> <div className="container relative py-5 sm:py-12">
@ -117,63 +137,78 @@ export function RoadmapHeader(props: RoadmapHeaderProps) {
<span className="ml-2">Subscribe</span> <span className="ml-2">Subscribe</span>
</button> </button>
</div> </div>
{$canManageCurrentRoadmap && ( <div className="flex items-center gap-2">
<div className="flex items-center gap-2"> {$canManageCurrentRoadmap && (
{isSharing && $currentRoadmap && ( <>
<ShareOptionsModal {isSharing && $currentRoadmap && (
isDiscoverable={$currentRoadmap.isDiscoverable} <ShareOptionsModal
description={$currentRoadmap?.description} isDiscoverable={$currentRoadmap.isDiscoverable}
visibility={$currentRoadmap?.visibility} description={$currentRoadmap?.description}
teamId={$currentRoadmap?.teamId} visibility={$currentRoadmap?.visibility}
roadmapId={$currentRoadmap?._id!} teamId={$currentRoadmap?.teamId}
sharedFriendIds={$currentRoadmap?.sharedFriendIds || []} roadmapId={$currentRoadmap?._id!}
sharedTeamMemberIds={ sharedFriendIds={$currentRoadmap?.sharedFriendIds || []}
$currentRoadmap?.sharedTeamMemberIds || [] sharedTeamMemberIds={
} $currentRoadmap?.sharedTeamMemberIds || []
onClose={() => setIsSharing(false)} }
onShareSettingsUpdate={(settings) => { onClose={() => setIsSharing(false)}
currentRoadmap.set({ onShareSettingsUpdate={(settings) => {
...$currentRoadmap, currentRoadmap.set({
...settings, ...$currentRoadmap,
}); ...settings,
});
}}
/>
)}
<a
href={`${import.meta.env.PUBLIC_EDITOR_APP_URL}/${
$currentRoadmap?._id
}`}
target="_blank"
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white py-1.5 pl-2 pr-2 text-xs font-medium text-black hover:border-gray-300 hover:bg-gray-300 sm:px-3 sm:text-sm"
>
<Shapes className="mr-1.5 h-4 w-4 stroke-[2.5]" />
<span className="hidden sm:inline-block">Edit Roadmap</span>
<span className="sm:hidden">Edit</span>
</a>
<button
onClick={() => setIsSharing(true)}
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white py-1.5 pl-2 pr-2 text-xs font-medium text-black hover:border-gray-300 hover:bg-gray-300 sm:px-3 sm:text-sm"
>
<Lock className="mr-1.5 h-4 w-4 stroke-[2.5]" />
Sharing
</button>
<RoadmapActionButton
onDelete={() => {
const confirmation = window.confirm(
'Are you sure you want to delete this roadmap?'
);
if (!confirmation) {
return;
}
deleteResource().finally(() => null);
}} }}
/> />
)} </>
)}
<a
href={`${import.meta.env.PUBLIC_EDITOR_APP_URL}/${ {!$canManageCurrentRoadmap && visibility === 'public' && (
$currentRoadmap?._id <>
}`} {sharingWithOthersModal}
target="_blank" <button
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white py-1.5 pl-2 pr-2 text-xs font-medium text-black hover:border-gray-300 hover:bg-gray-300 sm:px-3 sm:text-sm" onClick={() => setIsSharingWithOthers(true)}
> className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white py-1.5 pl-2 pr-2 text-xs font-medium text-black hover:border-gray-300 hover:bg-gray-300 sm:px-3 sm:text-sm"
<Shapes className="mr-1.5 h-4 w-4 stroke-[2.5]" /> >
<span className="hidden sm:inline-block">Edit Roadmap</span> <Lock className="mr-1.5 h-4 w-4 stroke-[2.5]" />
<span className="sm:hidden">Edit</span> Share with Others
</a> </button>
<button </>
onClick={() => setIsSharing(true)} )}
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white py-1.5 pl-2 pr-2 text-xs font-medium text-black hover:border-gray-300 hover:bg-gray-300 sm:px-3 sm:text-sm" </div>
>
<Lock className="mr-1.5 h-4 w-4 stroke-[2.5]" />
Sharing
</button>
<RoadmapActionButton
onDelete={() => {
const confirmation = window.confirm(
'Are you sure you want to delete this roadmap?'
);
if (!confirmation) {
return;
}
deleteResource().finally(() => null);
}}
/>
</div>
)}
</div> </div>
<RoadmapHint <RoadmapHint

@ -8,10 +8,17 @@ type ShareSuccessProps = {
onClose: () => void; onClose: () => void;
visibility: AllowedRoadmapVisibility; visibility: AllowedRoadmapVisibility;
description?: string; description?: string;
isSharingWithOthers?: boolean;
}; };
export function ShareSuccess(props: ShareSuccessProps) { export function ShareSuccess(props: ShareSuccessProps) {
const { roadmapId, onClose, description, visibility } = props; const {
roadmapId,
onClose,
description,
visibility,
isSharingWithOthers = false,
} = props;
const baseUrl = import.meta.env.DEV const baseUrl = import.meta.env.DEV
? 'http://localhost:3000' ? 'http://localhost:3000'
@ -42,7 +49,11 @@ export function ShareSuccess(props: ShareSuccessProps) {
<div className="flex grow flex-col justify-center"> <div className="flex grow flex-col justify-center">
<div className="mt-5 flex grow flex-col items-center justify-center gap-1.5"> <div className="mt-5 flex grow flex-col items-center justify-center gap-1.5">
<CheckCircle className="h-14 w-14 text-green-500" /> <CheckCircle className="h-14 w-14 text-green-500" />
<h3 className="text-xl font-medium">Sharing Settings Updated</h3> {isSharingWithOthers ? (
<h3 className="text-xl font-medium">Sharing with Others</h3>
) : (
<h3 className="text-xl font-medium">Sharing Settings Updated</h3>
)}
</div> </div>
<input <input
@ -55,15 +66,21 @@ export function ShareSuccess(props: ShareSuccessProps) {
copyText(shareLink); copyText(shareLink);
}} }}
/> />
<p className="mt-1 text-sm text-gray-400"> {isSharingWithOthers ? (
You can share the above link with anyone who has access <p className="mt-1 text-sm text-gray-400">
</p> You can share the above link with anyone
</p>
) : (
<p className="mt-1 text-sm text-gray-400">
You can share the above link with anyone who has access
</p>
)}
{visibility === 'public' && ( {visibility === 'public' && (
<> <>
<div className="-mx-4 mt-4 flex items-center gap-1.5"> <div className="-mx-4 mt-4 flex items-center gap-1.5">
<span className="h-px grow bg-gray-300" /> <span className="h-px grow bg-gray-300" />
<span className="text-xs uppercase text-gray-400 px-2">Or</span> <span className="px-2 text-xs uppercase text-gray-400">Or</span>
<span className="h-px grow bg-gray-300" /> <span className="h-px grow bg-gray-300" />
</div> </div>

@ -27,6 +27,7 @@ import {
import { RoadmapActionDropdown } from './RoadmapActionDropdown'; import { RoadmapActionDropdown } from './RoadmapActionDropdown';
import { UpdateTeamResourceModal } from '../CreateTeam/UpdateTeamResourceModal'; import { UpdateTeamResourceModal } from '../CreateTeam/UpdateTeamResourceModal';
import { ShareOptionsModal } from '../ShareOptions/ShareOptionsModal'; import { ShareOptionsModal } from '../ShareOptions/ShareOptionsModal';
import { cn } from '../../lib/classname';
export function TeamRoadmaps() { export function TeamRoadmaps() {
const { t: teamId } = getUrlParams(); const { t: teamId } = getUrlParams();
@ -428,7 +429,12 @@ export function TeamRoadmaps() {
return ( return (
<div <div
className="grid grid-cols-1 p-2.5 sm:grid-cols-[auto_110px]" className={cn(
'grid grid-cols-1 p-2.5',
canManageCurrentTeam
? 'sm:grid-cols-[auto_172px]'
: 'sm:grid-cols-[auto_110px]'
)}
key={resourceConfig.resourceId} key={resourceConfig.resourceId}
> >
<div className="mb-3 grid grid-cols-1 sm:mb-0"> <div className="mb-3 grid grid-cols-1 sm:mb-0">
@ -479,6 +485,18 @@ export function TeamRoadmaps() {
<ExternalLink className="inline-block h-4 w-4" /> <ExternalLink className="inline-block h-4 w-4" />
Visit Visit
</a> </a>
{canManageCurrentTeam && (
<a
href={editorLink}
className={
'ml-2 flex items-center gap-2 rounded-md border border-gray-800 bg-gray-900 px-2.5 py-1.5 text-xs text-white hover:bg-gray-800 focus:outline-none'
}
target={'_blank'}
>
<PenSquare className="inline-block h-4 w-4" />
Edit
</a>
)}
</div> </div>
</div> </div>
); );

Loading…
Cancel
Save