Files
remnawave-minishop/docs-site/src/pages/demo.astro
T

547 lines
14 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
import { emailPreviews } from '../lib/emailPreviews.mjs';
const defaultDemoSrc = '/demo/runtime/app/index.html?path=/home&mock=tariffs';
const docsHref = '/getting-started/demo/';
---
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, viewport-fit=cover"
/>
<meta name="robots" content="noindex, nofollow" />
<meta name="theme-color" content="#05080f" />
<link rel="icon" href="/favicon.png" sizes="any" />
<link rel="icon" href="/favicon.webp" type="image/webp" />
<title>remnawave-minishop demo</title>
<style>
:root {
color-scheme: dark;
font-family:
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
sans-serif;
background: #05080f;
color: #f8fafc;
}
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
}
body {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
overflow: hidden;
background: #05080f;
}
body[data-demo-mode='emails'] {
overflow: auto;
}
.demo-topbar {
display: flex;
gap: 1rem;
align-items: center;
justify-content: space-between;
min-height: 3.25rem;
padding: max(0.7rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right))
0.7rem max(1rem, env(safe-area-inset-left));
border-bottom: 1px solid rgb(148 163 184 / 20%);
background: rgb(5 8 15 / 94%);
backdrop-filter: blur(16px);
}
.demo-topbar__toggle,
.demo-topbar__hide {
display: none;
}
.demo-topbar__panel {
display: flex;
flex: 1 1 auto;
gap: 1rem;
align-items: center;
justify-content: space-between;
min-width: 0;
}
.demo-topbar__title {
min-width: 0;
}
.demo-topbar__title strong {
display: block;
color: #00fe7a;
font-size: 0.95rem;
line-height: 1.2;
}
.demo-topbar__state {
display: flex;
flex: 0 1 24rem;
gap: 0.5rem;
align-items: center;
justify-content: flex-end;
min-width: 0;
}
.demo-topbar__state-label {
flex: 0 0 auto;
color: #94a3b8;
font-size: 0.78rem;
font-weight: 650;
line-height: 1;
}
.demo-topbar__state-select {
min-width: 13.25rem;
max-width: 100%;
border: 1px solid rgb(148 163 184 / 28%);
border-radius: 7px;
padding: 0.42rem 1.9rem 0.42rem 0.65rem;
background: rgb(15 23 42 / 82%);
color: #f8fafc;
cursor: pointer;
font: inherit;
font-size: 0.82rem;
font-weight: 650;
line-height: 1.2;
}
.demo-topbar__state-select:focus-visible {
outline: 2px solid rgb(0 254 122 / 72%);
outline-offset: 2px;
}
.demo-topbar__back {
flex: 0 0 auto;
border: 1px solid rgb(0 254 122 / 45%);
border-radius: 7px;
padding: 0.48rem 0.72rem;
color: #f8fafc;
font-size: 0.86rem;
font-weight: 650;
line-height: 1;
text-decoration: none;
}
.demo-topbar__back:hover {
border-color: #00fe7a;
color: #00fe7a;
}
.demo-topbar__actions {
display: flex;
flex: 0 0 auto;
gap: 0.5rem;
align-items: center;
}
.demo-frame {
display: block;
width: 100%;
height: 100%;
border: 0;
background: #05080f;
}
.demo-frame[hidden],
.email-previews[hidden] {
display: none;
}
.email-previews {
min-height: 0;
overflow: auto;
background:
linear-gradient(180deg, rgb(15 23 42 / 32%), rgb(5 8 15 / 0) 14rem),
#05080f;
}
.email-previews__inner {
width: min(72rem, calc(100% - 2rem));
margin: 0 auto;
padding: 2rem 0 4rem;
}
.email-previews__header {
display: grid;
gap: 0.45rem;
max-width: 44rem;
margin-bottom: 1.25rem;
}
.email-previews__eyebrow {
color: #00fe7a;
font-size: 0.78rem;
font-weight: 800;
line-height: 1;
text-transform: uppercase;
}
.email-previews__header h1 {
margin: 0;
color: #ffffff;
font-size: 1.65rem;
line-height: 1.15;
}
.email-previews__header p {
margin: 0;
color: #a7b1c2;
font-size: 0.95rem;
line-height: 1.55;
}
.email-previews__index {
display: flex;
flex-wrap: wrap;
gap: 0.45rem;
margin: 0 0 1.4rem;
}
.email-previews__index a {
border: 1px solid rgb(148 163 184 / 24%);
border-radius: 7px;
padding: 0.42rem 0.6rem;
background: rgb(15 23 42 / 62%);
color: #dbeafe;
font-size: 0.78rem;
font-weight: 650;
line-height: 1;
text-decoration: none;
}
.email-previews__index a:hover {
border-color: rgb(0 254 122 / 54%);
color: #00fe7a;
}
.email-preview {
border-top: 1px solid rgb(148 163 184 / 18%);
}
.email-preview:last-child {
border-bottom: 1px solid rgb(148 163 184 / 18%);
}
.email-preview summary {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 1rem;
align-items: center;
padding: 1rem 0;
cursor: pointer;
list-style: none;
}
.email-preview summary::-webkit-details-marker {
display: none;
}
.email-preview__title {
min-width: 0;
}
.email-preview__title strong {
display: block;
color: #f8fafc;
font-size: 0.98rem;
line-height: 1.3;
}
.email-preview__title span {
display: block;
margin-top: 0.22rem;
color: #94a3b8;
font-size: 0.78rem;
line-height: 1.35;
}
.email-preview__meta {
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid rgb(14 165 233 / 34%);
border-radius: 999px;
padding: 0.28rem 0.55rem;
color: #bae6fd;
font-size: 0.72rem;
font-weight: 750;
line-height: 1;
white-space: nowrap;
}
.email-preview__body {
padding: 0.1rem 0 1.6rem;
}
.email-preview__frame-wrap {
overflow: hidden;
border: 1px solid rgb(148 163 184 / 20%);
border-radius: 8px;
background: #05070a;
}
.email-preview__frame {
display: block;
width: 100%;
height: 760px;
border: 0;
background: #05070a;
}
@media (max-width: 42rem) {
body {
display: block;
}
.demo-topbar {
position: fixed;
z-index: 2;
top: max(0.55rem, env(safe-area-inset-top));
right: max(0.55rem, env(safe-area-inset-right));
display: block;
min-height: 0;
padding: 0;
border: 0;
background: transparent;
backdrop-filter: none;
pointer-events: none;
}
.demo-topbar__toggle {
display: inline-grid;
min-width: 2.75rem;
height: 2.25rem;
place-items: center;
pointer-events: auto;
border: 1px solid rgb(0 254 122 / 35%);
border-radius: 999px;
padding: 0 0.7rem;
background: rgb(5 8 15 / 86%);
box-shadow: 0 12px 34px rgb(0 0 0 / 28%);
color: #f8fafc;
backdrop-filter: blur(12px);
cursor: pointer;
font: inherit;
font-size: 0.78rem;
font-weight: 700;
line-height: 1;
}
.demo-topbar:not([data-collapsed]) .demo-topbar__toggle,
.demo-topbar[data-collapsed] .demo-topbar__panel {
display: none;
}
.demo-topbar__panel {
display: flex;
flex-wrap: wrap;
gap: 0.55rem;
align-items: center;
width: min(20rem, calc(100vw - 1.1rem));
padding: 0.38rem;
pointer-events: auto;
border: 1px solid rgb(148 163 184 / 22%);
border-radius: 10px;
background: rgb(5 8 15 / 90%);
box-shadow: 0 16px 44px rgb(0 0 0 / 34%);
backdrop-filter: blur(14px);
}
.demo-topbar__title {
flex: 1 1 auto;
overflow: hidden;
}
.demo-topbar__title strong {
overflow: hidden;
font-size: 0.78rem;
text-overflow: ellipsis;
white-space: nowrap;
}
.demo-topbar__state {
flex: 1 1 100%;
order: 3;
width: 100%;
justify-content: stretch;
}
.demo-topbar__state-label {
display: none;
}
.demo-topbar__state-select {
width: 100%;
min-width: 0;
font-size: 0.78rem;
}
.demo-topbar__actions {
gap: 0.35rem;
}
.demo-topbar__back {
display: inline-flex;
border-color: rgb(0 254 122 / 35%);
padding: 0.42rem 0.55rem;
font-size: 0.78rem;
}
.demo-topbar__hide {
display: inline-grid;
width: 1.95rem;
height: 1.95rem;
place-items: center;
border: 1px solid rgb(148 163 184 / 26%);
border-radius: 7px;
padding: 0;
background: transparent;
color: #cbd5e1;
cursor: pointer;
font: inherit;
font-size: 1rem;
line-height: 1;
}
.demo-frame {
height: 100dvh;
}
.email-previews {
min-height: 100dvh;
}
.email-previews__inner {
width: min(calc(100% - 1rem), 72rem);
padding-top: 4rem;
}
.email-preview summary {
grid-template-columns: minmax(0, 1fr);
gap: 0.55rem;
}
.email-preview__meta {
width: fit-content;
}
.email-preview__frame {
height: 720px;
}
}
</style>
</head>
<body>
<header class="demo-topbar" data-collapsed>
<button
class="demo-topbar__toggle"
type="button"
aria-controls="demo-topbar-panel"
aria-expanded="false"
>
Демо
</button>
<div class="demo-topbar__panel" id="demo-topbar-panel">
<div class="demo-topbar__title">
<strong>remnawave-minishop demo</strong>
</div>
<label class="demo-topbar__state">
<span class="demo-topbar__state-label">Состояние</span>
<select class="demo-topbar__state-select" aria-label="Состояние личного кабинета">
<option value="tariffs">По умолчанию</option>
<option value="depleted">Трафик закончился</option>
<option value="no-subscription">Нет подписки</option>
<option value="trial">Доступна пробная подписка</option>
<option value="trial-telegram">Email-only: Telegram для триала</option>
<option value="referral-telegram">Email-only: Telegram для рефбонуса</option>
<option value="devices">Лимит и докупка устройств</option>
<option value="notifications">Telegram-уведомления</option>
<option value="auth">Вход и регистрация</option>
<option value="emails">Email-письма</option>
</select>
</label>
<div class="demo-topbar__actions">
<a class="demo-topbar__back" href={docsHref}>К документации</a>
<button class="demo-topbar__hide" type="button" aria-label="Скрыть панель">
×
</button>
</div>
</div>
</header>
<iframe
id="demo-frame"
class="demo-frame"
title="remnawave-minishop static demo"
src={defaultDemoSrc}
loading="eager"
></iframe>
<section
id="email-previews"
class="email-previews"
aria-labelledby="email-previews-title"
hidden
>
<div class="email-previews__inner">
<header class="email-previews__header">
<div class="email-previews__eyebrow">Email preview</div>
<h1 id="email-previews-title">Превью email-писем</h1>
<p>
Все транзакционные письма собраны на одной странице и подписаны по
сценарию отправки. HTML-превью генерируются теми же шаблонами,
которые отправляются пользователям.
</p>
</header>
<nav class="email-previews__index" aria-label="Навигация по email-письмам">
{
emailPreviews.map((preview) => (
<a href={`#${preview.id}`}>{preview.title}</a>
))
}
</nav>
<div class="email-previews__list">
{
emailPreviews.map((preview, index) => (
<details class="email-preview" id={preview.id} open={index === 0}>
<summary>
<span class="email-preview__title">
<strong>{preview.title}</strong>
<span>{preview.subject}</span>
</span>
<span class="email-preview__meta">{preview.category}</span>
</summary>
<div class="email-preview__body">
<div class="email-preview__frame-wrap">
<iframe
class="email-preview__frame"
title={`Email preview: ${preview.title}`}
srcdoc={preview.html}
loading="lazy"
sandbox="allow-scripts"
></iframe>
</div>
</div>
</details>
))
}
</div>
</div>
</section>
<script is:inline src="/demo/demo-shell.js"></script>
</body>
</html>