Skip to content

Commit fe0530e

Browse files
Add install and preset quick start to the home page
1 parent e4cb224 commit fe0530e

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

‎src/pages/index.astro‎

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,78 @@ const structuredData = {
336336
</div>
337337
</section>
338338

339+
<!-- Try it with a preset -->
340+
<section class="py-32 px-6 sm:px-8">
341+
<div class="max-w-4xl mx-auto text-center">
342+
<p class="section-reveal text-sm font-semibold tracking-widest uppercase text-purple-400 mb-4">Try It With a Preset</p>
343+
<h2 class="section-reveal text-3xl md:text-5xl font-bold mb-8">Test the API your app calls.</h2>
344+
<p class="section-reveal text-lg md:text-xl mb-12" style="color: var(--text-muted);">
345+
Install Dev Proxy, download the preset for your API, and run your app as usual. It keeps calling the real API URLs.
346+
</p>
347+
<p class="section-reveal text-left text-sm font-semibold mb-3" style="color: var(--text-muted);">1. Install Dev Proxy</p>
348+
<div class="section-reveal rounded-2xl border overflow-hidden text-left" style="background: var(--bg-secondary); border-color: var(--border-primary);" data-os-tabs>
349+
<div class="flex border-b" role="tablist" aria-label="Operating system" style="border-color: var(--border-primary);">
350+
{[
351+
{ id: 'windows', label: 'Windows' },
352+
{ id: 'macos', label: 'macOS' },
353+
{ id: 'linux', label: 'Linux' },
354+
].map((tab, i) => (
355+
<button
356+
type="button"
357+
role="tab"
358+
id={`os-tab-${tab.id}`}
359+
aria-controls={`os-panel-${tab.id}`}
360+
aria-selected={i === 0 ? 'true' : 'false'}
361+
tabindex={i === 0 ? 0 : -1}
362+
data-os={tab.id}
363+
class="-mb-px px-5 py-3 text-sm font-semibold border-b-2 border-transparent transition-colors hover:text-purple-400 aria-selected:border-purple-500 aria-selected:text-purple-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-purple-500"
364+
>{tab.label}</button>
365+
))}
366+
</div>
367+
{[
368+
{ id: 'windows', lines: ['winget install DevProxy.DevProxy --silent'], note: 'After the installation finishes, open a new terminal.' },
369+
{ id: 'macos', lines: ['brew tap dotnet/dev-proxy', 'brew install dev-proxy'] },
370+
{ id: 'linux', lines: ['bash -c "$(curl -sL https://aka.ms/devproxy/setup.sh)"'] },
371+
].map((panel, i) => (
372+
<div role="tabpanel" id={`os-panel-${panel.id}`} aria-labelledby={`os-tab-${panel.id}`} hidden={i !== 0} class="p-4 sm:p-6">
373+
<div class="font-mono text-xs sm:text-sm space-y-1">
374+
{panel.lines.map((line) => <p class="break-words" style="color: var(--text-secondary);">{line}</p>)}
375+
</div>
376+
{panel.note && <p class="mt-3 text-xs" style="color: var(--text-faint);">{panel.note}</p>}
377+
</div>
378+
))}
379+
</div>
380+
<p class="section-reveal mt-8 text-left text-sm font-semibold mb-3" style="color: var(--text-muted);">2. Download a preset and start Dev Proxy with it</p>
381+
<div class="section-reveal rounded-2xl border overflow-hidden text-left font-mono text-xs sm:text-sm" style="background: var(--bg-secondary); border-color: var(--border-primary);">
382+
<div class="p-4 sm:p-6 space-y-1">
383+
<p class="break-words" style="color: var(--text-secondary);">devproxy config get <span class="text-purple-400">github-rate-limiting</span></p>
384+
<p class="break-words" style="color: var(--text-secondary);">devproxy --config-file "~dataFolder/configs/<span class="text-purple-400">github-rate-limiting</span>/.devproxy/devproxyrc.json"</p>
385+
</div>
386+
</div>
387+
<p class="section-reveal mt-8 text-left text-sm font-semibold mb-3" style="color: var(--text-muted);">Presets for popular APIs</p>
388+
<div class="section-reveal grid grid-cols-2 md:grid-cols-4 gap-4">
389+
{[
390+
{ api: 'GitHub', preset: 'github-rate-limiting' },
391+
{ api: 'OpenAI', preset: 'openai-throttling' },
392+
{ api: 'Anthropic', preset: 'anthropic-throttling' },
393+
{ api: 'Microsoft Graph', preset: 'microsoft-graph-rate-limiting' },
394+
].map((item) => (
395+
<a
396+
href={`${import.meta.env.BASE_URL}samples/${item.preset}/`}
397+
class="rounded-xl border p-4 text-left transition-all duration-300 hover:border-purple-500/50"
398+
style="background: var(--bg-secondary); border-color: var(--border-primary);"
399+
>
400+
<p class="text-sm font-semibold mb-1">{item.api}</p>
401+
<p class="text-xs font-mono break-words" style="color: var(--text-faint);">{item.preset}</p>
402+
</a>
403+
))}
404+
</div>
405+
<p class="section-reveal mt-8 text-sm" style="color: var(--text-faint);">
406+
The first time you start Dev Proxy, you trust its certificate. <a href="https://aka.ms/devproxy/start" target="_blank" rel="noopener" class="text-purple-400 hover:text-purple-300">Step-by-step setup</a> &middot; <a href={`${import.meta.env.BASE_URL}samples/`} class="text-purple-400 hover:text-purple-300">More presets</a>
407+
</p>
408+
</div>
409+
</section>
410+
339411
<!-- Getting started video -->
340412
<section class="py-32 px-6 sm:px-8">
341413
<div class="max-w-4xl mx-auto text-center">
@@ -543,4 +615,35 @@ const structuredData = {
543615
);
544616

545617
document.querySelectorAll('.section-reveal').forEach((el) => observer.observe(el));
618+
619+
document.querySelectorAll<HTMLElement>('[data-os-tabs]').forEach((root) => {
620+
const tabs = Array.from(root.querySelectorAll<HTMLButtonElement>('[role="tab"]'));
621+
const select = (tab: HTMLButtonElement, focus = false, persist = false) => {
622+
tabs.forEach((t) => {
623+
const selected = t === tab;
624+
t.setAttribute('aria-selected', String(selected));
625+
t.tabIndex = selected ? 0 : -1;
626+
root.querySelector<HTMLElement>(`#${t.getAttribute('aria-controls')}`)!.hidden = !selected;
627+
});
628+
if (focus) tab.focus();
629+
if (persist) {
630+
const url = new URL(window.location.href);
631+
url.searchParams.set('os', tab.dataset.os!);
632+
history.replaceState(null, '', url);
633+
}
634+
};
635+
tabs.forEach((tab, i) => {
636+
tab.addEventListener('click', () => select(tab, false, true));
637+
tab.addEventListener('keydown', (e) => {
638+
const next = e.key === 'ArrowRight' ? 1 : e.key === 'ArrowLeft' ? -1 : 0;
639+
if (next) select(tabs[(i + next + tabs.length) % tabs.length], true, true);
640+
});
641+
});
642+
// A shared ?os= link wins over the visitor's own OS.
643+
const fromUrl = new URLSearchParams(window.location.search).get('os');
644+
const platform = (navigator.userAgent || '').toLowerCase();
645+
const detected = platform.includes('mac') ? 'macos' : platform.includes('linux') && !platform.includes('android') ? 'linux' : 'windows';
646+
const initial = tabs.find((t) => t.dataset.os === fromUrl) ?? tabs.find((t) => t.dataset.os === detected);
647+
if (initial) select(initial);
648+
});
546649
</script>

0 commit comments

Comments
 (0)