feat(family,ui): Family.role 字段与 BottomSheet 底部抽屉组件
Family 接口加可选 role: '管理员' | '群主',SEED_DATA 各家庭填角色,addFamily/joinFamily 新建家庭默认 '群主'。新建 BottomSheet 通用底部抽屉组件(遮罩+圆角面板+handle+标题+关闭钮),用于智能设备页"切换家庭圈"弹层。
This commit is contained in:
parent
1f3c9c842a
commit
d6333beda9
|
|
@ -13,6 +13,7 @@ export interface Family {
|
||||||
caredLabel: string
|
caredLabel: string
|
||||||
address: string
|
address: string
|
||||||
deviceCount: number
|
deviceCount: number
|
||||||
|
role?: '管理员' | '群主' // 当前用户在家庭圈的角色,弹层显示用
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EmergencyContact {
|
export interface EmergencyContact {
|
||||||
|
|
@ -55,10 +56,10 @@ interface FamilyData {
|
||||||
|
|
||||||
const SEED_DATA: FamilyData = {
|
const SEED_DATA: FamilyData = {
|
||||||
families: [
|
families: [
|
||||||
{ id: '846443196293189', name: 'JollyPlace', memberCount: 6, caredCount: 1, caredLabel: 'Jay', address: '--', deviceCount: 24 },
|
{ id: '846443196293189', name: 'JollyPlace', memberCount: 6, caredCount: 1, caredLabel: 'Jay', address: '--', deviceCount: 24, role: '管理员' },
|
||||||
{ id: '735201884550361', name: '我的家庭圈', memberCount: 4, caredCount: 0, caredLabel: '--', address: '--', deviceCount: 1 },
|
{ id: '735201884550361', name: '我的家庭圈', memberCount: 4, caredCount: 0, caredLabel: '--', address: '--', deviceCount: 1, role: '群主' },
|
||||||
{ id: '628934071266852', name: '康乐之家', memberCount: 1, caredCount: 0, caredLabel: '--', address: '--', deviceCount: 21 },
|
{ id: '628934071266852', name: '康乐之家', memberCount: 1, caredCount: 0, caredLabel: '--', address: '--', deviceCount: 21, role: '群主' },
|
||||||
{ id: '519027468331740', name: '平安庭院', memberCount: 1, caredCount: 0, caredLabel: '--', address: '--', deviceCount: 0 }
|
{ id: '519027468331740', name: '平安庭院', memberCount: 1, caredCount: 0, caredLabel: '--', address: '--', deviceCount: 0, role: '群主' }
|
||||||
],
|
],
|
||||||
cared: [
|
cared: [
|
||||||
{
|
{
|
||||||
|
|
@ -137,7 +138,8 @@ export async function addFamily(name: string): Promise<Family> {
|
||||||
caredCount: 0,
|
caredCount: 0,
|
||||||
caredLabel: '--',
|
caredLabel: '--',
|
||||||
address: '--',
|
address: '--',
|
||||||
deviceCount: 0
|
deviceCount: 0,
|
||||||
|
role: '群主'
|
||||||
}
|
}
|
||||||
data.families = [...data.families, family]
|
data.families = [...data.families, family]
|
||||||
saveData(data)
|
saveData(data)
|
||||||
|
|
@ -155,7 +157,8 @@ export async function joinFamily(code: string): Promise<Family> {
|
||||||
caredCount: 0,
|
caredCount: 0,
|
||||||
caredLabel: '--',
|
caredLabel: '--',
|
||||||
address: '--',
|
address: '--',
|
||||||
deviceCount: 0
|
deviceCount: 0,
|
||||||
|
role: '群主'
|
||||||
}
|
}
|
||||||
data.families = [...data.families, family]
|
data.families = [...data.families, family]
|
||||||
saveData(data)
|
saveData(data)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
.mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: $color-mask;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: $color-bg-white;
|
||||||
|
border-radius: $radius-lg $radius-lg 0 0;
|
||||||
|
padding-bottom: env(safe-area-inset-bottom, 0);
|
||||||
|
z-index: 101;
|
||||||
|
max-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handle {
|
||||||
|
width: 80px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: $radius-pill;
|
||||||
|
background: $color-bg-disabled;
|
||||||
|
margin: 16px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: relative;
|
||||||
|
padding: 16px 32px 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 34px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $color-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
right: 24px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closeIcon {
|
||||||
|
font-size: 40px;
|
||||||
|
color: $color-text-secondary;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 32px 32px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { View, Text } from '@tarojs/components'
|
||||||
|
import type { ReactNode } from 'react'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
title?: string
|
||||||
|
onClose: () => void
|
||||||
|
children: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BottomSheet({ visible, title, onClose, children }: Props) {
|
||||||
|
if (!visible) return null
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View className={styles.mask} onClick={onClose} />
|
||||||
|
<View className={styles.panel}>
|
||||||
|
<View className={styles.handle} />
|
||||||
|
{title && (
|
||||||
|
<View className={styles.header}>
|
||||||
|
<Text className={styles.title}>{title}</Text>
|
||||||
|
<View className={styles.close} onClick={onClose}>
|
||||||
|
<Text className={styles.closeIcon}>×</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
<View className={styles.body}>{children}</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue