Skip to content

Commit 5b882be

Browse files
committed
Add components
1 parent 8a592d4 commit 5b882be

File tree

5 files changed

+229
-2
lines changed

5 files changed

+229
-2
lines changed

MyApp/Pages/Releases.cshtml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
@functions {
77
public List<Page> GetStaticProps(RenderContext ctx) =>
8-
ctx.Resolve<MarkdownPages>().GetVisiblePages("releases", allDirectories:true).Map(page => new Page { Slug = page.Slug.RightPart('/') });
8+
ctx.Resolve<MarkdownPages>().GetVisiblePages("releases", allDirectories:true)
9+
.Map(page => new Page { Slug = page.Slug.RightPart('/') });
910
}
1011

1112
@await Html.PartialAsync("DocsPage", new Shared.DocsPage {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { ref, computed } from "vue"
2+
3+
export default {
4+
template: `
5+
<div class="bg-[#f9f9fb] dark:bg-[#1a1a1a] border border-gray-200 dark:border-gray-800 rounded-xl p-6 shadow-sm hover:shadow-md transition-shadow">
6+
<div class="flex items-center justify-between mb-4">
7+
<h4 class="font-semibold text-xs uppercase tracking-wider text-muted-foreground flex items-center gap-2">
8+
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /></svg>
9+
Architecture
10+
</h4>
11+
<div class="flex bg-muted rounded-lg p-0.5 border border-border/50">
12+
<button
13+
@click="diagramMode = 'Development'"
14+
:class="['px-3 py-1 text-[10px] font-medium rounded-md transition-all', diagramMode === 'Development' ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground']"
15+
>
16+
Development
17+
</button>
18+
<button
19+
@click="diagramMode = 'Production'"
20+
:class="['px-3 py-1 text-[10px] font-medium rounded-md transition-all', diagramMode === 'Production' ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground']"
21+
>
22+
Production
23+
</button>
24+
</div>
25+
</div>
26+
<img :src="currentDiagram" :alt="title + ' Architecture'" class="w-full h-auto rounded dark:invert opacity-90 hover:opacity-100 transition-opacity" />
27+
</div>
28+
`,
29+
props: {
30+
src: String,
31+
},
32+
setup(props) {
33+
const diagramMode = ref('Development')
34+
const currentDiagram = computed(() =>
35+
props.src.replace('-prod.svg', diagramMode.value === 'Production' ? '-prod.svg' : '-dev.svg')
36+
)
37+
return { diagramMode, currentDiagram }
38+
}
39+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { ref } from "vue"
2+
3+
export default {
4+
template: `
5+
<div :class="[
6+
'not-prose copy-block group relative overflow-hidden rounded-lg border border-slate-200 dark:border-slate-700',
7+
'bg-slate-50 dark:bg-gradient-to-br dark:from-slate-900 dark:to-slate-800',
8+
'shadow-sm hover:shadow-md transition-all duration-200',
9+
]"
10+
@click="copy"
11+
>
12+
<!-- Background pattern - only visible in dark mode -->
13+
<div class="absolute inset-0 opacity-0 dark:opacity-50"
14+
:style="{ backgroundImage: 'radial-gradient(circle, rgba(0,0,0,0.05) 1px, transparent 1px)', backgroundSize: '16px 16px' }" />
15+
16+
<div class="relative flex items-center justify-between px-4 py-3">
17+
<!-- Left side - Terminal icon and command -->
18+
<div class="flex items-center gap-3 flex-1 min-w-0 cursor-pointer">
19+
<svg class="w-4 h-4 text-slate-500 dark:text-slate-400 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19h8"/><path d="m4 17 6-6-6-6"/></svg>
20+
<div class="flex items-center gap-2 min-w-0 flex-1">
21+
<code ref="commandRef" class="text-sm font-mono text-slate-900 dark:text-slate-100 truncate">
22+
<slot></slot>
23+
</code>
24+
</div>
25+
</div>
26+
27+
<!-- Right side - Language badge and copy button -->
28+
<div class="flex items-center gap-2 ml-4">
29+
<button
30+
@click="copy"
31+
:class="[
32+
'flex items-center justify-center p-2 rounded-md',
33+
'transition-all duration-200',
34+
'focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2',
35+
copied
36+
? 'bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 border border-green-300 dark:border-green-700'
37+
: 'bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-300 border border-slate-300 dark:border-slate-600 hover:bg-slate-50 dark:hover:bg-slate-700 hover:border-slate-400 dark:hover:border-slate-500'
38+
]"
39+
:aria-label="copied ? 'Copied!' : 'Copy command'"
40+
>
41+
<svg v-if="copied" class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
42+
<svg v-else class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
43+
</button>
44+
</div>
45+
</div>
46+
</div>
47+
`,
48+
props: {
49+
},
50+
setup(props) {
51+
const copied = ref(false)
52+
const commandRef = ref(null)
53+
54+
async function copy(e) {
55+
e.preventDefault()
56+
57+
// Get the text content from the command element
58+
const textToCopy = commandRef.value?.textContent || ""
59+
60+
try {
61+
// Use modern Clipboard API
62+
await navigator.clipboard.writeText(textToCopy)
63+
64+
copied.value = true
65+
setTimeout(() => copied.value = false, 2000)
66+
} catch (err) {
67+
// Fallback for older browsers
68+
const $el = document.createElement("textarea")
69+
$el.value = textToCopy
70+
$el.style.position = "fixed"
71+
$el.style.opacity = "0"
72+
document.body.appendChild($el)
73+
$el.select()
74+
document.execCommand("copy")
75+
document.body.removeChild($el)
76+
77+
copied.value = true
78+
setTimeout(() => copied.value = false, 2000)
79+
}
80+
}
81+
82+
return { copied, commandRef, copy }
83+
}
84+
}

MyApp/wwwroot/pages/components/ScreenshotsGallery.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default {
44
gridClass: String,
55
},
66
template:`
7-
<div class="not-prose my-16">
7+
<div class="not-prose my-8">
88
<!-- Gallery Grid -->
99
<div :class="gridClass || 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8'">
1010
<div v-for="(imageUrl, title) in images" :key="title"
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { computed } from "vue"
2+
import CopyBlock from "./CopyBlock.mjs"
3+
4+
export default {
5+
components: { CopyBlock },
6+
template: `
7+
<div :class="['mb-16 not-prose flex flex-col gap-16 items-center']">
8+
<div class="flex-1 space-y-8 text-left">
9+
<a :href="href" class="group inline-block">
10+
<h3 class="text-4xl font-bold group-hover:text-primary transition-colors flex items-center gap-3">
11+
{{title}}
12+
<svg class="w-6 h-6 opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3" /></svg>
13+
</h3>
14+
</a>
15+
<p class="text-lg text-muted-foreground leading-relaxed">{{description}}</p>
16+
17+
<div class="flex-1 w-full space-y-6">
18+
<CopyBlock v-if="command" class="w-full">
19+
{{command}}
20+
</CopyBlock>
21+
22+
<div v-if="githubTemplate" class="mt-4 p-4 bg-white dark:bg-[#0d1117] border border-gray-200 dark:border-gray-800 rounded-lg shadow-sm">
23+
<div class="flex items-start gap-3">
24+
<svg class="w-5 h-5 text-gray-900 dark:text-white mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 24 24">
25+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 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.23.957-.266 1.983-.399 3.003-.404 1.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.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
26+
</svg>
27+
<div class="flex-1">
28+
<p class="text-sm font-semibold text-gray-900 dark:text-white mb-1">Jumpstart with Copilot</p>
29+
<p class="text-xs text-gray-600 dark:text-gray-400 mb-2">
30+
Instantly scaffold a new App with this template using GitHub Copilot, just describe the features you want and watch Copilot build it!
31+
</p>
32+
<a
33+
:href="githubTemplate"
34+
target="_blank"
35+
rel="noopener noreferrer"
36+
class="inline-flex items-center gap-2 px-3 py-1.5 bg-[#24292f] hover:bg-[#1b1f23] dark:bg-white dark:hover:bg-gray-100 text-white dark:text-gray-900 text-xs font-medium rounded-md transition-colors shadow-sm"
37+
>
38+
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
39+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 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.23.957-.266 1.983-.399 3.003-.404 1.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.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
40+
</svg>
41+
Create from Template
42+
<svg class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
43+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
44+
</svg>
45+
</a>
46+
</div>
47+
</div>
48+
</div>
49+
50+
<a :href="href" class="block relative rounded-2xl overflow-hidden shadow-2xl border-4 border-muted/20 bg-muted group hover:border-primary/30 transition-colors duration-300">
51+
<div class="absolute inset-0 bg-black/0 group-hover:bg-black/5 transition-colors z-10" />
52+
<img
53+
:src="screenshot"
54+
:alt="title + ' Screenshot'"
55+
class="w-full h-auto object-cover transform group-hover:scale-[1.02] transition-transform duration-700"
56+
/>
57+
</a>
58+
</div>
59+
<div class="mt-6 not-prose flex flex-col items-center gap-3">
60+
<span class="text-sm text-muted-foreground font-mono">{{ template }}.react-templates.net</span>
61+
<div class="flex flex-wrap justify-center gap-4">
62+
<a :href="'https://' + template + '.react-templates.net'"
63+
class="group inline-flex items-center gap-2 px-4 py-2 bg-[#61DAFB] hover:bg-[#4fa8c7] text-gray-900 font-medium rounded-lg shadow-md hover:shadow-lg transition-all duration-300">
64+
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
65+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
66+
</svg>
67+
<span>Live Demo</span>
68+
<svg class="w-4 h-4 opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300" fill="none" viewBox="0 0 24 24" stroke="currentColor">
69+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
70+
</svg>
71+
</a>
72+
<a :href="'https://github.com/NetCoreTemplates/' + template"
73+
class="group inline-flex items-center gap-2 px-4 py-2 bg-gray-800 hover:bg-gray-900 dark:bg-gray-700 dark:hover:bg-gray-600 text-white font-medium rounded-lg shadow-md hover:shadow-lg transition-all duration-300">
74+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
75+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 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.23.957-.266 1.983-.399 3.003-.404 1.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.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
76+
</svg>
77+
<span>Source Code</span>
78+
<svg class="w-4 h-4 opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-300" fill="none" viewBox="0 0 24 24" stroke="currentColor">
79+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
80+
</svg>
81+
</a>
82+
</div>
83+
</div>
84+
</div>
85+
</div>
86+
`,
87+
props: {
88+
template: String,
89+
title: String,
90+
description: String,
91+
href: String,
92+
screenshot: String,
93+
command: String,
94+
githubTemplate: String,
95+
reversed: { type: Boolean, default: false }
96+
},
97+
setup(props) {
98+
const command = computed(() => `npx create-net ${props.template} MyProject`)
99+
return {
100+
command
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)