Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
153 changes: 122 additions & 31 deletions src/components/CRETemplate/CRETemplateOverview.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import { CRETemplatesFrontmatter } from "~/content.config.ts"

interface Props {
frontmatter: CRETemplatesFrontmatter
templateSlug: string
}
const { frontmatter, templateSlug } = Astro.props
const { frontmatter } = Astro.props
---

<div class="hero-content">
Expand All @@ -28,38 +27,78 @@ const { frontmatter, templateSlug } = Astro.props
<!-- Description -->
<p class="description">{frontmatter.description}</p>

<!-- Get the template section (hidden until CLI is available) -->
<div class="get-template" style="display: none;">
<span class="get-template-label">Get the template</span>
<div class="template-actions">
<div class="command-box">
<code style="color: #fff !important;">cre init --template={templateSlug}</code>
<button class="copy-btn" data-command={`cre init --template=${templateSlug}`} title="Copy command">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
{
frontmatter.cliTemplateIds?.length ? (
<div class="get-template">
<span class="get-template-label">Get the template</span>
<div class="template-actions">
{frontmatter.cliTemplateIds.length > 1 && (
<div class="lang-toggle">
{frontmatter.cliTemplateIds.map((entry, i) => (
<button class={`lang-toggle-pill ${i === 0 ? "active" : ""}`} data-cli-id={entry.id}>
{entry.label.replace("TypeScript", "TS")}
</button>
))}
</div>
)}
<div class="command-box">
<code id="cli-command" style="color: #fff !important;">
cre init --template={frontmatter.cliTemplateIds[0].id}
</code>
<button
class="copy-btn"
id="cli-copy-btn"
data-command={`cre init --template=${frontmatter.cliTemplateIds[0].id}`}
title="Copy command"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
</svg>
</button>
</div>
<a href={frontmatter.githubUrl} class="github-btn" target="_blank" rel="noopener noreferrer">
<svg class="github-icon" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z" />
</svg>
View on GitHub
</a>
</div>
</div>
) : (
<div class="github-buttons">
<a href={frontmatter.githubUrl} class="github-btn" target="_blank" rel="noopener noreferrer">
<svg class="github-icon" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z" />
</svg>
</button>
View on GitHub
</a>
</div>
</div>
</div>

<!-- GitHub button -->
<div class="github-buttons">
<a href={frontmatter.githubUrl} class="github-btn" target="_blank" rel="noopener noreferrer">
<svg class="github-icon" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path
d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"
></path>
</svg>
View on GitHub
</a>
</div>
)
}
</div>
</div>

<script>
document.addEventListener("DOMContentLoaded", () => {
const cliCommand = document.getElementById("cli-command")
const cliCopyBtn = document.getElementById("cli-copy-btn") as HTMLButtonElement | null
const togglePills = document.querySelectorAll<HTMLButtonElement>(".lang-toggle-pill")

togglePills.forEach((pill) => {
pill.addEventListener("click", () => {
const id = pill.dataset.cliId
if (!id || !cliCommand || !cliCopyBtn) return

togglePills.forEach((p) => p.classList.remove("active"))
pill.classList.add("active")

const command = `cre init --template=${id}`
cliCommand.textContent = command
cliCopyBtn.dataset.command = command
})
})

const copyBtns = document.querySelectorAll<HTMLButtonElement>(".copy-btn")
copyBtns.forEach((btn) => {
btn.addEventListener("click", async () => {
Expand Down Expand Up @@ -121,7 +160,6 @@ const { frontmatter, templateSlug } = Astro.props
max-width: 500px;
}

/* Hidden until CLI is available — remove style="display: none;" from .get-template to re-enable */
.get-template {
display: flex;
flex-direction: column;
Expand All @@ -134,10 +172,44 @@ const { frontmatter, templateSlug } = Astro.props
color: #5a6175;
}

.lang-toggle {
display: inline-flex;
border-radius: 6px;
border: 1px solid #d1d5db;
flex-shrink: 0;
}

.lang-toggle-pill {
display: flex;
align-items: center;
padding: 0 14px;
background: #f5f7fa;
color: #5a6175;
font-size: 13px;
font-weight: 600;
border: none;
cursor: pointer;
transition: all 0.15s ease;
white-space: nowrap;
}

.lang-toggle-pill:not(:last-child) {
border-right: 1px solid #d1d5db;
}

.lang-toggle-pill:hover {
background: #e8eaed;
}

.lang-toggle-pill.active {
background: #1e293b;
color: white;
}

.template-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
align-items: stretch;
gap: var(--space-3x);
}

Expand All @@ -149,6 +221,24 @@ const { frontmatter, templateSlug } = Astro.props
background: #1e293b;
border-radius: 6px;
font-family: var(--font-mono, monospace);
white-space: nowrap;
overflow-x: auto;
min-width: 0;
}

@media (max-width: 50em) {
.template-actions {
flex-direction: column;
align-items: flex-start;
}

.command-box {
max-width: 100%;
}

.lang-toggle-pill {
padding: 10px 18px;
}
}

.command-box code,
Expand Down Expand Up @@ -201,10 +291,11 @@ const { frontmatter, templateSlug } = Astro.props
font-size: 14px;
font-weight: 600;
border: 1px solid #0847f7;
border-radius: 4px;
border-radius: 6px;
text-decoration: none;
transition: all 0.2s ease;
min-width: 120px;
white-space: nowrap;
flex-shrink: 0;
}

.github-btn:hover {
Expand Down
15 changes: 11 additions & 4 deletions src/components/CRETemplate/TemplateCard.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ interface Props {
href: string
author: string
languages: string[] // e.g., ["Go", "TypeScript", "Go (MVR)"]
tags?: string[] // e.g., ["data-feeds", "cross-chain", "defi"]
}

const { title, description, href, author, languages } = Astro.props
const { title, description, href, author, languages, tags = [] } = Astro.props

// Extract unique base languages (e.g., "Go (MVR)" -> "Go")
// Extract unique base languages (e.g., "Go (MVR)" -> "Go") — used for filtering
const baseLanguages = [...new Set(languages.map((lang) => lang.replace(/\s*\([^)]*\)\s*/g, "").trim()))].sort(
(a, b) => {
// TypeScript always comes first
Expand All @@ -19,6 +20,9 @@ const baseLanguages = [...new Set(languages.map((lang) => lang.replace(/\s*\([^)
return a.localeCompare(b)
}
)

// Show at most 3 tags on the card
const displayTags = tags.slice(0, 3)
---

<a href={href} class="template-card" data-languages={baseLanguages.join(",")}>
Expand All @@ -27,9 +31,9 @@ const baseLanguages = [...new Set(languages.map((lang) => lang.replace(/\s*\([^)

<!-- Card Content -->
<div class="card-content">
<!-- Badges -->
<!-- Tags -->
<div class="language-badges">
{baseLanguages.map((lang) => <span class="lang-badge">{lang}</span>)}
{displayTags.map((tag) => <span class="lang-badge">{tag}</span>)}
</div>

<!-- Title -->
Expand Down Expand Up @@ -120,6 +124,8 @@ const baseLanguages = [...new Set(languages.map((lang) => lang.replace(/\s*\([^)
/* Language Badges */
.language-badges {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
Expand All @@ -134,6 +140,7 @@ const baseLanguages = [...new Set(languages.map((lang) => lang.replace(/\s*\([^)
border: 1px solid #e5e7eb;
letter-spacing: 0.3px;
text-transform: uppercase;
text-align: center;
}

/* Title */
Expand Down
9 changes: 9 additions & 0 deletions src/content.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ const creTemplatesFrontmatter = z
), // Links to GitHub folders for each language variant
image: z.string(),
featured: z.boolean().optional(), // Whether this template is featured on the hub page
tags: z.array(z.string()).optional(), // Tags from cre-templates registry (e.g., "data-feeds", "cross-chain")
cliTemplateIds: z
.array(
z.object({
label: z.string(), // e.g., "TypeScript", "Go"
id: z.string(), // CLI ID used in `cre init --template=<id>`
})
)
.optional(),
datePublished: z.string().optional(), // ISO date string
lastModified: z.string().optional(), // ISO date string
})
Expand Down
4 changes: 4 additions & 0 deletions src/content/cre-templates/aws-cre-pricefeeds-por.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ description: "Workflows using Chainlink CRE to fetch data from AWS serverless AP
excerpt: "Combine AWS reliability with decentralized trust guarantees for digital asset price feeds and proof-of-reserves monitoring."
author: "AWS"
image: "thumbnail.jpg"
tags:
- "data-feeds"
- "proof-of-reserve"
- "aws"
githubUrl: "https://github.com/aws-samples/sample-cre-pricefeeds-por"
githubRepoLinks:
- label: "Go"
Expand Down
9 changes: 9 additions & 0 deletions src/content/cre-templates/bring-your-own-data.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ description: "A template for bringing your own off-chain Proof-of-Reserve (PoR)
author: "Chainlink Labs"
excerpt: "Publish verified financial or reserve data to smart contracts using CRE."
image: "thumbnail.jpg"
cliTemplateIds:
- label: "TypeScript"
id: "bring-your-own-data-ts"
- label: "Go"
id: "bring-your-own-data-go"
tags:
- "data-feeds"
- "custom-data"
- "proof-of-reserve"
githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/bring-your-own-data"
githubRepoLinks:
- label: "Go"
Expand Down
Loading
Loading