feat: init longde website project
- Astro 静态网站 - 首页、学习产品介绍 - 等待名单表单 - 隐私政策、用户协议、支持、下载、更新日志页面 - SEO 优化 (sitemap, robots, OG)
This commit is contained in:
commit
bd570d5fb3
11
.env.example
Normal file
11
.env.example
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Environment Variables
|
||||||
|
|
||||||
|
# Site URL (for SEO and sitemap)
|
||||||
|
SITE_URL=http://localhost:4321
|
||||||
|
|
||||||
|
# Server Configuration
|
||||||
|
HOST=localhost
|
||||||
|
PORT=4321
|
||||||
|
|
||||||
|
# API endpoints (for future backend integration)
|
||||||
|
# API_URL=https://api.longde.cloud
|
||||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
node_modules/
|
||||||
|
.DS_Store
|
||||||
|
.astro/
|
||||||
|
.env
|
||||||
|
dist/
|
||||||
93
README.md
Normal file
93
README.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# 龙德AI学习 官网
|
||||||
|
|
||||||
|
AI 学习产品的官方网站,基于 Astro + TypeScript 构建。
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- **框架**: Astro 5.x
|
||||||
|
- **语言**: TypeScript
|
||||||
|
- **样式**: 原生 CSS(Apple 风格)
|
||||||
|
|
||||||
|
## 页面结构
|
||||||
|
|
||||||
|
- `/` - 首页
|
||||||
|
- `/privacy` - 隐私政策
|
||||||
|
- `/terms` - 用户协议
|
||||||
|
- `/support` - 支持与反馈
|
||||||
|
- `/waitlist` - 等待名单
|
||||||
|
- `/changelog` - 更新日志
|
||||||
|
- `/download` - Mac 下载页
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 启动开发服务器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
访问 http://localhost:4321
|
||||||
|
|
||||||
|
### 其他命令
|
||||||
|
|
||||||
|
| 命令 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `npm run dev` | 启动开发服务器 |
|
||||||
|
| `npm run build` | 构建生产版本 |
|
||||||
|
| `npm run preview` | 预览生产版本 |
|
||||||
|
| `npm run astro` | 运行 Astro CLI |
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
复制 `.env.example` 为 `.env` 并根据需要修改:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| `SITE_URL` | http://localhost:4321 | 站点地址(SEO 和 sitemap 使用)|
|
||||||
|
| `HOST` | localhost | 服务器主机 |
|
||||||
|
| `PORT` | 4321 | 服务器端口 |
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
├── src/
|
||||||
|
│ ├── components/ # 组件
|
||||||
|
│ │ ├── Header.astro
|
||||||
|
│ │ ├── Footer.astro
|
||||||
|
│ │ ├── Hero.astro
|
||||||
|
│ │ ├── FeatureCard.astro
|
||||||
|
│ │ ├── CTA.astro
|
||||||
|
│ │ └── WaitlistForm.astro
|
||||||
|
│ ├── layouts/ # 布局
|
||||||
|
│ │ └── BaseLayout.astro
|
||||||
|
│ └── pages/ # 页面
|
||||||
|
│ ├── index.astro
|
||||||
|
│ ├── privacy.astro
|
||||||
|
│ ├── terms.astro
|
||||||
|
│ ├── support.astro
|
||||||
|
│ ├── waitlist.astro
|
||||||
|
│ ├── changelog.astro
|
||||||
|
│ └── download.astro
|
||||||
|
├── public/ # 静态文件
|
||||||
|
│ ├── favicon.svg
|
||||||
|
│ └── robots.txt
|
||||||
|
├── astro.config.mjs
|
||||||
|
├── tsconfig.json
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 域名 `longde.cloud` 正在备案中,所有 URL 使用环境变量管理
|
||||||
|
- 等待名单表单当前为 Mock 模式,后端接入后修改 `WaitlistForm.astro`
|
||||||
|
- SEO 配置在 `BaseLayout.astro` 中统一管理
|
||||||
12
astro.config.mjs
Normal file
12
astro.config.mjs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
|
const host = process.env.HOST || 'localhost';
|
||||||
|
const port = process.env.PORT || '4321';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
site: process.env.SITE_URL || `http://${host}:${port}`,
|
||||||
|
server: {
|
||||||
|
host,
|
||||||
|
port: parseInt(port, 10),
|
||||||
|
},
|
||||||
|
});
|
||||||
5457
package-lock.json
generated
Normal file
5457
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
package.json
Normal file
15
package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "longde-website",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"start": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview",
|
||||||
|
"astro": "astro"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"astro": "^5.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
public/favicon.svg
Normal file
4
public/favicon.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
|
<circle cx="16" cy="16" r="14" fill="none" stroke="#0071e3" stroke-width="2"/>
|
||||||
|
<path d="M10 16h12M16 10v12" stroke="#0071e3" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 261 B |
4
public/robots.txt
Normal file
4
public/robots.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
Sitemap: http://localhost:4321/sitemap.xml
|
||||||
60
src/components/CTA.astro
Normal file
60
src/components/CTA.astro
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
href: string;
|
||||||
|
variant?: 'primary' | 'secondary';
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, description, href, variant = 'primary' } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="cta">
|
||||||
|
<a href={href} class:list={['button', variant]}>{title}</a>
|
||||||
|
{description && <p class="description">{description}</p>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.cta {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.primary {
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: #ffffff;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.primary:hover {
|
||||||
|
background: var(--color-accent-hover);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.secondary {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--color-accent);
|
||||||
|
border: 1px solid var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.secondary:hover {
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: #ffffff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
52
src/components/FeatureCard.astro
Normal file
52
src/components/FeatureCard.astro
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
icon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, description, icon } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="feature-card">
|
||||||
|
{icon && <div class="icon">{icon}</div>}
|
||||||
|
<h3 class="title">{title}</h3>
|
||||||
|
<p class="description">{description}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.feature-card {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--color-bg);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 12px;
|
||||||
|
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-card:hover {
|
||||||
|
border-color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
71
src/components/Footer.astro
Normal file
71
src/components/Footer.astro
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
const currentYear = new Date().getFullYear();
|
||||||
|
|
||||||
|
const footerLinks = [
|
||||||
|
{ href: '/privacy', label: '隐私政策' },
|
||||||
|
{ href: '/terms', label: '用户协议' },
|
||||||
|
{ href: '/support', label: '支持与反馈' },
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="footer-content">
|
||||||
|
<div class="footer-brand">
|
||||||
|
<span class="copyright">© {currentYear} 龙德AI学习</span>
|
||||||
|
</div>
|
||||||
|
<nav class="footer-links">
|
||||||
|
{footerLinks.map(link => (
|
||||||
|
<a href={link.href} class="footer-link">{link.label}</a>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.footer {
|
||||||
|
margin-top: auto;
|
||||||
|
padding: 2rem var(--page-padding);
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
background: var(--color-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-links {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link:hover {
|
||||||
|
color: var(--color-text);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.footer-content {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
99
src/components/Header.astro
Normal file
99
src/components/Header.astro
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
const pathname = Astro.url.pathname;
|
||||||
|
|
||||||
|
const navItems = [
|
||||||
|
{ href: '/waitlist', label: '等待名单' },
|
||||||
|
{ href: '/changelog', label: '更新日志' },
|
||||||
|
{ href: '/support', label: '支持' },
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<header class="header">
|
||||||
|
<nav class="nav">
|
||||||
|
<a href="/" class="logo">
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="1.5"/>
|
||||||
|
<path d="M8 12h8M12 8v8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
<span>龙德</span>
|
||||||
|
</a>
|
||||||
|
<div class="nav-links">
|
||||||
|
{navItems.map(item => (
|
||||||
|
<a
|
||||||
|
href={item.href}
|
||||||
|
class:list={['nav-link', { active: pathname === item.href }]}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
-webkit-backdrop-filter: blur(20px);
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 var(--page-padding);
|
||||||
|
height: 52px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo svg {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-links {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover,
|
||||||
|
.nav-link.active {
|
||||||
|
color: var(--color-text);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.nav-links {
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
42
src/components/Hero.astro
Normal file
42
src/components/Hero.astro
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
subtitle?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, subtitle } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<section class="hero">
|
||||||
|
<div class="hero-content">
|
||||||
|
<h1 class="title">{title}</h1>
|
||||||
|
{subtitle && <p class="subtitle">{subtitle}</p>}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.hero {
|
||||||
|
padding: clamp(4rem, 10vw, 6rem) var(--page-padding);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-content {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: clamp(2rem, 6vw, 3rem);
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
line-height: 1.1;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-size: clamp(1rem, 2.5vw, 1.25rem);
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
254
src/components/WaitlistForm.astro
Normal file
254
src/components/WaitlistForm.astro
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
title?: string;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
title = "加入等待名单",
|
||||||
|
description = "留下你的邮箱,我们会第一时间通知你"
|
||||||
|
} = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="waitlist-form-container">
|
||||||
|
<form id="waitlist-form" class="waitlist-form">
|
||||||
|
<div class="form-header">
|
||||||
|
<h2 class="title">{title}</h2>
|
||||||
|
<p class="description">{description}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-fields">
|
||||||
|
<div class="field">
|
||||||
|
<label for="nickname">昵称(可选)</label>
|
||||||
|
<input type="text" id="nickname" name="nickname" placeholder="你的昵称" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field required">
|
||||||
|
<label for="email">邮箱</label>
|
||||||
|
<input type="email" id="email" name="email" placeholder="your@email.com" required />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label for="device">使用设备</label>
|
||||||
|
<select id="device" name="device">
|
||||||
|
<option value="">请选择</option>
|
||||||
|
<option value="iphone">iPhone</option>
|
||||||
|
<option value="android">Android</option>
|
||||||
|
<option value="ipad">iPad</option>
|
||||||
|
<option value="mac">Mac</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label for="interest">感兴趣的方向</label>
|
||||||
|
<select id="interest" name="interest">
|
||||||
|
<option value="">请选择</option>
|
||||||
|
<option value="gongkai">公考申论 AI 学习教练</option>
|
||||||
|
<option value="ai-tools">AI 工具学习知识库</option>
|
||||||
|
<option value="frontend-interview">程序员前端面试学习助手</option>
|
||||||
|
<option value="other">其他</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label for="pain-point">当前最大痛点</label>
|
||||||
|
<textarea id="pain-point" name="pain-point" rows="3" placeholder="描述你当前学习中遇到的最大困难..."></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field checkbox-field">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
<input type="checkbox" name="beta" value="yes" />
|
||||||
|
<span>愿意参加内测</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field checkbox-field">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
<input type="checkbox" name="notify" value="yes" checked />
|
||||||
|
<span>接受后续邮件通知</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="submit-button">提交</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="success-message" class="success-message" hidden>
|
||||||
|
<div class="success-icon">✓</div>
|
||||||
|
<h3>提交成功!</h3>
|
||||||
|
<p>感谢你的关注,我们会在产品上线后第一时间通知你。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const form = document.getElementById('waitlist-form') as HTMLFormElement;
|
||||||
|
const successMessage = document.getElementById('success-message');
|
||||||
|
|
||||||
|
form?.addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Mock successful submission
|
||||||
|
form.hidden = true;
|
||||||
|
if (successMessage) {
|
||||||
|
successMessage.hidden = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.waitlist-form-container {
|
||||||
|
max-width: 480px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-fields {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field.required label::after {
|
||||||
|
content: " *";
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"],
|
||||||
|
input[type="email"],
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: inherit;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-bg);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus,
|
||||||
|
select:focus,
|
||||||
|
textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: none;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2386868b' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right 1rem center;
|
||||||
|
padding-right: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-field {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label input[type="checkbox"] {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
accent-color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.875rem 1.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
background: var(--color-accent);
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button:hover {
|
||||||
|
background: var(--color-accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-message {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
margin: 0 auto 1rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #ffffff;
|
||||||
|
background: #34c759;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-message h3 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-message p {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
107
src/layouts/BaseLayout.astro
Normal file
107
src/layouts/BaseLayout.astro
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
ogImage?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, description, ogImage } = Astro.props;
|
||||||
|
const siteUrl = import.meta.env.SITE_URL || 'http://localhost:4321';
|
||||||
|
const ogImageUrl = ogImage || `${siteUrl}/og-default.png`;
|
||||||
|
---
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
<meta name="robots" content="index, follow" />
|
||||||
|
<link rel="canonical" href={Astro.url.href} />
|
||||||
|
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={description} />
|
||||||
|
<meta property="og:url" content={Astro.url.href} />
|
||||||
|
<meta property="og:image" content={ogImageUrl} />
|
||||||
|
<meta property="og:site_name" content="龙德AI学习" />
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:title" content={title} />
|
||||||
|
<meta name="twitter:description" content={description} />
|
||||||
|
<meta name="twitter:image" content={ogImageUrl} />
|
||||||
|
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<slot />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
*, *::before, *::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--color-bg: #ffffff;
|
||||||
|
--color-bg-secondary: #f5f5f7;
|
||||||
|
--color-text: #1d1d1f;
|
||||||
|
--color-text-secondary: #86868b;
|
||||||
|
--color-accent: #0071e3;
|
||||||
|
--color-accent-hover: #0077ed;
|
||||||
|
--color-border: #d2d2d7;
|
||||||
|
--font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", monospace;
|
||||||
|
--max-width: 980px;
|
||||||
|
--page-padding: clamp(1rem, 5vw, 2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-bg);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-accent);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
line-height: 1.2;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
125
src/pages/changelog.astro
Normal file
125
src/pages/changelog.astro
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
|
||||||
|
const changelog = [
|
||||||
|
{
|
||||||
|
version: 'v0.1.0',
|
||||||
|
date: '2024年5月4日',
|
||||||
|
changes: ['等待名单页面上线', '基础官网框架搭建'],
|
||||||
|
status: 'planning'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="更新日志 - 龙德AI学习"
|
||||||
|
description="龙德AI学习的最新更新和开发进度。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="更新日志"
|
||||||
|
subtitle="产品开发进度与更新记录"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<section class="changelog-section">
|
||||||
|
<div class="changelog-container">
|
||||||
|
{changelog.map(item => (
|
||||||
|
<div class="changelog-item">
|
||||||
|
<div class="version-header">
|
||||||
|
<span class="version">{item.version}</span>
|
||||||
|
<span class="date">{item.date}</span>
|
||||||
|
<span class:list={['status', item.status]}>{item.status === 'planning' ? '计划中' : item.status}</span>
|
||||||
|
</div>
|
||||||
|
<ul class="changes">
|
||||||
|
{item.changes.map(change => (
|
||||||
|
<li>{change}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.changelog-section {
|
||||||
|
padding: 0 var(--page-padding) 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog-container {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changelog-item {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.25rem 0.75rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status.planning {
|
||||||
|
background: #e8f4fd;
|
||||||
|
color: #0071e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status.current {
|
||||||
|
background: #d4edda;
|
||||||
|
color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changes {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changes li {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changes li::before {
|
||||||
|
content: "•";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
92
src/pages/download.astro
Normal file
92
src/pages/download.astro
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
import CTA from '../components/CTA.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="下载 - 龙德AI学习"
|
||||||
|
description="龙德AI学习 Mac 版下载,敬请期待。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="Mac 应用"
|
||||||
|
subtitle="龙德AI学习 Mac 版正在开发中"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<section class="download-section">
|
||||||
|
<div class="download-card">
|
||||||
|
<div class="icon">
|
||||||
|
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="8" y="8" width="48" height="48" rx="8" stroke="currentColor" stroke-width="2"/>
|
||||||
|
<path d="M24 28c0-4.418 3.582-8 8-8s8 3.582 8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
<circle cx="32" cy="38" r="4" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h2>即将上线</h2>
|
||||||
|
<p>Mac 版应用正在积极开发中,请先加入等待名单获取最新消息。</p>
|
||||||
|
<div class="version-info">
|
||||||
|
<span>支持 macOS 12+</span>
|
||||||
|
</div>
|
||||||
|
<CTA
|
||||||
|
title="加入等待名单"
|
||||||
|
href="/waitlist"
|
||||||
|
variant="primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.download-section {
|
||||||
|
padding: 0 var(--page-padding) 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-card {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 3rem 2rem;
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
border-radius: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-card h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-card p {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-info span {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
padding: 0.375rem 0.875rem;
|
||||||
|
background: var(--color-bg);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
70
src/pages/index.astro
Normal file
70
src/pages/index.astro
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
import FeatureCard from '../components/FeatureCard.astro';
|
||||||
|
import CTA from '../components/CTA.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="龙德AI学习 - 智能学习助手"
|
||||||
|
description="龙德AI学习,专注公考申论、AI工具学习、前端面试的智能学习助手,让学习更高效。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="让学习更高效"
|
||||||
|
subtitle="智能学习助手,专注于公考申论、AI工具学习、前端面试等领域"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<section class="features">
|
||||||
|
<div class="features-container">
|
||||||
|
<FeatureCard
|
||||||
|
title="公考申论 AI 教练"
|
||||||
|
description="基于 AI 的申论批改与反馈,帮你找到提升空间,提高考试成绩。"
|
||||||
|
icon="📝"
|
||||||
|
/>
|
||||||
|
<FeatureCard
|
||||||
|
title="AI 工具知识库"
|
||||||
|
description="系统整理 AI 工具使用技巧,让你在工作和学习中快人一步。"
|
||||||
|
icon="🛠️"
|
||||||
|
/>
|
||||||
|
<FeatureCard
|
||||||
|
title="前端面试助手"
|
||||||
|
description="针对程序员的前端面试准备工具,模拟真实面试场景。"
|
||||||
|
icon="💻"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="cta-section">
|
||||||
|
<CTA
|
||||||
|
title="加入等待名单"
|
||||||
|
description="抢先体验更多功能"
|
||||||
|
href="/waitlist"
|
||||||
|
variant="primary"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.features {
|
||||||
|
padding: 4rem var(--page-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.features-container {
|
||||||
|
max-width: var(--max-width);
|
||||||
|
margin: 0 auto;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section {
|
||||||
|
padding: 2rem var(--page-padding) 4rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
94
src/pages/privacy.astro
Normal file
94
src/pages/privacy.astro
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
|
||||||
|
const lastUpdated = '2024年5月4日';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="隐私政策 - 龙德AI学习"
|
||||||
|
description="龙德AI学习的隐私政策,说明我们如何收集、使用和保护您的个人信息。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="隐私政策"
|
||||||
|
subtitle={`最后更新:${lastUpdated}`}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<article class="content">
|
||||||
|
<div class="content-inner">
|
||||||
|
<section class="section">
|
||||||
|
<h2>信息收集</h2>
|
||||||
|
<p>我们收集您主动提供的信息,包括但不限于:昵称、邮箱地址、设备类型、使用偏好等。这些信息仅用于改进我们的服务和向您提供相关更新。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>信息使用</h2>
|
||||||
|
<p>我们使用收集的信息用于:提供和维护服务、发送产品更新和通知、改进产品功能、分析服务使用情况。您可以随时选择退出邮件通知。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>信息保护</h2>
|
||||||
|
<p>我们采取合理的安全措施保护您的个人信息,防止未经授权的访问、使用或泄露。但互联网传输无法保证100%安全,我们会持续努力保护您的数据。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>Cookie 使用</h2>
|
||||||
|
<p>我们的网站可能使用 Cookie 来改善用户体验。您可以通过浏览器设置禁用 Cookie,但这可能影响部分功能。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>第三方服务</h2>
|
||||||
|
<p>我们可能使用第三方服务提供商来辅助运营服务,他们会按照各自的隐私政策处理您的信息。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>用户权利</h2>
|
||||||
|
<p>您有权访问、更正或删除您的个人信息。如有任何疑问,请通过支持页面联系我们。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>政策更新</h2>
|
||||||
|
<p>我们可能会不时更新本隐私政策。更新后我们会通过网站公告或邮件通知您。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>联系我们</h2>
|
||||||
|
<p>如对本隐私政策有任何疑问,请访问我们的 <a href="/support">支持页面</a>。</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.content {
|
||||||
|
padding: 0 var(--page-padding) 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-inner {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section p {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
29
src/pages/sitemap.xml.astro
Normal file
29
src/pages/sitemap.xml.astro
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
|
||||||
|
const siteUrl = import.meta.env.SITE_URL || 'http://localhost:4321';
|
||||||
|
|
||||||
|
const pages = [
|
||||||
|
{ url: '/', priority: '1.0' },
|
||||||
|
{ url: '/privacy', priority: '0.8' },
|
||||||
|
{ url: '/terms', priority: '0.8' },
|
||||||
|
{ url: '/support', priority: '0.8' },
|
||||||
|
{ url: '/waitlist', priority: '0.9' },
|
||||||
|
{ url: '/changelog', priority: '0.6' },
|
||||||
|
{ url: '/download', priority: '0.7' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const today = new Date().toISOString().split('T')[0];
|
||||||
|
---
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
{pages.map(page => (
|
||||||
|
<url>
|
||||||
|
<loc>{siteUrl}{page.url}</loc>
|
||||||
|
<lastmod>{today}</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>{page.priority}</priority>
|
||||||
|
</url>
|
||||||
|
))}
|
||||||
|
</urlset>
|
||||||
151
src/pages/support.astro
Normal file
151
src/pages/support.astro
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="支持与反馈 - 龙德AI学习"
|
||||||
|
description="获取龙德AI学习的帮助与支持,反馈问题或建议。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="支持与反馈"
|
||||||
|
subtitle="我们随时为您服务"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<section class="content">
|
||||||
|
<div class="content-inner">
|
||||||
|
<div class="support-card">
|
||||||
|
<div class="icon">💬</div>
|
||||||
|
<h2>联系我们</h2>
|
||||||
|
<p>有问题或建议?我们很乐意听到您的声音。</p>
|
||||||
|
<a href="mailto:support@longde.cloud" class="contact-link">support@longde.cloud</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="faq-section">
|
||||||
|
<h3>常见问题</h3>
|
||||||
|
<div class="faq-list">
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>龙德AI学习是什么?</summary>
|
||||||
|
<p>龙德AI学习是一个专注于公考申论、AI工具学习、前端面试的智能学习助手。</p>
|
||||||
|
</details>
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>产品什么时候上线?</summary>
|
||||||
|
<p>我们正在积极开发中,可以加入等待名单获取最新消息。</p>
|
||||||
|
</details>
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>支持哪些平台?</summary>
|
||||||
|
<p>我们计划支持 Web、iOS、Android、Mac 等平台。</p>
|
||||||
|
</details>
|
||||||
|
<details class="faq-item">
|
||||||
|
<summary>如何反馈问题?</summary>
|
||||||
|
<p>请发送邮件至 support@longde.cloud,我们会尽快回复。</p>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.content {
|
||||||
|
padding: 0 var(--page-padding) 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-inner {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.support-card {
|
||||||
|
text-align: center;
|
||||||
|
padding: 3rem 2rem;
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.support-card h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.support-card p {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-link {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-accent);
|
||||||
|
background: var(--color-bg);
|
||||||
|
border: 1px solid var(--color-accent);
|
||||||
|
border-radius: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-link:hover {
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: #ffffff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-section h3 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item {
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
background: var(--color-bg-secondary);
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item summary {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item[open] summary {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item p {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
94
src/pages/terms.astro
Normal file
94
src/pages/terms.astro
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
|
||||||
|
const lastUpdated = '2024年5月4日';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="用户协议 - 龙德AI学习"
|
||||||
|
description="龙德AI学习的用户协议,明确用户与服务商之间的权利与义务。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="用户协议"
|
||||||
|
subtitle={`最后更新:${lastUpdated}`}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<article class="content">
|
||||||
|
<div class="content-inner">
|
||||||
|
<section class="section">
|
||||||
|
<h2>服务说明</h2>
|
||||||
|
<p>龙德AI学习是一个 AI 驱动的学习辅助平台,旨在帮助用户提升学习效率。用户使用我们的服务即表示同意本协议的所有条款。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>用户账户</h2>
|
||||||
|
<p>您需要保证提供给我们的信息真实、准确、完整。您有责任妥善保管账户信息,因账户被盗用造成的损失由您自行承担。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>使用规范</h2>
|
||||||
|
<p>您同意不会利用服务从事任何违法活动,不发布危害国家安全、侵犯他人权益的内容。我们有权对违规行为采取相应措施。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>知识产权</h2>
|
||||||
|
<p>服务中的内容、代码、界面设计等知识产权归我们所有。未经授权,用户不得复制、修改或传播。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>服务变更</h2>
|
||||||
|
<p>我们保留随时修改或暂停服务的权利,并会提前通知用户。因服务变更造成的损失,我们不承担责任。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>免责声明</h2>
|
||||||
|
<p>服务按「现状」提供,我们不对服务的准确性、完整性、可靠性做任何承诺。用户需自行承担使用风险。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>争议解决</h2>
|
||||||
|
<p>本协议的解释和执行均适用中华人民共和国法律。如有争议,双方应协商解决,协商不成的可向法院提起诉讼。</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h2>联系我们</h2>
|
||||||
|
<p>如对用户协议有任何疑问,请访问我们的 <a href="/support">支持页面</a>。</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.content {
|
||||||
|
padding: 0 var(--page-padding) 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-inner {
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section p {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
31
src/pages/waitlist.astro
Normal file
31
src/pages/waitlist.astro
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
import Hero from '../components/Hero.astro';
|
||||||
|
import WaitlistForm from '../components/WaitlistForm.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout
|
||||||
|
title="等待名单 - 龙德AI学习"
|
||||||
|
description="加入龙德AI学习等待名单抢先体验,获取最新产品资讯和内测资格。"
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<main>
|
||||||
|
<Hero
|
||||||
|
title="加入等待名单"
|
||||||
|
subtitle="留下你的信息,我们会第一时间通知你"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<section class="waitlist-section">
|
||||||
|
<WaitlistForm />
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</BaseLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.waitlist-section {
|
||||||
|
padding: 0 var(--page-padding) 4rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
6
tsconfig.json
Normal file
6
tsconfig.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"compilerOptions": {
|
||||||
|
"strictNullChecks": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user