Initial frontend repository commit.
Include app source and update .gitignore to exclude local release artifacts and signing files. Made-with: Cursor
This commit is contained in:
155
src/screens/message/components/GroupRequestShared.tsx
Normal file
155
src/screens/message/components/GroupRequestShared.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
import React from 'react';
|
||||
import { View, StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
|
||||
import { Avatar, Text } from '../../../components/common';
|
||||
import { colors, spacing, borderRadius, shadows } from '../../../theme';
|
||||
|
||||
interface GroupInfoSummaryCardProps {
|
||||
groupName?: string;
|
||||
groupAvatar?: string;
|
||||
groupNo?: string;
|
||||
groupDescription?: string;
|
||||
memberCountText?: string;
|
||||
}
|
||||
|
||||
export const GroupInfoSummaryCard: React.FC<GroupInfoSummaryCardProps> = ({
|
||||
groupName,
|
||||
groupAvatar,
|
||||
groupNo,
|
||||
groupDescription,
|
||||
memberCountText,
|
||||
}) => {
|
||||
return (
|
||||
<View style={styles.headerCard}>
|
||||
<View style={styles.groupHeader}>
|
||||
<Avatar source={groupAvatar || ''} size={88} name={groupName} />
|
||||
<View style={styles.groupInfo}>
|
||||
<Text variant="h3" style={styles.groupName} numberOfLines={1}>{groupName || '群聊'}</Text>
|
||||
<View style={styles.groupMeta}>
|
||||
<MaterialCommunityIcons name="account-group" size={16} color={colors.text.secondary} />
|
||||
<Text variant="caption" color={colors.text.secondary}>
|
||||
{memberCountText || '- 人'}
|
||||
</Text>
|
||||
</View>
|
||||
<Text variant="caption" color={colors.text.secondary} style={styles.groupNoText}>
|
||||
群号:{groupNo || '-'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.descriptionContainer}>
|
||||
<MaterialCommunityIcons name="information-outline" size={16} color={colors.text.secondary} />
|
||||
<Text variant="body" color={colors.text.secondary} style={styles.groupDesc}>
|
||||
{groupDescription || '暂无群描述'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
interface DecisionFooterProps {
|
||||
canAction: boolean;
|
||||
submitting: boolean;
|
||||
onReject: () => void;
|
||||
onApprove: () => void;
|
||||
processedText?: string;
|
||||
}
|
||||
|
||||
export const DecisionFooter: React.FC<DecisionFooterProps> = ({
|
||||
canAction,
|
||||
submitting,
|
||||
onReject,
|
||||
onApprove,
|
||||
processedText = '该请求已处理',
|
||||
}) => {
|
||||
const insets = useSafeAreaInsets();
|
||||
if (canAction) {
|
||||
return (
|
||||
<View style={[styles.footer, { paddingBottom: Math.max(insets.bottom, spacing.sm) }]}>
|
||||
<TouchableOpacity style={[styles.btn, styles.reject]} onPress={onReject} disabled={submitting}>
|
||||
<Text variant="body" color={colors.error.main}>拒绝</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.btn, styles.approve]} onPress={onApprove} disabled={submitting}>
|
||||
{submitting ? <ActivityIndicator color="#fff" /> : <Text variant="body" color="#fff">同意</Text>}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={[styles.statusBox, { paddingBottom: Math.max(insets.bottom, spacing.sm) }]}>
|
||||
<Text variant="caption" color={colors.text.secondary}>{processedText}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
headerCard: {
|
||||
backgroundColor: colors.background.paper,
|
||||
borderRadius: borderRadius.lg,
|
||||
padding: spacing.lg,
|
||||
marginBottom: spacing.md,
|
||||
...shadows.sm,
|
||||
},
|
||||
groupHeader: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
groupInfo: {
|
||||
marginLeft: spacing.lg,
|
||||
flex: 1,
|
||||
},
|
||||
groupName: {
|
||||
marginBottom: spacing.xs,
|
||||
fontWeight: '700',
|
||||
},
|
||||
groupMeta: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: spacing.xs,
|
||||
},
|
||||
groupNoText: {
|
||||
marginTop: spacing.xs,
|
||||
},
|
||||
descriptionContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
backgroundColor: colors.background.default,
|
||||
borderRadius: borderRadius.lg,
|
||||
padding: spacing.md,
|
||||
marginTop: spacing.md,
|
||||
},
|
||||
groupDesc: {
|
||||
marginLeft: spacing.sm,
|
||||
flex: 1,
|
||||
lineHeight: 20,
|
||||
},
|
||||
footer: {
|
||||
paddingHorizontal: spacing.lg,
|
||||
paddingTop: spacing.sm,
|
||||
flexDirection: 'row',
|
||||
backgroundColor: colors.background.default,
|
||||
},
|
||||
btn: {
|
||||
flex: 1,
|
||||
height: 42,
|
||||
borderRadius: borderRadius.md,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
reject: {
|
||||
marginRight: spacing.sm,
|
||||
backgroundColor: colors.error.light + '25',
|
||||
borderWidth: 1,
|
||||
borderColor: colors.error.light,
|
||||
},
|
||||
approve: {
|
||||
marginLeft: spacing.sm,
|
||||
backgroundColor: colors.primary.main,
|
||||
},
|
||||
statusBox: {
|
||||
alignItems: 'center',
|
||||
paddingTop: spacing.sm,
|
||||
backgroundColor: colors.background.default,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user