fix: improve meteor effects and fix document management add functionality
Docker Build / Build and Push Docker Image (push) Successful in 3m45s

This commit is contained in:
2026-06-15 03:01:39 +08:00
parent 497ed7c39a
commit 71519301e4
5 changed files with 62 additions and 26 deletions
+7 -3
View File
@@ -76,14 +76,18 @@ export function DocCategories() {
try {
const payload = {
name: form.name,
slug: form.slug || form.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''),
slug: form.slug || form.name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9\u4e00-\u9fff-]/g, ''),
parent_id: form.parent_id ? parseInt(form.parent_id) : null,
sort_order: form.sort_order,
}
let res
if (editingCategory) {
await api.put(`/api/admin/docs/categories/${editingCategory.id}`, payload)
res = await api.put(`/api/admin/docs/categories/${editingCategory.id}`, payload)
} else {
await api.post('/api/admin/docs/categories', payload)
res = await api.post('/api/admin/docs/categories', payload)
}
if (res.data?.success === false) {
return
}
setDialogOpen(false)
fetchCategories()
+6 -2
View File
@@ -113,10 +113,14 @@ export function DocsManagement() {
visibility: form.visibility,
sort_order: form.sort_order,
}
let res
if (editingDoc) {
await api.put(`/api/admin/docs/${editingDoc.id}`, payload)
res = await api.put(`/api/admin/docs/${editingDoc.id}`, payload)
} else {
await api.post('/api/admin/docs/', payload)
res = await api.post('/api/admin/docs/', payload)
}
if (res.data?.success === false) {
return
}
setDialogOpen(false)
fetchData()
+16 -6
View File
@@ -279,6 +279,11 @@ export function Docs() {
<div className='meteor meteor-1' />
<div className='meteor meteor-2' />
<div className='meteor meteor-3' />
<div className='meteor meteor-4' />
<div className='meteor meteor-5' />
<div className='meteor meteor-6' />
<div className='meteor meteor-7' />
<div className='meteor meteor-8' />
</div>
<div className='relative mx-auto w-full max-w-6xl px-6 pt-20 pb-12'>
@@ -504,16 +509,21 @@ export function Docs() {
.dark .meteor::after {
background: linear-gradient(to bottom, oklch(0.78 0.15 210 / 0.7) 0%, oklch(0.78 0.15 210 / 0.35) 15%, oklch(0.78 0.15 210 / 0.1) 50%, transparent 100%);
}
.meteor-1 { left: 15%; top: -2%; animation-duration: 1.8s; animation-delay: 3s; }
.meteor-2 { left: 50%; top: -2%; animation-duration: 1.6s; animation-delay: 10s; }
.meteor-3 { left: 80%; top: -2%; animation-duration: 2.0s; animation-delay: 18s; }
.meteor-1 { left: 5%; top: -2%; animation-duration: 2.0s; animation-delay: 1s; }
.meteor-2 { left: 20%; top: -2%; animation-duration: 1.7s; animation-delay: 5s; }
.meteor-3 { left: 38%; top: -2%; animation-duration: 2.2s; animation-delay: 9s; }
.meteor-4 { left: 52%; top: -2%; animation-duration: 1.8s; animation-delay: 13s; }
.meteor-5 { left: 65%; top: -2%; animation-duration: 2.1s; animation-delay: 17s; }
.meteor-6 { left: 78%; top: -2%; animation-duration: 1.6s; animation-delay: 21s; }
.meteor-7 { left: 88%; top: -2%; animation-duration: 1.9s; animation-delay: 25s; }
.meteor-8 { left: 95%; top: -2%; animation-duration: 2.3s; animation-delay: 29s; }
@keyframes meteor-fall {
0% { height: 0; opacity: 0; transform: translateY(0) translateX(0) rotate(220deg); }
8% { opacity: 1; }
20% { height: 100px; opacity: 0.9; }
50% { height: 160px; opacity: 0.5; }
20% { height: 120px; opacity: 0.9; }
50% { height: 180px; opacity: 0.5; }
80% { height: 60px; opacity: 0.15; }
100% { height: 0; opacity: 0; transform: translateY(700px) translateX(-200px) rotate(220deg); }
100% { height: 0; opacity: 0; transform: translateY(800px) translateX(-120px) rotate(220deg); }
}
@media (prefers-reduced-motion: reduce) {
.nebula-cloud, .meteor { animation: none !important; opacity: 0 !important; }
+17 -9
View File
@@ -175,6 +175,10 @@ export function Hero(props: HeroProps) {
<div className='meteor meteor-4' />
<div className='meteor meteor-5' />
<div className='meteor meteor-6' />
<div className='meteor meteor-7' />
<div className='meteor meteor-8' />
<div className='meteor meteor-9' />
<div className='meteor meteor-10' />
</div>
{/* Section navigation dots (desktop only) */}
@@ -469,12 +473,16 @@ export function Hero(props: HeroProps) {
transparent 100%
);
}
.meteor-1 { left: 8%; top: -2%; animation-duration: 1.8s; animation-delay: 1s; }
.meteor-2 { left: 30%; top: -2%; animation-duration: 1.5s; animation-delay: 5s; }
.meteor-3 { left: 52%; top: -2%; animation-duration: 2.0s; animation-delay: 9s; }
.meteor-4 { left: 75%; top: -2%; animation-duration: 1.6s; animation-delay: 14s; }
.meteor-5 { left: 20%; top: -2%; animation-duration: 1.9s; animation-delay: 19s; }
.meteor-6 { left: 65%; top: -2%; animation-duration: 1.7s; animation-delay: 24s; }
.meteor-1 { left: 5%; top: -2%; animation-duration: 2.0s; animation-delay: 0s; }
.meteor-2 { left: 15%; top: -2%; animation-duration: 1.7s; animation-delay: 3s; }
.meteor-3 { left: 25%; top: -2%; animation-duration: 2.2s; animation-delay: 6s; }
.meteor-4 { left: 35%; top: -2%; animation-duration: 1.8s; animation-delay: 9s; }
.meteor-5 { left: 48%; top: -2%; animation-duration: 2.1s; animation-delay: 12s; }
.meteor-6 { left: 58%; top: -2%; animation-duration: 1.6s; animation-delay: 15s; }
.meteor-7 { left: 68%; top: -2%; animation-duration: 1.9s; animation-delay: 18s; }
.meteor-8 { left: 78%; top: -2%; animation-duration: 2.3s; animation-delay: 21s; }
.meteor-9 { left: 88%; top: -2%; animation-duration: 1.7s; animation-delay: 24s; }
.meteor-10 { left: 95%; top: -2%; animation-duration: 2.0s; animation-delay: 27s; }
@keyframes meteor-fall {
0% {
height: 0;
@@ -485,11 +493,11 @@ export function Hero(props: HeroProps) {
opacity: 1;
}
20% {
height: 100px;
height: 120px;
opacity: 0.9;
}
50% {
height: 160px;
height: 180px;
opacity: 0.5;
}
80% {
@@ -499,7 +507,7 @@ export function Hero(props: HeroProps) {
100% {
height: 0;
opacity: 0;
transform: translateY(700px) translateX(-200px) rotate(220deg);
transform: translateY(800px) translateX(-120px) rotate(220deg);
}
}
+16 -6
View File
@@ -197,6 +197,11 @@ export function Pricing() {
<div className='meteor meteor-1' />
<div className='meteor meteor-2' />
<div className='meteor meteor-3' />
<div className='meteor meteor-4' />
<div className='meteor meteor-5' />
<div className='meteor meteor-6' />
<div className='meteor meteor-7' />
<div className='meteor meteor-8' />
</div>
<PageTransition className='relative mx-auto w-full max-w-6xl px-6 pt-20 pb-12'>
@@ -388,16 +393,21 @@ export function Pricing() {
.dark .meteor::after {
background: linear-gradient(to bottom, oklch(0.78 0.15 210 / 0.7) 0%, oklch(0.78 0.15 210 / 0.35) 15%, oklch(0.78 0.15 210 / 0.1) 50%, transparent 100%);
}
.meteor-1 { left: 15%; top: -2%; animation-duration: 1.8s; animation-delay: 2s; }
.meteor-2 { left: 50%; top: -2%; animation-duration: 1.6s; animation-delay: 9s; }
.meteor-3 { left: 80%; top: -2%; animation-duration: 2.0s; animation-delay: 16s; }
.meteor-1 { left: 5%; top: -2%; animation-duration: 2.0s; animation-delay: 0s; }
.meteor-2 { left: 20%; top: -2%; animation-duration: 1.7s; animation-delay: 4s; }
.meteor-3 { left: 38%; top: -2%; animation-duration: 2.2s; animation-delay: 8s; }
.meteor-4 { left: 52%; top: -2%; animation-duration: 1.8s; animation-delay: 12s; }
.meteor-5 { left: 65%; top: -2%; animation-duration: 2.1s; animation-delay: 16s; }
.meteor-6 { left: 78%; top: -2%; animation-duration: 1.6s; animation-delay: 20s; }
.meteor-7 { left: 88%; top: -2%; animation-duration: 1.9s; animation-delay: 24s; }
.meteor-8 { left: 95%; top: -2%; animation-duration: 2.3s; animation-delay: 28s; }
@keyframes meteor-fall {
0% { height: 0; opacity: 0; transform: translateY(0) translateX(0) rotate(220deg); }
8% { opacity: 1; }
20% { height: 100px; opacity: 0.9; }
50% { height: 160px; opacity: 0.5; }
20% { height: 120px; opacity: 0.9; }
50% { height: 180px; opacity: 0.5; }
80% { height: 60px; opacity: 0.15; }
100% { height: 0; opacity: 0; transform: translateY(700px) translateX(-200px) rotate(220deg); }
100% { height: 0; opacity: 0; transform: translateY(800px) translateX(-120px) rotate(220deg); }
}
@media (prefers-reduced-motion: reduce) {
.nebula-cloud, .meteor { animation: none !important; opacity: 0 !important; }