|
|
|
---
|
|
|
|
import Icon from './AstroIcon.astro';
|
|
|
|
import LoginPopup from './AuthenticationFlow/LoginPopup.astro';
|
|
|
|
import BestPracticeHint from './BestPracticeHint.astro';
|
|
|
|
import { MarkFavorite } from './FeaturedItems/MarkFavorite';
|
|
|
|
import ProgressHelpPopup from './ProgressHelpPopup.astro';
|
|
|
|
|
|
|
|
export interface Props {
|
|
|
|
title: string;
|
|
|
|
description: string;
|
|
|
|
bestPracticeId: string;
|
|
|
|
isUpcoming?: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
const { title, description, bestPracticeId, isUpcoming = false } = Astro.props;
|
|
|
|
const isBestPracticeReady = !isUpcoming;
|
|
|
|
---
|
|
|
|
|
|
|
|
<LoginPopup />
|
|
|
|
<ProgressHelpPopup />
|
|
|
|
|
|
|
|
<div class="border-b">
|
|
|
|
<div class="container relative py-5 sm:py-12">
|
|
|
|
<div class="mb-3 mt-0 sm:mb-6">
|
|
|
|
<h1 class="mb-0.5 text-2xl font-bold sm:mb-2 sm:text-4xl">
|
|
|
|
{title}
|
|
|
|
<MarkFavorite
|
|
|
|
resourceId={bestPracticeId}
|
|
|
|
resourceType="best-practice"
|
|
|
|
className="text-gray-500 !opacity-100 hover:text-gray-600 [&>svg]:stroke-[0.4] [&>svg]:stroke-gray-400 hover:[&>svg]:stroke-gray-600 [&>svg]:h-4 [&>svg]:w-4 sm:[&>svg]:h-5 sm:[&>svg]:w-5 ml-1.5 relative focus:outline-0"
|
|
|
|
client:load
|
|
|
|
/>
|
|
|
|
</h1>
|
|
|
|
<p class="text-sm text-gray-500 sm:text-lg">{description}</p>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex justify-between">
|
|
|
|
<div class="flex gap-1 sm:gap-2">
|
|
|
|
<a
|
|
|
|
href="/best-practices"
|
|
|
|
class="rounded-md bg-gray-500 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-600 sm:text-sm"
|
|
|
|
aria-label="Back to All Best Practices"
|
|
|
|
>
|
|
|
|
←<span class="hidden sm:inline"> All Best Practices</span>
|
|
|
|
</a>
|
|
|
|
|
|
|
|
{
|
|
|
|
isBestPracticeReady && (
|
|
|
|
<button
|
|
|
|
data-guest-required
|
|
|
|
data-popup="login-popup"
|
|
|
|
class="inline-flex hidden items-center justify-center rounded-md bg-yellow-400 px-3 py-1.5 text-xs font-medium hover:bg-yellow-500 sm:text-sm"
|
|
|
|
aria-label="Download Roadmap"
|
|
|
|
>
|
|
|
|
<Icon icon="download" />
|
|
|
|
<span class="ml-2 hidden sm:inline">Download</span>
|
|
|
|
</button>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
isBestPracticeReady && (
|
|
|
|
<a
|
|
|
|
data-auth-required
|
|
|
|
class="inline-flex hidden items-center justify-center rounded-md bg-yellow-400 px-3 py-1.5 text-xs font-medium hover:bg-yellow-500 sm:text-sm"
|
|
|
|
aria-label="Download Roadmap"
|
|
|
|
target="_blank"
|
|
|
|
href={`/pdfs/best-practices/${bestPracticeId}.pdf`}
|
|
|
|
>
|
|
|
|
<Icon icon="download" />
|
|
|
|
<span class="ml-2 hidden sm:inline">Download</span>
|
|
|
|
</a>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
<button
|
|
|
|
data-guest-required
|
|
|
|
data-popup="login-popup"
|
|
|
|
class="inline-flex hidden items-center justify-center rounded-md bg-yellow-400 px-3 py-1.5 text-xs font-medium hover:bg-yellow-500 sm:text-sm"
|
|
|
|
aria-label="Subscribe for Updates"
|
|
|
|
>
|
|
|
|
<Icon icon="email" />
|
|
|
|
<span class="ml-2">Subscribe</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{
|
|
|
|
isBestPracticeReady && (
|
|
|
|
<a
|
|
|
|
href={`https://github.com/kamranahmedse/developer-roadmap/issues/new?title=[Suggestion] ${title}`}
|
|
|
|
target="_blank"
|
|
|
|
class="inline-flex items-center justify-center rounded-md bg-gray-500 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-600 sm:text-sm"
|
|
|
|
aria-label="Suggest Changes"
|
|
|
|
>
|
|
|
|
<Icon icon="comment" class="h-3 w-3" />
|
|
|
|
<span class="ml-2 hidden sm:inline">Suggest Changes</span>
|
|
|
|
<span class="ml-2 inline sm:hidden">Suggest</span>
|
|
|
|
</a>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<BestPracticeHint bestPracticeId={bestPracticeId} />
|
|
|
|
</div>
|
|
|
|
</div>
|