This commit is contained in:
2026-02-12 21:03:53 +08:00
parent 414d3334fd
commit bbb8f3bbaf
20 changed files with 11277 additions and 235 deletions

View File

@@ -17,7 +17,7 @@
/* Hero Section */
.hero-section {
position: relative;
height: 320px;
height: 380px; /* Enlarge height */
width: 100%;
overflow: hidden;
@@ -33,11 +33,11 @@
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to top, #050505 0%, rgba(5,5,5,0.6) 50%, rgba(0,0,0,0.2) 100%);
background: linear-gradient(to top, #050505 0%, rgba(5,5,5,0.6) 60%, rgba(0,0,0,0.2) 100%);
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 24px;
padding: 32px; /* More padding */
box-sizing: border-box;
.status-tag {
@@ -45,26 +45,27 @@
background: var(--primary-cyan, #00f0ff);
color: #000;
font-weight: 800;
padding: 4px 12px;
border-radius: 4px;
font-size: 14px;
margin-bottom: 12px;
box-shadow: 0 0 10px rgba(0, 240, 255, 0.4);
padding: 6px 16px; /* Larger tag */
border-radius: 6px;
font-size: 16px; /* Larger font */
margin-bottom: 16px;
box-shadow: 0 0 15px rgba(0, 240, 255, 0.5);
}
.hero-title {
font-size: 32px;
font-weight: 800;
font-size: 36px; /* Larger title */
font-weight: 900;
color: #fff;
text-shadow: 0 2px 10px rgba(0,0,0,0.5);
line-height: 1.3;
text-shadow: 0 4px 15px rgba(0,0,0,0.6);
line-height: 1.25;
letter-spacing: 0.5px;
}
}
}
.main-content {
padding: 0 24px;
transform: translateY(-20px);
padding: 0 32px; /* More side padding */
transform: translateY(-30px); /* Larger overlap */
position: relative;
z-index: 10;
}
@@ -73,34 +74,36 @@
.info-grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
margin-bottom: 32px;
gap: 20px; /* More gap */
margin-bottom: 40px;
.info-card {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 16px;
background: rgba(255, 255, 255, 0.08); /* Slightly lighter for contrast */
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 20px; /* Rounder */
padding: 20px; /* More padding */
display: flex;
align-items: center;
box-shadow: 0 8px 20px rgba(0,0,0,0.2);
.info-text {
margin-left: 16px;
margin-left: 20px;
display: flex;
flex-direction: column;
.label {
font-size: 12px;
color: rgba(255,255,255,0.5);
margin-bottom: 4px;
font-size: 14px; /* Larger label */
color: rgba(255,255,255,0.6);
margin-bottom: 6px;
}
.value {
font-size: 16px;
font-size: 18px; /* Larger value */
color: #fff;
font-weight: 500;
font-weight: 600;
letter-spacing: 0.3px;
}
}
}
@@ -109,64 +112,65 @@
/* Stats Section */
.stats-section {
background: #111;
border-radius: 20px;
padding: 24px;
margin-bottom: 32px;
border: 1px solid rgba(255,255,255,0.05);
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
border-radius: 24px;
padding: 28px; /* More padding */
margin-bottom: 40px;
border: 1px solid rgba(255,255,255,0.08);
box-shadow: 0 15px 40px rgba(0,0,0,0.4);
.stats-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 16px;
margin-bottom: 20px;
.stats-title {
font-size: 18px;
font-size: 20px; /* Larger title */
font-weight: 700;
color: #fff;
}
.stats-count {
.current {
font-size: 24px;
font-size: 32px; /* Larger numbers */
font-weight: 800;
color: var(--primary-cyan, #00f0ff);
}
.divider {
font-size: 16px;
font-size: 20px;
color: #666;
margin: 0 4px;
margin: 0 6px;
}
.max {
font-size: 18px;
font-size: 20px;
color: #888;
}
}
}
.progress-bar-container {
height: 8px;
background: rgba(255,255,255,0.1);
border-radius: 4px;
height: 12px; /* Thicker bar */
background: rgba(255,255,255,0.15);
border-radius: 6px;
position: relative;
overflow: hidden;
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #00f0ff, #bd00ff);
border-radius: 4px;
border-radius: 6px;
transition: width 0.5s ease-out;
box-shadow: 0 0 10px rgba(189, 0, 255, 0.4);
}
.progress-glow {
position: absolute;
top: 0;
width: 10px;
width: 15px;
height: 100%;
background: #fff;
filter: blur(4px);
opacity: 0.8;
filter: blur(6px);
opacity: 0.9;
transform: translateX(-50%);
transition: left 0.5s ease-out;
}
@@ -175,65 +179,71 @@
/* Detail Section */
.detail-section {
padding-bottom: 40px;
.section-header {
display: flex;
align-items: center;
margin-bottom: 24px;
margin-bottom: 30px;
.title-text {
font-size: 22px;
font-size: 24px; /* Larger title */
font-weight: 800;
color: #fff;
margin-right: 16px;
margin-right: 20px;
white-space: nowrap;
letter-spacing: 0.5px;
}
.line {
flex: 1;
height: 1px;
height: 2px; /* Thicker line */
background: linear-gradient(90deg, rgba(255,255,255,0.2), transparent);
}
}
.rich-text-wrapper {
color: #ccc;
font-size: 16px;
line-height: 1.8;
color: #ddd; /* Brighter text */
font-size: 18px; /* Base font size increased */
line-height: 1.9;
image {
max-width: 100%;
border-radius: 12px;
margin: 16px 0;
border-radius: 16px;
margin: 20px 0;
box-shadow: 0 8px 24px rgba(0,0,0,0.3);
}
/* Markdown Styling */
h1, h2, h3, h4, h5, h6 { margin-top: 24px; margin-bottom: 16px; color: #fff; font-weight: 700; line-height: 1.4; }
h1 { font-size: 24px; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 8px; }
h2 { font-size: 20px; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 6px; }
h3 { font-size: 18px; }
h1, h2, h3, h4, h5, h6 { margin-top: 32px; margin-bottom: 20px; color: #fff; font-weight: 700; line-height: 1.4; }
h1 { font-size: 30px; border-bottom: 2px solid rgba(255,255,255,0.1); padding-bottom: 12px; }
h2 { font-size: 26px; border-bottom: 1px solid rgba(255,255,255,0.08); padding-bottom: 10px; }
h3 { font-size: 22px; }
p { margin-bottom: 16px; }
p { margin-bottom: 20px; }
strong { font-weight: 800; color: #fff; }
em { font-style: italic; color: #aaa; }
del { text-decoration: line-through; color: #666; }
em { font-style: italic; color: #bbb; }
del { text-decoration: line-through; color: #777; }
ul, ol { margin-bottom: 16px; padding-left: 20px; }
li { margin-bottom: 6px; list-style-position: outside; }
ul, ol { margin-bottom: 20px; padding-left: 24px; }
li { margin-bottom: 10px; list-style-position: outside; }
ul li { list-style-type: disc; }
ol li { list-style-type: decimal; }
blockquote {
border-left: 4px solid var(--primary-cyan, #00f0ff);
background: rgba(255, 255, 255, 0.05);
padding: 12px 16px;
margin: 16px 0;
border-radius: 4px;
color: #bbb;
font-style: italic;
p { margin-bottom: 0; }
border-left: 5px solid var(--primary-cyan, #00f0ff);
background: rgba(255, 255, 255, 0.08);
padding: 16px 20px;
margin: 24px 0;
border-radius: 8px;
color: #ccc;
font-style: italic;
font-size: 17px;
p { margin-bottom: 0; }
}
a { color: var(--primary-cyan, #00f0ff); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.2s; }
@@ -306,47 +316,50 @@
bottom: 0;
left: 0;
right: 0;
background: rgba(10, 10, 10, 0.9);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
padding: 16px 24px;
padding-bottom: calc(16px + env(safe-area-inset-bottom));
background: rgba(10, 10, 10, 0.95); /* More opaque */
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
padding: 20px 32px; /* More padding */
padding-bottom: calc(20px + env(safe-area-inset-bottom));
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1px solid rgba(255,255,255,0.1);
border-top: 1px solid rgba(255,255,255,0.15);
z-index: 100;
box-shadow: 0 -10px 30px rgba(0,0,0,0.5);
.left-info {
display: flex;
flex-direction: column;
.price {
font-size: 24px;
font-size: 28px; /* Larger price */
font-weight: 800;
color: var(--primary-cyan, #00f0ff);
text-shadow: 0 0 10px rgba(0, 240, 255, 0.3);
}
.desc {
font-size: 12px;
color: #888;
font-size: 14px; /* Larger desc */
color: #999;
margin-top: 4px;
}
}
.action-btn {
margin: 0;
padding: 0 40px;
height: 56px;
line-height: 56px;
border-radius: 28px;
font-size: 18px;
font-weight: 700;
padding: 0 48px;
height: 64px; /* Taller button */
line-height: 64px;
border-radius: 32px;
font-size: 20px; /* Larger font */
font-weight: 800;
border: none;
&.active {
background: linear-gradient(90deg, #00f0ff, #00b96b);
color: #000;
box-shadow: 0 4px 15px rgba(0, 240, 255, 0.3);
box-shadow: 0 6px 20px rgba(0, 240, 255, 0.4);
&:active {
transform: scale(0.98);
@@ -354,8 +367,8 @@
}
&.disabled {
background: rgba(255,255,255,0.1);
color: #666;
background: rgba(255,255,255,0.15);
color: #777;
}
}
}

View File

@@ -22,8 +22,11 @@ const ActivityDetail = () => {
// Function to refresh data, can be used in useDidShow
const refreshData = () => {
if (id) {
if (id && id !== 'undefined' && id !== 'null' && !isNaN(Number(id))) {
fetchDetail()
} else {
setLoading(false)
setActivity(null)
}
}
@@ -88,8 +91,12 @@ const ActivityDetail = () => {
fetchDetail() // Refresh status
} catch (error: any) {
console.error(error)
const msg = error.response?.data?.error || error.message || '报名失败'
Taro.showToast({ title: msg, icon: 'none' })
// Request utility already handles error toasts
if (error?.statusCode === 400) {
// If likely already signed up, refresh to update UI
fetchDetail()
setShowSignupModal(false)
}
} finally {
setSubmitting(false)
}
@@ -150,14 +157,14 @@ const ActivityDetail = () => {
{/* Info Cards */}
<View className='info-grid'>
<View className='info-card time'>
<AtIcon value='clock' size='18' color='#00f0ff' />
<AtIcon value='clock' size='24' color='#00f0ff' />
<View className='info-text'>
<Text className='label'></Text>
<Text className='value'>{new Date(activity.start_time).toLocaleString()}</Text>
</View>
</View>
<View className='info-card location'>
<AtIcon value='map-pin' size='18' color='#bd00ff' />
<AtIcon value='map-pin' size='24' color='#bd00ff' />
<View className='info-text'>
<Text className='label'></Text>
<Text className='value'>{activity.location || '线上直播'}</Text>

View File

@@ -22,10 +22,10 @@ const ActivityList = () => {
try {
if (tab === 'all') {
const res = await getActivities()
setActivities(res.results || res.data || [])
setActivities(res.results || res.data || (Array.isArray(res) ? res : []))
} else {
const res = await getMySignups()
setMySignups(res.results || res.data || [])
setMySignups(res.results || res.data || (Array.isArray(res) ? res : []))
}
} catch (error) {
console.error(error)
@@ -68,7 +68,18 @@ const ActivityList = () => {
return list.map(item => {
// Handle API structure differences
// For 'mine' tab, item is the signup record. activity_info is the full activity object.
const activity = tab === 'mine' ? (item.activity_info || item.activity || item) : item
let activity = tab === 'mine' ? (item.activity_info || item.activity || item) : item
// Safety check if activity is just an ID (number)
if (typeof activity === 'number' || typeof activity === 'string') {
// In this case we can't render the card properly without the activity details
// Skip or render placeholder? Ideally we should have the object.
// If we just have ID, we can't show title/image etc.
// Let's create a placeholder object to avoid crash, but it won't show much info.
activity = { id: activity, title: '加载中...', start_time: new Date().toISOString() }
}
if (!activity || !activity.id) return null
return (
<View key={activity.id} className='activity-card' onClick={() => goDetail(activity.id)}>