diff --git a/src/components/CustomRoadmap/CreateRoadmap/CreateRoadmapModal.tsx b/src/components/CustomRoadmap/CreateRoadmap/CreateRoadmapModal.tsx index 1c9d9cf9d..ca47570d8 100644 --- a/src/components/CustomRoadmap/CreateRoadmap/CreateRoadmapModal.tsx +++ b/src/components/CustomRoadmap/CreateRoadmap/CreateRoadmapModal.tsx @@ -23,21 +23,17 @@ export const allowedCustomRoadmapType = ['role', 'skill'] as const; export type AllowedCustomRoadmapType = (typeof allowedCustomRoadmapType)[number]; -export const allowedShowcaseStatus = ['visible', 'hidden'] as const; -export type AllowedShowcaseStatus = (typeof allowedShowcaseStatus)[number]; - -export const allowedRoadmapFeaturedListStatus = [ +export const allowedShowcaseStatus = [ 'idle', 'submitted', 'approved', 'rejected', 'rejected_with_reason', ] as const; -export type AllowedRoadmapFeaturedListStatus = - (typeof allowedRoadmapFeaturedListStatus)[number]; +export type AllowedShowcaseStatus = (typeof allowedShowcaseStatus)[number]; export interface RoadmapDocument { - _id?: string; + _id: string; title: string; description?: string; slug?: string; @@ -61,18 +57,21 @@ export interface RoadmapDocument { edges: any[]; isDiscoverable?: boolean; - showcaseStatus?: AllowedShowcaseStatus; ratings: { average: number; + totalCount: number; breakdown: { [key: number]: number; }; }; - featuredListStatus?: AllowedRoadmapFeaturedListStatus; - featuredListRejectedReason?: string; - featuredListSubmittedAt?: Date; - featuredListApprovedAt?: Date; + showcaseStatus?: AllowedShowcaseStatus; + showcaseRejectedReason?: string; + showcaseRejectedAt?: Date; + showcaseSubmittedAt?: Date; + showcaseApprovedAt?: Date; + + hasMigratedContent?: boolean; createdAt: Date; updatedAt: Date; diff --git a/src/components/CustomRoadmap/FeaturedListing/FeaturedListingStatus.tsx b/src/components/CustomRoadmap/FeaturedListing/FeaturedListingStatus.tsx deleted file mode 100644 index 9c5ccb531..000000000 --- a/src/components/CustomRoadmap/FeaturedListing/FeaturedListingStatus.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { useState } from 'react'; -import { SubmitFeaturedListingWarning } from './SubmitFeaturedListingWarning'; -import type { GetRoadmapResponse } from '../CustomRoadmap'; -import { CheckIcon, EyeIcon, FlagIcon, SendIcon, XIcon } from 'lucide-react'; -import { cn } from '../../../lib/classname'; - -type FeaturedListingStatusProps = { - currentRoadmap: GetRoadmapResponse; -}; - -export function FeaturedListingStatus(props: FeaturedListingStatusProps) { - const { currentRoadmap } = props; - - const { featuredListStatus = 'idle' } = currentRoadmap; - const [showSubmitWarning, setShowSubmitWarning] = useState(false); - - const currentLabel = { - idle: { - icon: SendIcon, - label: 'Submit for Featured Listing', - className: 'bg-gray-100 text-gray-600 border-gray-200', - }, - submitted: { - icon: EyeIcon, - label: 'Waiting for Approval', - className: 'bg-blue-100 text-blue-600 border-blue-200', - }, - approved: { - icon: CheckIcon, - label: 'Approved', - className: 'bg-green-100 text-green-600 border-green-200', - }, - rejected: { - icon: XIcon, - label: 'Rejected', - className: 'bg-red-100 text-red-600 border-red-200', - }, - rejected_with_reason: { - icon: FlagIcon, - label: 'Changes Requested', - className: 'bg-yellow-100 text-yellow-600 border-yellow-200', - }, - }[featuredListStatus]; - - return ( - <> - {showSubmitWarning && ( - { - setShowSubmitWarning(false); - }} - /> - )} - - - - ); -} diff --git a/src/components/CustomRoadmap/RoadmapHeader.tsx b/src/components/CustomRoadmap/RoadmapHeader.tsx index 957594f11..9ac525571 100644 --- a/src/components/CustomRoadmap/RoadmapHeader.tsx +++ b/src/components/CustomRoadmap/RoadmapHeader.tsx @@ -11,7 +11,8 @@ import { RoadmapActionButton } from './RoadmapActionButton'; import { ShareRoadmapButton } from '../ShareRoadmapButton.tsx'; import { CustomRoadmapAlert } from './CustomRoadmapAlert.tsx'; import { CustomRoadmapRatings } from './CustomRoadmapRatings.tsx'; -import { FeaturedListingStatus } from './FeaturedListing/FeaturedListingStatus.tsx'; +import { ShowcaseStatus } from './Showcase/ShowcaseStatus.tsx'; +import { ShowcaseAlert } from './Showcase/ShowcaseAlert.tsx'; type RoadmapHeaderProps = {}; @@ -74,126 +75,131 @@ export function RoadmapHeader(props: RoadmapHeaderProps) { : '/images/default-avatar.png'; return ( -
-
- {!$canManageCurrentRoadmap && } - - {creator?.name && ( -
- {creator.name} - - Created by  - - {creator?.name} + <> + {$currentRoadmap && } + +
+
+ {!$canManageCurrentRoadmap && } + + {creator?.name && ( +
+ {creator.name} + + Created by  + + {creator?.name} + + {team && ( + <> +  from  + + {team?.name} + + + )} - {team && ( - <> -  from  - - {team?.name} - - - )} - +
+ )} +
+

{title}

+

+ {description} +

- )} -
-

{title}

-

- {description} -

-
-
- -
- {$canManageCurrentRoadmap && ( - <> - {isSharing && $currentRoadmap && ( - setIsSharing(false)} - onShareSettingsUpdate={(settings) => { - currentRoadmap.set({ - ...$currentRoadmap, - ...settings, - }); +
+ +
+ {$canManageCurrentRoadmap && ( + <> + {isSharing && $currentRoadmap && ( + setIsSharing(false)} + onShareSettingsUpdate={(settings) => { + currentRoadmap.set({ + ...$currentRoadmap, + ...settings, + }); + }} + /> + )} + + {$currentRoadmap && ( + + )} + + setIsSharing(true)} + onCustomize={() => { + window.location.href = `${ + import.meta.env.PUBLIC_EDITOR_APP_URL + }/${$currentRoadmap?._id}`; }} - /> - )} + onDelete={() => { + const confirmation = window.confirm( + 'Are you sure you want to delete this roadmap?', + ); - {$currentRoadmap && ( - - )} + if (!confirmation) { + return; + } + + deleteResource().finally(() => null); + }} + /> + + )} - setIsSharing(true)} - onCustomize={() => { - window.location.href = `${ - import.meta.env.PUBLIC_EDITOR_APP_URL - }/${$currentRoadmap?._id}`; - }} - onDelete={() => { - const confirmation = window.confirm( - 'Are you sure you want to delete this roadmap?', - ); - - if (!confirmation) { - return; - } - - deleteResource().finally(() => null); - }} + {((ratings?.average || 0) > 0 || + showcaseStatus === 'approved') && ( + - - )} - - {((ratings?.average || 0) > 0 || showcaseStatus === 'visible') && ( - - )} + )} +
-
- + +
-
+ ); } diff --git a/src/components/CustomRoadmap/Showcase/ShowcaseAlert.tsx b/src/components/CustomRoadmap/Showcase/ShowcaseAlert.tsx new file mode 100644 index 000000000..ea7b0cad0 --- /dev/null +++ b/src/components/CustomRoadmap/Showcase/ShowcaseAlert.tsx @@ -0,0 +1,75 @@ +import { + CheckIcon, + EyeIcon, + FlagIcon, + FrownIcon, + SmileIcon, + XIcon, +} from 'lucide-react'; +import { cn } from '../../../lib/classname'; +import type { GetRoadmapResponse } from '../CustomRoadmap'; + +type ShowcaseAlertProps = { + currentRoadmap: GetRoadmapResponse; +}; + +export function ShowcaseAlert(props: ShowcaseAlertProps) { + const { currentRoadmap } = props; + + // const { showcaseStatus = 'idle' } = currentRoadmap; + // if (showcaseStatus === 'idle') { + // return null; + // } + + const showcaseStatus = 'rejected_with_reason'; + + const showcaseStatusMap = { + submitted: { + icon: EyeIcon, + label: + 'We are reviewing your roadmap. It will be visible to everyone on the platform once approved.', + className: 'text-blue-600 border-blue-200', + }, + approved: { + icon: SmileIcon, + label: 'Hooray! Your roadmap is now visible to everyone on the platform.', + className: 'text-green-600 border-green-200', + }, + rejected: { + icon: FrownIcon, + label: 'Sorry, we are unable to feature your roadmap at this time.', + className: 'text-red-600 border-red-200', + }, + rejected_with_reason: { + icon: FlagIcon, + label: ( + <> + Your roadmap needs changes before it can be featured.{' '} + + + ), + className: 'text-yellow-600 border-yellow-200', + }, + }; + const { icon: Icon, label, className } = showcaseStatusMap[showcaseStatus]; + + return ( +
+
+
+ +
{label}
+
+
+
+ ); +} diff --git a/src/components/CustomRoadmap/Showcase/ShowcaseStatus.tsx b/src/components/CustomRoadmap/Showcase/ShowcaseStatus.tsx new file mode 100644 index 000000000..0a5ac14e2 --- /dev/null +++ b/src/components/CustomRoadmap/Showcase/ShowcaseStatus.tsx @@ -0,0 +1,42 @@ +import { useState } from 'react'; +import { SubmitShowcaseWarning } from './SubmitShowcaseWarning'; +import type { GetRoadmapResponse } from '../CustomRoadmap'; +import { SendIcon } from 'lucide-react'; + +type ShowcaseStatusProps = { + currentRoadmap: GetRoadmapResponse; +}; + +export function ShowcaseStatus(props: ShowcaseStatusProps) { + const { currentRoadmap } = props; + + const { showcaseStatus = 'idle' } = currentRoadmap; + const [showSubmitWarning, setShowSubmitWarning] = useState(false); + + if (!currentRoadmap || showcaseStatus !== 'idle') { + return null; + } + + return ( + <> + {showSubmitWarning && ( + { + setShowSubmitWarning(false); + }} + /> + )} + + + + ); +} diff --git a/src/components/CustomRoadmap/FeaturedListing/SubmitFeaturedListingWarning.tsx b/src/components/CustomRoadmap/Showcase/SubmitShowcaseWarning.tsx similarity index 82% rename from src/components/CustomRoadmap/FeaturedListing/SubmitFeaturedListingWarning.tsx rename to src/components/CustomRoadmap/Showcase/SubmitShowcaseWarning.tsx index 1f8a69e87..a71c071e9 100644 --- a/src/components/CustomRoadmap/FeaturedListing/SubmitFeaturedListingWarning.tsx +++ b/src/components/CustomRoadmap/Showcase/SubmitShowcaseWarning.tsx @@ -6,12 +6,12 @@ import { useStore } from '@nanostores/react'; import { currentRoadmap } from '../../../stores/roadmap'; import { useToast } from '../../../hooks/use-toast'; -type SubmitFeaturedListingWarningProps = { +type SubmitShowcaseWarningProps = { onClose: () => void; }; -export function SubmitFeaturedListingWarning( - props: SubmitFeaturedListingWarningProps, +export function SubmitShowcaseWarning( + props: SubmitShowcaseWarningProps, ) { const { onClose } = props; @@ -40,21 +40,21 @@ export function SubmitFeaturedListingWarning( queryClient, ); - const { featuredListStatus = 'idle', featuredListRejectedReason } = + const { showcaseStatus = 'idle', showcaseRejectedReason } = $currentRoadmap || {}; return (

- {featuredListStatus === 'rejected_with_reason' + {showcaseStatus === 'rejected_with_reason' ? 'Rejected Reason' : 'Featured Listing'}

- {featuredListStatus === 'rejected_with_reason' && - featuredListRejectedReason} - {featuredListStatus === 'idle' && ( + {showcaseStatus === 'rejected_with_reason' && + showcaseRejectedReason} + {showcaseStatus === 'idle' && ( <> Submitting your roadmap for a featured listing will make it visible to everyone on the platform.{' '} @@ -78,7 +78,7 @@ export function SubmitFeaturedListingWarning( > {submit.isPending ? 'Submitting...' - : featuredListStatus === 'rejected_with_reason' + : showcaseStatus === 'rejected_with_reason' ? 'Resubmit' : 'Submit'}