feat(ui): add verification badge to UserProfileHeader
Add verification status display with identity-based badge icons to the user profile header component. Also add identity and verification_status fields to UserDTO and UserDetailDTO types. - Add VerificationBadge component with icon display based on identity type - Support for student, teacher, staff, alumni, and external identity types - Add 'none' status to VerificationStatus type for unverified users
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
} from 'react-native';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import { spacing, fontSizes, borderRadius, useAppColors, type AppColors } from '../../theme';
|
||||
import { User } from '../../types';
|
||||
import { User, UserIdentity, VerificationStatus } from '../../types';
|
||||
import Text from '../common/Text';
|
||||
import Avatar from '../common/Avatar';
|
||||
import { ImageGallery } from '../common';
|
||||
@@ -281,7 +281,10 @@ const UserProfileHeader: React.FC<UserProfileHeaderProps> = ({
|
||||
|
||||
{/* 用户名 */}
|
||||
<View style={styles.nameSection}>
|
||||
<Text style={styles.nickname}>{user.nickname}</Text>
|
||||
<View style={styles.nicknameRow}>
|
||||
<Text style={styles.nickname}>{user.nickname}</Text>
|
||||
<VerificationBadge identity={user.identity} verificationStatus={user.verification_status} />
|
||||
</View>
|
||||
<Text style={styles.username}>@{user.username}</Text>
|
||||
</View>
|
||||
|
||||
@@ -477,11 +480,16 @@ function createUserProfileHeaderStyles(colors: AppColors) {
|
||||
nameSection: {
|
||||
marginBottom: spacing.sm,
|
||||
},
|
||||
nicknameRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: spacing.xs,
|
||||
marginBottom: 2,
|
||||
},
|
||||
nickname: {
|
||||
fontSize: fontSizes['2xl'],
|
||||
fontWeight: '800',
|
||||
color: colors.text.primary,
|
||||
marginBottom: 2,
|
||||
},
|
||||
username: {
|
||||
fontSize: fontSizes.md,
|
||||
@@ -564,5 +572,54 @@ function createUserProfileHeaderStyles(colors: AppColors) {
|
||||
|
||||
import { shadows } from '../../theme';
|
||||
|
||||
// ==================== VerificationBadge ====================
|
||||
|
||||
interface VerificationBadgeProps {
|
||||
identity?: UserIdentity;
|
||||
verificationStatus?: VerificationStatus;
|
||||
}
|
||||
|
||||
const IDENTITY_CONFIG: Record<
|
||||
UserIdentity,
|
||||
{ label: string; color: string; bg: string }
|
||||
> = {
|
||||
general: { label: '未认证', color: '#9CA3AF', bg: '#F3F4F6' },
|
||||
student: { label: '学生认证', color: '#10B981', bg: '#D1FAE5' },
|
||||
teacher: { label: '教师认证', color: '#3B82F6', bg: '#DBEAFE' },
|
||||
staff: { label: '职工认证', color: '#8B5CF6', bg: '#EDE9FE' },
|
||||
alumni: { label: '校友认证', color: '#F59E0B', bg: '#FEF3C7' },
|
||||
external: { label: '未认证', color: '#9CA3AF', bg: '#F3F4F6' },
|
||||
};
|
||||
|
||||
const VerificationBadge: React.FC<VerificationBadgeProps> = ({
|
||||
identity,
|
||||
verificationStatus,
|
||||
}) => {
|
||||
const colors = useAppColors();
|
||||
|
||||
// 默认值:未认证状态
|
||||
const effectiveIdentity = identity || 'general';
|
||||
const effectiveStatus = verificationStatus || 'none';
|
||||
|
||||
const isApproved = effectiveStatus === 'approved';
|
||||
// none 表示未认证,统一用 general 的未认证样式
|
||||
const displayIdentity = isApproved ? effectiveIdentity : 'general';
|
||||
const config = IDENTITY_CONFIG[displayIdentity] || IDENTITY_CONFIG.general;
|
||||
|
||||
return (
|
||||
<View style={{ width: 22, height: 22, justifyContent: 'center', alignItems: 'center' }}>
|
||||
{isApproved ? (
|
||||
<MaterialCommunityIcons name="check-decagram" size={22} color={config.color} />
|
||||
) : (
|
||||
<>
|
||||
<MaterialCommunityIcons name="decagram" size={22} color="#9CA3AF" />
|
||||
<MaterialCommunityIcons name="decagram-outline" size={22} color="#9CA3AF" style={{ position: 'absolute' }} />
|
||||
<Text style={{ position: 'absolute', fontSize: 11, fontWeight: '800', color: '#FFFFFF', marginTop: 1 }}>?</Text>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const MemoizedUserProfileHeader = React.memo(UserProfileHeader);
|
||||
export default MemoizedUserProfileHeader;
|
||||
|
||||
@@ -23,6 +23,8 @@ export interface UserDTO {
|
||||
created_at: string;
|
||||
is_following?: boolean;
|
||||
is_following_me?: boolean;
|
||||
identity?: UserIdentity;
|
||||
verification_status?: VerificationStatus;
|
||||
}
|
||||
|
||||
export interface UserDetailDTO {
|
||||
@@ -43,6 +45,8 @@ export interface UserDetailDTO {
|
||||
// 额外字段
|
||||
is_following?: boolean; // 当前用户是否关注了该用户
|
||||
is_following_me?: boolean; // 该用户是否关注了当前用户
|
||||
identity?: UserIdentity;
|
||||
verification_status?: VerificationStatus;
|
||||
}
|
||||
|
||||
// ==================== Post DTOs ====================
|
||||
@@ -858,7 +862,7 @@ export interface CreateVotePostRequest {
|
||||
|
||||
// ==================== Verification DTOs ====================
|
||||
|
||||
export type VerificationStatus = 'not_submitted' | 'pending' | 'approved' | 'rejected';
|
||||
export type VerificationStatus = 'not_submitted' | 'pending' | 'approved' | 'rejected' | 'none';
|
||||
export type UserIdentity = 'general' | 'student' | 'teacher' | 'staff' | 'alumni' | 'external';
|
||||
|
||||
export interface VerificationStatusDTO {
|
||||
|
||||
Reference in New Issue
Block a user