feat(ui): add verification badge to UserProfileHeader
Some checks failed
Frontend CI / build-and-push-web (push) Has been cancelled
Frontend CI / ota-android (push) Has been cancelled
Frontend CI / build-android-apk (push) Has been cancelled

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:
lafay
2026-04-26 19:51:26 +08:00
parent 6cbd2092ac
commit 1989cc8519
2 changed files with 65 additions and 4 deletions

View File

@@ -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;

View File

@@ -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 {