refactor(mp): 迁移剩余 8 特殊页面到统一组件库
- 首页/健康/我的/商城/消息 TabBar 页面使用 PageShell 替代手写容器 - 登录/法律条款/关怀模式设置页使用 PageShell 替代手写容器 - 各页面卡片统一使用 ContentCard 组件 - 清理页面 SCSS 中的 min-height/background/padding 样板代码 - 66 个小程序页面全部完成统一组件迁移
This commit is contained in:
@@ -2,9 +2,6 @@
|
|||||||
@import '../../styles/mixins.scss';
|
@import '../../styles/mixins.scss';
|
||||||
|
|
||||||
.health-page {
|
.health-page {
|
||||||
min-height: 100vh;
|
|
||||||
background: $bg;
|
|
||||||
padding: 20px 24px 100px;
|
|
||||||
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,10 +20,6 @@
|
|||||||
/* ─── 录入区 ─── */
|
/* ─── 录入区 ─── */
|
||||||
.input-section {
|
.input-section {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: $shadow-md;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group {
|
.input-group {
|
||||||
@@ -130,11 +123,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trend-empty {
|
.trend-empty {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 24px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.trend-empty-text {
|
.trend-empty-text {
|
||||||
@@ -143,10 +132,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trend-chart {
|
.trend-chart {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.trend-bars {
|
.trend-bars {
|
||||||
@@ -217,10 +203,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
@@ -266,11 +248,6 @@
|
|||||||
|
|
||||||
/* ─── 健康资讯入口 ─── */
|
/* ─── 健康资讯入口 ─── */
|
||||||
.article-entry {
|
.article-entry {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import Loading from '../../components/Loading';
|
|||||||
import ErrorState from '../../components/ErrorState';
|
import ErrorState from '../../components/ErrorState';
|
||||||
import GuestGuard from '../../components/GuestGuard';
|
import GuestGuard from '../../components/GuestGuard';
|
||||||
import SegmentTabs from '../../components/SegmentTabs';
|
import SegmentTabs from '../../components/SegmentTabs';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
|
import ContentCard from '@/components/ui/ContentCard';
|
||||||
import { useHealthData, VITAL_TABS, type VitalType } from './useHealthData';
|
import { useHealthData, VITAL_TABS, type VitalType } from './useHealthData';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
@@ -48,12 +50,12 @@ export default function Health() {
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<View className={`health-page ${modeClass}`}>
|
<PageShell padding="md" safeBottom={false} scroll={false} className={`health-page ${modeClass}`}>
|
||||||
<View className='health-header'>
|
<View className='health-header'>
|
||||||
<Text className='health-title'>健康数据</Text>
|
<Text className='health-title'>健康数据</Text>
|
||||||
</View>
|
</View>
|
||||||
<ErrorState onRetry={fetchData} />
|
<ErrorState onRetry={fetchData} />
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +164,7 @@ export default function Health() {
|
|||||||
const dayLabels = ['日', '一', '二', '三', '四', '五', '六'];
|
const dayLabels = ['日', '一', '二', '三', '四', '五', '六'];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`health-page ${modeClass}`}>
|
<PageShell padding="md" safeBottom={false} scroll={false} className={`health-page ${modeClass}`}>
|
||||||
<View className='health-header'>
|
<View className='health-header'>
|
||||||
<Text className='health-title'>健康数据</Text>
|
<Text className='health-title'>健康数据</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -199,7 +201,7 @@ export default function Health() {
|
|||||||
|
|
||||||
<SegmentTabs tabs={VITAL_TABS} activeKey={activeTab} onChange={handleTabChange} variant="pill" />
|
<SegmentTabs tabs={VITAL_TABS} activeKey={activeTab} onChange={handleTabChange} variant="pill" />
|
||||||
|
|
||||||
<View className='input-section'>
|
<ContentCard variant="elevated">
|
||||||
{activeTab === 'blood_pressure' && (
|
{activeTab === 'blood_pressure' && (
|
||||||
<View className='input-group'>
|
<View className='input-group'>
|
||||||
<Text className='input-label'>收缩压(高压)</Text>
|
<Text className='input-label'>收缩压(高压)</Text>
|
||||||
@@ -281,18 +283,18 @@ export default function Health() {
|
|||||||
<View className='save-btn' onClick={handleSave}>
|
<View className='save-btn' onClick={handleSave}>
|
||||||
<Text className='save-btn-text'>{saving ? '保存中...' : '保存'}</Text>
|
<Text className='save-btn-text'>{saving ? '保存中...' : '保存'}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
|
|
||||||
<View className='trend-section'>
|
<View className='trend-section'>
|
||||||
<Text className='section-title'>近 7 天趋势</Text>
|
<Text className='section-title'>近 7 天趋势</Text>
|
||||||
{trendLoading ? (
|
{trendLoading ? (
|
||||||
<Loading />
|
<Loading />
|
||||||
) : trendData.length === 0 ? (
|
) : trendData.length === 0 ? (
|
||||||
<View className='trend-empty'>
|
<ContentCard padding="md">
|
||||||
<Text className='trend-empty-text'>暂无趋势数据</Text>
|
<Text className='trend-empty-text'>暂无趋势数据</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
) : (
|
) : (
|
||||||
<View className='trend-chart'>
|
<ContentCard padding="md">
|
||||||
<View className='trend-bars'>
|
<View className='trend-bars'>
|
||||||
{getThresholdValue(activeTab, thresholds) && (() => {
|
{getThresholdValue(activeTab, thresholds) && (() => {
|
||||||
const tv = getThresholdValue(activeTab, thresholds)!;
|
const tv = getThresholdValue(activeTab, thresholds)!;
|
||||||
@@ -319,16 +321,15 @@ export default function Health() {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<ContentCard
|
||||||
className='article-entry'
|
onPress={() => Taro.navigateTo({ url: '/pages/article/index' })}
|
||||||
onClick={() => Taro.navigateTo({ url: '/pages/article/index' })}
|
|
||||||
>
|
>
|
||||||
<Text className='article-entry-text'>最新健康资讯 ›</Text>
|
<Text className='article-entry-text'>最新健康资讯 ›</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,6 @@
|
|||||||
═══════════════════════════════════════ */
|
═══════════════════════════════════════ */
|
||||||
|
|
||||||
.home-page {
|
.home-page {
|
||||||
min-height: 100vh;
|
|
||||||
background: $bg;
|
|
||||||
padding: 20px 24px 100px;
|
|
||||||
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,10 +66,6 @@
|
|||||||
|
|
||||||
/* ─── 今日体征进度 ─── */
|
/* ─── 今日体征进度 ─── */
|
||||||
.checkin-card {
|
.checkin-card {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
box-shadow: $shadow-md;
|
|
||||||
padding: 20px;
|
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -140,11 +133,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.vital-card {
|
.vital-card {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 14px 16px;
|
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
@@ -314,8 +302,6 @@
|
|||||||
═══════════════════════════════════════ */
|
═══════════════════════════════════════ */
|
||||||
|
|
||||||
.guest-page {
|
.guest-page {
|
||||||
min-height: 100vh;
|
|
||||||
background: $bg;
|
|
||||||
padding-bottom: calc(120px + env(safe-area-inset-bottom));
|
padding-bottom: calc(120px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,10 +379,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.guest-article-card {
|
.guest-article-card {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
@@ -449,10 +432,6 @@
|
|||||||
/* ─── 底部登录引导 ─── */
|
/* ─── 底部登录引导 ─── */
|
||||||
.guest-login-prompt {
|
.guest-login-prompt {
|
||||||
margin: 24px 24px 0;
|
margin: 24px 24px 0;
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: $shadow-md;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import { api } from '@/services/request';
|
|||||||
import type { Article } from '@/services/article';
|
import type { Article } from '@/services/article';
|
||||||
import ProgressRing from '../../components/ProgressRing';
|
import ProgressRing from '../../components/ProgressRing';
|
||||||
import Loading from '../../components/Loading';
|
import Loading from '../../components/Loading';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
|
import ContentCard from '@/components/ui/ContentCard';
|
||||||
import { useHomeData, type ReminderItem } from './useHomeData';
|
import { useHomeData, type ReminderItem } from './useHomeData';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
@@ -83,7 +85,7 @@ function GuestHome({ modeClass }: { modeClass: string }) {
|
|||||||
const slides = banners.length > 0 ? banners : FALLBACK_SLIDES;
|
const slides = banners.length > 0 ? banners : FALLBACK_SLIDES;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`guest-page ${modeClass}`}>
|
<PageShell padding="none" safeBottom={false} scroll={false} className={`guest-page ${modeClass}`}>
|
||||||
<Swiper
|
<Swiper
|
||||||
className='guest-swiper'
|
className='guest-swiper'
|
||||||
indicatorDots
|
indicatorDots
|
||||||
@@ -116,10 +118,11 @@ function GuestHome({ modeClass }: { modeClass: string }) {
|
|||||||
{articles.length > 0 ? (
|
{articles.length > 0 ? (
|
||||||
<View className='guest-articles'>
|
<View className='guest-articles'>
|
||||||
{articles.map((article) => (
|
{articles.map((article) => (
|
||||||
<View
|
<ContentCard
|
||||||
className='guest-article-card'
|
|
||||||
key={article.id}
|
key={article.id}
|
||||||
onClick={() => Taro.navigateTo({ url: `/pages/article/detail/index?id=${article.id}` })}
|
onPress={() => Taro.navigateTo({ url: `/pages/article/detail/index?id=${article.id}` })}
|
||||||
|
activeFeedback="opacity"
|
||||||
|
padding="none"
|
||||||
>
|
>
|
||||||
{article.cover_image && (
|
{article.cover_image && (
|
||||||
<Image className='guest-article-cover' src={article.cover_image} mode='aspectFill' />
|
<Image className='guest-article-cover' src={article.cover_image} mode='aspectFill' />
|
||||||
@@ -130,34 +133,40 @@ function GuestHome({ modeClass }: { modeClass: string }) {
|
|||||||
{article.summary || '点击查看详情'}
|
{article.summary || '点击查看详情'}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<View className='guest-articles'>
|
<View className='guest-articles'>
|
||||||
<View className='guest-article-card'>
|
<ContentCard padding="none">
|
||||||
<Text className='guest-article-title'>健康数据管理</Text>
|
<View className='guest-article-body'>
|
||||||
<Text className='guest-article-summary'>记录并追踪您的体征数据</Text>
|
<Text className='guest-article-title'>健康数据管理</Text>
|
||||||
</View>
|
<Text className='guest-article-summary'>记录并追踪您的体征数据</Text>
|
||||||
<View className='guest-article-card'>
|
</View>
|
||||||
<Text className='guest-article-title'>智能预约排班</Text>
|
</ContentCard>
|
||||||
<Text className='guest-article-summary'>在线预约透析和治疗</Text>
|
<ContentCard padding="none">
|
||||||
</View>
|
<View className='guest-article-body'>
|
||||||
<View className='guest-article-card'>
|
<Text className='guest-article-title'>智能预约排班</Text>
|
||||||
<Text className='guest-article-title'>AI 健康分析</Text>
|
<Text className='guest-article-summary'>在线预约透析和治疗</Text>
|
||||||
<Text className='guest-article-summary'>个性化健康趋势解读</Text>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
|
<ContentCard padding="none">
|
||||||
|
<View className='guest-article-body'>
|
||||||
|
<Text className='guest-article-title'>AI 健康分析</Text>
|
||||||
|
<Text className='guest-article-summary'>个性化健康趋势解读</Text>
|
||||||
|
</View>
|
||||||
|
</ContentCard>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className='guest-login-prompt'>
|
<ContentCard variant="elevated">
|
||||||
<Text className='guest-login-text'>登录后即可使用完整健康管理服务</Text>
|
<Text className='guest-login-text'>登录后即可使用完整健康管理服务</Text>
|
||||||
<View className='guest-login-btn' onClick={navigateToLogin}>
|
<View className='guest-login-btn' onClick={navigateToLogin}>
|
||||||
<Text className='guest-login-btn-text'>立即登录</Text>
|
<Text className='guest-login-btn-text'>立即登录</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +186,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`home-page ${modeClass}`}>
|
<PageShell padding="md" safeBottom={false} scroll={false} className={`home-page ${modeClass}`}>
|
||||||
<View className='greeting-section'>
|
<View className='greeting-section'>
|
||||||
<View className='greeting-left'>
|
<View className='greeting-left'>
|
||||||
<Text className='greeting-text'>{greeting},{displayName}</Text>
|
<Text className='greeting-text'>{greeting},{displayName}</Text>
|
||||||
@@ -191,7 +200,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className='checkin-card' onClick={() => Taro.switchTab({ url: '/pages/health/index' })}>
|
<ContentCard variant="elevated" onPress={() => Taro.switchTab({ url: '/pages/health/index' })}>
|
||||||
<View className='checkin-left'>
|
<View className='checkin-left'>
|
||||||
<ProgressRing percent={progressPercent} />
|
<ProgressRing percent={progressPercent} />
|
||||||
</View>
|
</View>
|
||||||
@@ -207,7 +216,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) {
|
|||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
|
|
||||||
<View className='vitals-section'>
|
<View className='vitals-section'>
|
||||||
<Text className='section-title'>今日体征</Text>
|
<Text className='section-title'>今日体征</Text>
|
||||||
@@ -218,10 +227,10 @@ function HomeDashboard({ modeClass }: { modeClass: string }) {
|
|||||||
{healthItems.map((item) => {
|
{healthItems.map((item) => {
|
||||||
const tag = getStatusTag(item.status);
|
const tag = getStatusTag(item.status);
|
||||||
return (
|
return (
|
||||||
<View
|
<ContentCard
|
||||||
className='vital-card'
|
|
||||||
key={item.label}
|
key={item.label}
|
||||||
onClick={() => Taro.navigateTo({ url: `/pages/pkg-health/trend/index?indicator=${item.indicator}` })}
|
onPress={() => Taro.navigateTo({ url: `/pages/pkg-health/trend/index?indicator=${item.indicator}` })}
|
||||||
|
activeFeedback="opacity"
|
||||||
>
|
>
|
||||||
<Text className='vital-label'>{item.label}</Text>
|
<Text className='vital-label'>{item.label}</Text>
|
||||||
<View className='vital-value-row'>
|
<View className='vital-value-row'>
|
||||||
@@ -232,7 +241,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) {
|
|||||||
{tag && <Text className={`vital-tag ${tag.cls}`}>{tag.label}</Text>}
|
{tag && <Text className={`vital-tag ${tag.cls}`}>{tag.label}</Text>}
|
||||||
{!item.status && <Text className='vital-tag tag-empty'>未记录</Text>}
|
{!item.status && <Text className='vital-tag tag-empty'>未记录</Text>}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
@@ -270,7 +279,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) {
|
|||||||
<Text className='action-btn-text'>预约挂号</Text>
|
<Text className='action-btn-text'>预约挂号</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
@import '../../styles/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.legal-page {
|
.legal-page {
|
||||||
min-height: 100vh;
|
|
||||||
background: $card;
|
background: $card;
|
||||||
padding: 32px 24px;
|
|
||||||
padding-bottom: 60px;
|
padding-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { View, Text, RichText } from '@tarojs/components';
|
import { View, Text, RichText } from '@tarojs/components';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
const PRIVACY_CONTENT = `
|
const PRIVACY_CONTENT = `
|
||||||
@@ -48,11 +49,11 @@ const PRIVACY_CONTENT = `
|
|||||||
|
|
||||||
export default function PrivacyPolicy() {
|
export default function PrivacyPolicy() {
|
||||||
return (
|
return (
|
||||||
<View className='legal-page'>
|
<PageShell className='legal-page' scroll={false}>
|
||||||
<RichText className='legal-content' nodes={PRIVACY_CONTENT} />
|
<RichText className='legal-content' nodes={PRIVACY_CONTENT} />
|
||||||
<View className='legal-footer'>
|
<View className='legal-footer'>
|
||||||
<Text className='legal-footer-text'>如有疑问,请联系客服</Text>
|
<Text className='legal-footer-text'>如有疑问,请联系客服</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { View, Text, RichText } from '@tarojs/components';
|
import { View, Text, RichText } from '@tarojs/components';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
const AGREEMENT_CONTENT = `
|
const AGREEMENT_CONTENT = `
|
||||||
@@ -34,11 +35,11 @@ const AGREEMENT_CONTENT = `
|
|||||||
|
|
||||||
export default function UserAgreement() {
|
export default function UserAgreement() {
|
||||||
return (
|
return (
|
||||||
<View className='legal-page'>
|
<PageShell className='legal-page' scroll={false}>
|
||||||
<RichText className='legal-content' nodes={AGREEMENT_CONTENT} />
|
<RichText className='legal-content' nodes={AGREEMENT_CONTENT} />
|
||||||
<View className='legal-footer'>
|
<View className='legal-footer'>
|
||||||
<Text className='legal-footer-text'>如有疑问,请联系客服</Text>
|
<Text className='legal-footer-text'>如有疑问,请联系客服</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
@import '../../styles/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
@import '../../styles/mixins.scss';
|
@import '../../styles/mixins.scss';
|
||||||
|
|
||||||
.login-scroll {
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-page {
|
.login-page {
|
||||||
min-height: 100vh;
|
// PageShell 接管 min-height, background, scroll
|
||||||
background: $bg;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { View, Text, Button, ScrollView } from '@tarojs/components';
|
import { View, Text, Button } from '@tarojs/components';
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { useAuthStore } from '../../stores/auth';
|
import { useAuthStore } from '../../stores/auth';
|
||||||
import { useElderClass } from '../../hooks/useElderClass';
|
import { useElderClass } from '../../hooks/useElderClass';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
const IS_DEV = process.env.NODE_ENV !== 'production';
|
const IS_DEV = process.env.NODE_ENV !== 'production';
|
||||||
@@ -95,8 +96,7 @@ export default function Login() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView scrollY className={`login-scroll ${loginClass}`}>
|
<PageShell padding="none" scroll className={`login-page ${loginClass}`}>
|
||||||
<View className='login-page'>
|
|
||||||
{/* 品牌区 */}
|
{/* 品牌区 */}
|
||||||
<View className='login-brand'>
|
<View className='login-brand'>
|
||||||
<View className='login-logo'>
|
<View className='login-logo'>
|
||||||
@@ -155,7 +155,6 @@ export default function Login() {
|
|||||||
暂不登录,先看看
|
暂不登录,先看看
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</PageShell>
|
||||||
</ScrollView>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
@import '../../styles/mixins.scss';
|
@import '../../styles/mixins.scss';
|
||||||
|
|
||||||
.mall-page {
|
.mall-page {
|
||||||
min-height: 100vh;
|
|
||||||
background: $bg;
|
|
||||||
padding-bottom: calc(120px + env(safe-area-inset-bottom));
|
padding-bottom: calc(120px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,10 +119,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.product-card {
|
.product-card {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import Loading from '../../components/Loading';
|
|||||||
import ErrorState from '../../components/ErrorState';
|
import ErrorState from '../../components/ErrorState';
|
||||||
import EmptyState from '../../components/EmptyState';
|
import EmptyState from '../../components/EmptyState';
|
||||||
import { useElderClass } from '../../hooks/useElderClass';
|
import { useElderClass } from '../../hooks/useElderClass';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
|
import ContentCard from '@/components/ui/ContentCard';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
const PRODUCT_TYPE_TABS = [
|
const PRODUCT_TYPE_TABS = [
|
||||||
@@ -137,7 +139,7 @@ export default function Mall() {
|
|||||||
|
|
||||||
if (noProfile) {
|
if (noProfile) {
|
||||||
return (
|
return (
|
||||||
<View className={`mall-page ${modeClass}`}>
|
<PageShell padding="md" safeBottom={false} scroll={false} className={`mall-page ${modeClass}`}>
|
||||||
<EmptyState
|
<EmptyState
|
||||||
icon='档'
|
icon='档'
|
||||||
text='请先完善个人档案'
|
text='请先完善个人档案'
|
||||||
@@ -145,12 +147,12 @@ export default function Mall() {
|
|||||||
actionText='去建档'
|
actionText='去建档'
|
||||||
onAction={() => Taro.navigateTo({ url: '/pages/pkg-profile/family-add/index' })}
|
onAction={() => Taro.navigateTo({ url: '/pages/pkg-profile/family-add/index' })}
|
||||||
/>
|
/>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`mall-page ${modeClass}`}>
|
<PageShell padding="none" safeBottom={false} scroll={false} className={`mall-page ${modeClass}`}>
|
||||||
{/* 积分余额卡片 */}
|
{/* 积分余额卡片 */}
|
||||||
<View className='mall-header'>
|
<View className='mall-header'>
|
||||||
<View className='points-card'>
|
<View className='points-card'>
|
||||||
@@ -197,7 +199,7 @@ export default function Mall() {
|
|||||||
) : (
|
) : (
|
||||||
<View className='product-grid'>
|
<View className='product-grid'>
|
||||||
{products.map((item) => (
|
{products.map((item) => (
|
||||||
<View className='product-card' key={item.id} onClick={() => handleProductClick(item)}>
|
<ContentCard key={item.id} onPress={() => handleProductClick(item)} activeFeedback="opacity" padding="none">
|
||||||
<View className={`product-image ${TYPE_BG[item.product_type] || ''}`}>
|
<View className={`product-image ${TYPE_BG[item.product_type] || ''}`}>
|
||||||
<Text className='product-image-char'>
|
<Text className='product-image-char'>
|
||||||
{item.product_type === 'physical' ? '物' : item.product_type === 'service' ? '券' : '权'}
|
{item.product_type === 'physical' ? '物' : item.product_type === 'service' ? '券' : '权'}
|
||||||
@@ -217,7 +219,7 @@ export default function Mall() {
|
|||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
))}
|
))}
|
||||||
{loading && <Loading />}
|
{loading && <Loading />}
|
||||||
{!loading && products.length >= total && total > 0 && (
|
{!loading && products.length >= total && total > 0 && (
|
||||||
@@ -225,6 +227,6 @@ export default function Mall() {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
@import '../../styles/mixins.scss';
|
@import '../../styles/mixins.scss';
|
||||||
|
|
||||||
.messages-page {
|
.messages-page {
|
||||||
min-height: 100vh;
|
// PageShell 接管 min-height, background
|
||||||
background: $bg;
|
|
||||||
padding: 20px 24px 100px;
|
padding: 20px 24px 100px;
|
||||||
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
@@ -91,14 +90,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: $card;
|
// ContentCard 接管 background, border-radius, padding, box-shadow, active feedback
|
||||||
border-radius: $r;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.85;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.consult-card-muted {
|
.consult-card-muted {
|
||||||
@@ -188,10 +180,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
background: $card;
|
// ContentCard 接管 background, border-radius, padding, box-shadow
|
||||||
border-radius: $r;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.notify-card-muted {
|
.notify-card-muted {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import GuestGuard from '../../components/GuestGuard';
|
|||||||
import { useAuthStore } from '../../stores/auth';
|
import { useAuthStore } from '../../stores/auth';
|
||||||
import { useElderClass } from '../../hooks/useElderClass';
|
import { useElderClass } from '../../hooks/useElderClass';
|
||||||
import { usePageData } from '@/hooks/usePageData';
|
import { usePageData } from '@/hooks/usePageData';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
|
import ContentCard from '@/components/ui/ContentCard';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
type MsgTab = 'consultation' | 'notification';
|
type MsgTab = 'consultation' | 'notification';
|
||||||
@@ -116,7 +118,7 @@ export default function Messages() {
|
|||||||
const unreadConsultCount = sessions.filter((s) => s.unread_count_patient > 0).length;
|
const unreadConsultCount = sessions.filter((s) => s.unread_count_patient > 0).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`messages-page ${modeClass}`}>
|
<PageShell safeBottom={false} scroll={false} className={`messages-page ${modeClass}`}>
|
||||||
{/* 页头 */}
|
{/* 页头 */}
|
||||||
<View className='messages-header'>
|
<View className='messages-header'>
|
||||||
<Text className='messages-title'>消息</Text>
|
<Text className='messages-title'>消息</Text>
|
||||||
@@ -160,10 +162,11 @@ export default function Messages() {
|
|||||||
const doctorName = session.last_message?.slice(0, 1) || '医';
|
const doctorName = session.last_message?.slice(0, 1) || '医';
|
||||||
const hasUnread = session.unread_count_patient > 0;
|
const hasUnread = session.unread_count_patient > 0;
|
||||||
return (
|
return (
|
||||||
<View
|
<ContentCard
|
||||||
key={session.id}
|
key={session.id}
|
||||||
|
onPress={() => Taro.navigateTo({ url: `/pages/pkg-consultation/detail/index?id=${session.id}` })}
|
||||||
|
padding="sm"
|
||||||
className={`consult-card ${hasUnread ? '' : 'consult-card-muted'}`}
|
className={`consult-card ${hasUnread ? '' : 'consult-card-muted'}`}
|
||||||
onClick={() => Taro.navigateTo({ url: `/pages/pkg-consultation/detail/index?id=${session.id}` })}
|
|
||||||
>
|
>
|
||||||
<View className={`consult-avatar ${hasUnread ? 'consult-avatar-active' : ''}`}>
|
<View className={`consult-avatar ${hasUnread ? 'consult-avatar-active' : ''}`}>
|
||||||
<Text className='consult-avatar-char'>{doctorName}</Text>
|
<Text className='consult-avatar-char'>{doctorName}</Text>
|
||||||
@@ -188,7 +191,7 @@ export default function Messages() {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
@@ -207,7 +210,7 @@ export default function Messages() {
|
|||||||
const cfg = NOTIFY_ICONS[n.type] || NOTIFY_ICONS.report;
|
const cfg = NOTIFY_ICONS[n.type] || NOTIFY_ICONS.report;
|
||||||
const isUnread = !n.read;
|
const isUnread = !n.read;
|
||||||
return (
|
return (
|
||||||
<View key={n.id} className={`notify-card ${isUnread ? '' : 'notify-card-muted'}`}>
|
<ContentCard key={n.id} padding="sm" activeFeedback="none" className={`notify-card ${isUnread ? '' : 'notify-card-muted'}`}>
|
||||||
<View className={`notify-icon ${cfg.cls}`}>
|
<View className={`notify-icon ${cfg.cls}`}>
|
||||||
<Text className={`notify-icon-char ${cfg.cls}`}>{cfg.icon}</Text>
|
<Text className={`notify-icon-char ${cfg.cls}`}>{cfg.icon}</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -219,7 +222,7 @@ export default function Messages() {
|
|||||||
<Text className='notify-desc'>{n.desc}</Text>
|
<Text className='notify-desc'>{n.desc}</Text>
|
||||||
</View>
|
</View>
|
||||||
{isUnread && <View className='notify-dot' />}
|
{isUnread && <View className='notify-dot' />}
|
||||||
</View>
|
</ContentCard>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
@@ -228,6 +231,6 @@ export default function Messages() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,11 @@
|
|||||||
@import '../../../styles/mixins.scss';
|
@import '../../../styles/mixins.scss';
|
||||||
|
|
||||||
.elder-mode-page {
|
.elder-mode-page {
|
||||||
min-height: 100vh;
|
// PageShell 接管 min-height, background, padding
|
||||||
background: $bg;
|
|
||||||
padding: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.elder-mode-card {
|
.elder-mode-card {
|
||||||
background: $card;
|
// ContentCard 接管 background, border-radius, padding, box-shadow, margin-bottom
|
||||||
border-radius: $r;
|
|
||||||
padding: 24px;
|
|
||||||
box-shadow: $shadow-md;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.elder-mode-header {
|
.elder-mode-header {
|
||||||
@@ -108,10 +102,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.elder-mode-preview-card {
|
.elder-mode-preview-card {
|
||||||
background: $card;
|
// ContentCard 接管 background, border-radius, padding, box-shadow
|
||||||
border-radius: $r;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.elder-mode-preview-sample {
|
.elder-mode-preview-sample {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { View, Text } from '@tarojs/components';
|
|||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import { useUIStore } from '../../../stores/ui';
|
import { useUIStore } from '../../../stores/ui';
|
||||||
import { useElderClass } from '../../../hooks/useElderClass';
|
import { useElderClass } from '../../../hooks/useElderClass';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
|
import ContentCard from '@/components/ui/ContentCard';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
export default function ElderMode() {
|
export default function ElderMode() {
|
||||||
@@ -21,8 +23,8 @@ export default function ElderMode() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`elder-mode-page ${modeClass}`}>
|
<PageShell className={`elder-mode-page ${modeClass}`}>
|
||||||
<View className='elder-mode-card'>
|
<ContentCard variant="elevated" className='elder-mode-card'>
|
||||||
<View className='elder-mode-header'>
|
<View className='elder-mode-header'>
|
||||||
<Text className='elder-mode-icon'>老</Text>
|
<Text className='elder-mode-icon'>老</Text>
|
||||||
<View className='elder-mode-info'>
|
<View className='elder-mode-info'>
|
||||||
@@ -42,19 +44,19 @@ export default function ElderMode() {
|
|||||||
<View className='elder-mode-switch-thumb' />
|
<View className='elder-mode-switch-thumb' />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</ContentCard>
|
||||||
|
|
||||||
<View className='elder-mode-preview'>
|
<View className='elder-mode-preview'>
|
||||||
<Text className='elder-mode-preview-title'>效果预览</Text>
|
<Text className='elder-mode-preview-title'>效果预览</Text>
|
||||||
<View className='elder-mode-preview-card'>
|
<ContentCard padding="lg" className='elder-mode-preview-card'>
|
||||||
<Text className={`elder-mode-preview-sample ${isElder ? 'elder-mode-preview-sample--large' : ''}`}>
|
<Text className={`elder-mode-preview-sample ${isElder ? 'elder-mode-preview-sample--large' : ''}`}>
|
||||||
{isElder ? '长辈模式字体示例' : '标准模式字体示例'}
|
{isElder ? '长辈模式字体示例' : '标准模式字体示例'}
|
||||||
</Text>
|
</Text>
|
||||||
<Text className='elder-mode-preview-note'>
|
<Text className='elder-mode-preview-note'>
|
||||||
{isElder ? '字号放大 1.3 倍,间距放大 1.2 倍' : '正常字号和间距'}
|
{isElder ? '字号放大 1.3 倍,间距放大 1.2 倍' : '正常字号和间距'}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,14 @@
|
|||||||
@import '../../styles/mixins.scss';
|
@import '../../styles/mixins.scss';
|
||||||
|
|
||||||
.profile-page {
|
.profile-page {
|
||||||
min-height: 100vh;
|
|
||||||
background: $bg;
|
|
||||||
padding: 20px 24px 100px;
|
|
||||||
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
padding-bottom: calc(100px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ─── 用户信息卡片 ─── */
|
/* ─── 用户信息卡片 ─── */
|
||||||
.profile-user-card {
|
.profile-user-card {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
box-shadow: $shadow-md;
|
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,11 +63,7 @@
|
|||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
padding: 16px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
@@ -118,10 +107,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-group-card {
|
.menu-group-card {
|
||||||
background: $card;
|
|
||||||
border-radius: $r;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: $shadow-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import { useUIStore } from '../../stores/ui';
|
|||||||
import { navigateToLogin } from '../../utils/navigate';
|
import { navigateToLogin } from '../../utils/navigate';
|
||||||
import { usePageData } from '@/hooks/usePageData';
|
import { usePageData } from '@/hooks/usePageData';
|
||||||
import Loading from '../../components/Loading';
|
import Loading from '../../components/Loading';
|
||||||
|
import PageShell from '@/components/ui/PageShell';
|
||||||
|
import ContentCard from '@/components/ui/ContentCard';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
interface MenuItem {
|
interface MenuItem {
|
||||||
@@ -123,10 +125,10 @@ export default function Profile() {
|
|||||||
const displayInitial = (user?.display_name || user?.username || '用').charAt(0);
|
const displayInitial = (user?.display_name || user?.username || '用').charAt(0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={`profile-page ${modeClass}`}>
|
<PageShell padding="md" safeBottom={false} scroll={false} className={`profile-page ${modeClass}`}>
|
||||||
{/* 用户信息卡片 */}
|
{/* 用户信息卡片 */}
|
||||||
{isGuest ? (
|
{isGuest ? (
|
||||||
<View className='profile-user-card' onClick={navigateToLogin}>
|
<ContentCard variant="elevated" onPress={navigateToLogin}>
|
||||||
<View className='profile-avatar profile-avatar--guest'>
|
<View className='profile-avatar profile-avatar--guest'>
|
||||||
<Text className='profile-avatar-char'>?</Text>
|
<Text className='profile-avatar-char'>?</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -135,10 +137,10 @@ export default function Profile() {
|
|||||||
<Text className='profile-phone'>点击登录,开启健康管理之旅</Text>
|
<Text className='profile-phone'>点击登录,开启健康管理之旅</Text>
|
||||||
</View>
|
</View>
|
||||||
<Text className='profile-arrow'>›</Text>
|
<Text className='profile-arrow'>›</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<View className='profile-user-card'>
|
<ContentCard variant="elevated">
|
||||||
<View className='profile-avatar'>
|
<View className='profile-avatar'>
|
||||||
<Text className='profile-avatar-char'>{displayInitial}</Text>
|
<Text className='profile-avatar-char'>{displayInitial}</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -149,21 +151,21 @@ export default function Profile() {
|
|||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<Text className='profile-arrow'>›</Text>
|
<Text className='profile-arrow'>›</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
|
|
||||||
{/* 积分 + 打卡 */}
|
{/* 积分 + 打卡 */}
|
||||||
{pointsLoading ? (
|
{pointsLoading ? (
|
||||||
<Loading />
|
<Loading />
|
||||||
) : (
|
) : (
|
||||||
<View className='profile-stats-row'>
|
<View className='profile-stats-row'>
|
||||||
<View className='stat-card'>
|
<ContentCard padding="sm">
|
||||||
<Text className='stat-value stat-pri'>{(pointsAccount?.balance ?? 0).toLocaleString()}</Text>
|
<Text className='stat-value stat-pri'>{(pointsAccount?.balance ?? 0).toLocaleString()}</Text>
|
||||||
<Text className='stat-label'>健康积分</Text>
|
<Text className='stat-label'>健康积分</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
<View className='stat-card'>
|
<ContentCard padding="sm">
|
||||||
<Text className='stat-value stat-acc'>{checkinInfo?.consecutive_days ?? 0}<Text className='stat-unit'>天</Text></Text>
|
<Text className='stat-value stat-acc'>{checkinInfo?.consecutive_days ?? 0}<Text className='stat-unit'>天</Text></Text>
|
||||||
<Text className='stat-label'>连续打卡</Text>
|
<Text className='stat-label'>连续打卡</Text>
|
||||||
</View>
|
</ContentCard>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@@ -173,7 +175,7 @@ export default function Profile() {
|
|||||||
{groups.map((group) => (
|
{groups.map((group) => (
|
||||||
<View className='menu-group' key={group.title}>
|
<View className='menu-group' key={group.title}>
|
||||||
<Text className='menu-group-title'>{group.title}</Text>
|
<Text className='menu-group-title'>{group.title}</Text>
|
||||||
<View className='menu-group-card'>
|
<ContentCard padding="none">
|
||||||
{group.items.map((item, idx) => (
|
{group.items.map((item, idx) => (
|
||||||
<View
|
<View
|
||||||
className='menu-item'
|
className='menu-item'
|
||||||
@@ -188,7 +190,7 @@ export default function Profile() {
|
|||||||
<Text className='menu-arrow'>›</Text>
|
<Text className='menu-arrow'>›</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</ContentCard>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
@@ -202,6 +204,6 @@ export default function Profile() {
|
|||||||
<Text className='logout-text'>退出登录</Text>
|
<Text className='logout-text'>退出登录</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</PageShell>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user