feat(home): 首页卡片视觉细化——渐变横幅、状态色块、信息层级

This commit is contained in:
ozh 2026-09-09 11:43:14 +08:00
parent 240c235921
commit e2d7232f3c
2 changed files with 138 additions and 74 deletions

View File

@ -4,6 +4,7 @@
padding-bottom: 40px; padding-bottom: 40px;
} }
// loading 分支与空态分支共用(error 分支已由 StateView 自带 margin)
.stateWrap { .stateWrap {
margin-top: 80px; margin-top: 80px;
display: flex; display: flex;
@ -11,106 +12,149 @@
align-items: center; align-items: center;
} }
// ===== 家庭圈入口 ===== // ===== 家庭圈入口:渐变横幅卡 =====
.familyEntry { .familyEntry {
margin: 24px; margin: 24px;
padding-left: 48px; padding: 36px 32px;
background: $color-primary-grad;
border-radius: $radius-lg;
// 品牌绿阴影(spec §5.1 允许的字面量)
box-shadow: 0 4px 12px rgba(44, 203, 152, 0.3);
display: flex;
align-items: center;
justify-content: space-between;
}
.familyTexts {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center;
} }
.familyIcon { .familyTitle {
width: 108px; font-size: 32px;
height: 108px; font-weight: 700;
border-radius: $radius-circle; color: #ffffff;
background: $color-primary-grad;
display: flex;
align-items: center;
justify-content: center;
} }
.familyEmoji { .familySub {
font-size: 56px; margin-top: 8px;
line-height: 1; font-size: 24px;
color: rgba(255, 255, 255, 0.85);
} }
.familyText { .familyArrow {
margin-top: 12px; font-size: 36px;
font-size: 28px; color: rgba(255, 255, 255, 0.85);
color: $color-text;
} }
// ===== 未处理告警卡片 ===== // ===== 未处理告警卡:左红色块 + 文字块 + 右上圆角标签 =====
.unhandledCard { .unhandledCard {
position: relative;
margin: 0 24px 24px; margin: 0 24px 24px;
padding: 32px; padding: 28px;
background: $color-bg-white; background: $color-bg-white;
border-radius: $radius-lg; border-radius: $radius-lg;
box-shadow: $shadow-card; box-shadow: $shadow-card;
} }
.unhandledTag { .unhandledHead {
position: absolute;
top: -16px;
left: -8px;
padding: 6px 18px;
background: $color-danger-light-bg;
color: $color-danger-deep;
border: 2px solid $color-danger-deep;
border-radius: $radius-sm;
font-size: 22px;
transform: rotate(-4deg);
box-shadow: 0 2px 8px rgba(213, 59, 29, 0.15);
}
.unhandledTitle {
font-size: 32px;
font-weight: 600;
color: $color-text;
}
.unhandledRow {
margin-top: 16px;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.rowLabel { .unhandledIcon {
font-size: 28px; flex-shrink: 0;
color: $color-text-secondary; width: 72px;
height: 72px;
border-radius: $radius-md;
background: $color-danger-light-bg;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
} }
.rowValue { .unhandledIconText {
font-size: 28px; font-size: 36px;
font-weight: 700;
color: $color-danger-deep;
}
.unhandledTitle {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 30px;
font-weight: 600;
color: $color-text; color: $color-text;
} }
// ===== 告警消息列表 ===== .unhandledTag {
flex-shrink: 0;
margin-left: 16px;
padding: 4px 16px;
background: $color-danger-light-bg;
border-radius: $radius-pill;
}
.unhandledTagText {
font-size: 22px;
color: $color-danger-deep;
}
// 元信息与标题文字左对齐:72 图标 + 20 间距
.unhandledMeta {
margin-top: 12px;
padding-left: 92px;
}
.unhandledMetaText {
font-size: 26px;
color: $color-text-secondary;
}
// ===== 告警消息列表:左绿色块 + 标题/时间 + 设备名副行 =====
.messageList { .messageList {
padding: 0 24px; padding: 0 24px;
} }
.messageCard { .messageCard {
margin-bottom: 24px; margin-bottom: 24px;
padding: 32px; padding: 28px;
background: $color-bg-white; background: $color-bg-white;
border-radius: $radius-lg; border-radius: $radius-lg;
box-shadow: $shadow-card; box-shadow: $shadow-card;
display: flex;
align-items: flex-start;
}
.messageIcon {
flex-shrink: 0;
width: 72px;
height: 72px;
border-radius: $radius-md;
background: $color-primary-light-bg;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
}
.messageIconText {
font-size: 22px;
color: $color-primary;
}
.messageBody {
flex: 1;
min-width: 0;
} }
.messageHead { .messageHead {
display: flex; display: flex;
align-items: center; align-items: center;
} justify-content: space-between;
.messageDot {
width: 16px;
height: 16px;
border-radius: $radius-circle;
background: $color-danger-deep;
margin-right: 12px;
} }
.messageTitle { .messageTitle {
@ -120,7 +164,14 @@
} }
.messageTime { .messageTime {
margin-top: 12px; margin-left: 16px;
font-size: 24px; font-size: 24px;
color: $color-text-secondary; color: $color-text-secondary;
} }
.messageDevice {
display: block;
margin-top: 10px;
font-size: 26px;
color: $color-text-secondary;
}

View File

@ -78,10 +78,11 @@ export default function Index() {
function FamilyEntry({ onClick }: { onClick: () => void }) { function FamilyEntry({ onClick }: { onClick: () => void }) {
return ( return (
<View className={styles.familyEntry} onClick={onClick}> <View className={styles.familyEntry} onClick={onClick}>
<View className={styles.familyIcon}> <View className={styles.familyTexts}>
<Text className={styles.familyEmoji}>👨‍👩‍👧</Text> <Text className={styles.familyTitle}>家庭圈</Text>
<Text className={styles.familySub}>家人共享 · 守护彼此</Text>
</View> </View>
<Text className={styles.familyText}>家庭圈</Text> <Text className={styles.familyArrow}>›</Text>
</View> </View>
) )
} }
@ -89,18 +90,23 @@ function FamilyEntry({ onClick }: { onClick: () => void }) {
function UnhandledAlert({ alert, onClick }: { alert: EventItem; onClick: () => void }) { function UnhandledAlert({ alert, onClick }: { alert: EventItem; onClick: () => void }) {
return ( return (
<View className={styles.unhandledCard} onClick={onClick}> <View className={styles.unhandledCard} onClick={onClick}>
<View className={styles.unhandledTag}><Text>未处理</Text></View> <View className={styles.unhandledHead}>
<View className={styles.unhandledIcon}>
<Text className={styles.unhandledIconText}>!</Text>
</View>
<Text className={styles.unhandledTitle}>{alert.deviceName || '未知设备'}</Text> <Text className={styles.unhandledTitle}>{alert.deviceName || '未知设备'}</Text>
<View className={styles.unhandledTag}>
<Text className={styles.unhandledTagText}>未处理</Text>
</View>
</View>
{alert.sceneName && ( {alert.sceneName && (
<View className={styles.unhandledRow}> <View className={styles.unhandledMeta}>
<Text className={styles.rowLabel}>家庭圈:</Text> <Text className={styles.unhandledMetaText}>{alert.sceneName}</Text>
<Text className={styles.rowValue}>{alert.sceneName}</Text>
</View> </View>
)} )}
{alert.time && ( {alert.time && (
<View className={styles.unhandledRow}> <View className={styles.unhandledMeta}>
<Text className={styles.rowLabel}>时间:</Text> <Text className={styles.unhandledMetaText}>{alert.time}</Text>
<Text className={styles.rowValue}>{alert.time}</Text>
</View> </View>
)} )}
</View> </View>
@ -110,11 +116,18 @@ function UnhandledAlert({ alert, onClick }: { alert: EventItem; onClick: () => v
function AlertMessageItem({ alert, onClick }: { alert: EventItem; onClick: () => void }) { function AlertMessageItem({ alert, onClick }: { alert: EventItem; onClick: () => void }) {
return ( return (
<View className={styles.messageCard} onClick={onClick}> <View className={styles.messageCard} onClick={onClick}>
<View className={styles.messageHead}> <View className={styles.messageIcon}>
<View className={styles.messageDot} /> <Text className={styles.messageIconText}>●</Text>
<Text className={styles.messageTitle}>告警消息</Text>
</View> </View>
<View className={styles.messageBody}>
<View className={styles.messageHead}>
<Text className={styles.messageTitle}>告警消息</Text>
{alert.time && <Text className={styles.messageTime}>{alert.time}</Text>} {alert.time && <Text className={styles.messageTime}>{alert.time}</Text>}
</View> </View>
{alert.deviceName && (
<Text className={styles.messageDevice}>{alert.deviceName}</Text>
)}
</View>
</View>
) )
} }