import { Ionicons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import { useState } from 'react';
import {
ActivityIndicator,
Pressable,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useLegalData } from '../src/hooks';
import { colors } from '../src/theme';
import type { LegalFAQ, LegalPlan, LegalService, LegalTemplate } from '../src/types';
/* ===================== 子组件:顶部导航 ===================== */
function Header({ onBack }: { onBack: () => void }) {
return (
阿布阿诺法律服务
);
}
/* ===================== 子组件:品牌卡片 ===================== */
function BrandCard({ name, company, slogan, logo }: { name: string; company: string; slogan: string; logo: string }) {
return (
{logo}
{name}
{company}
{slogan}
);
}
/* ===================== 子组件:服务入口 ===================== */
function ServiceCard({ service, onPress }: { service: LegalService; onPress: () => void }) {
const isMember = service.type === 'member';
return (
{service.title}
{isMember && (
会员
)}
{service.description}
);
}
/* ===================== 子组件:FAQ 卡片 ===================== */
function FAQItem({ faq }: { faq: LegalFAQ }) {
const [expanded, setExpanded] = useState(false);
return (
setExpanded((v) => !v)}>
{faq.question}
{expanded && {faq.answer}}
);
}
/* ===================== 子组件:模板卡片 ===================== */
function TemplateCard({ template }: { template: LegalTemplate }) {
return (
{template.name}
{template.description}
);
}
/* ===================== 子组件:会员套餐 ===================== */
function PlanCard({ plan }: { plan: LegalPlan }) {
return (
{plan.recommended && (
推荐
)}
{plan.name}
¥
{plan.price}
{plan.period}
{plan.benefits.map((benefit, idx) => (
{benefit}
))}
);
}
/* ===================== 页面 ===================== */
export default function LegalScreen() {
const router = useRouter();
const { brand, services, faqs, templates, plans, loading, error, refresh } = useLegalData();
const freeServices = services.filter((s) => s.type === 'free');
const memberServices = services.filter((s) => s.type === 'member');
const handleServicePress = (service: LegalService) => {
if (service.action === 'chat') {
router.push('/legal/chat');
} else if (service.action === 'templates') {
// 模板在首页已展示,滚动到模板区更自然;这里简单提示
console.log('[LegalScreen] 查看文书模板');
} else if (service.action === 'faq') {
console.log('[LegalScreen] 查看常见问题');
} else if (service.action === 'upgrade') {
console.log('[LegalScreen] 开通会员');
}
};
return (
router.back()} />
{loading ? (
) : error ? (
加载失败,请重试
重试
) : (
{brand && (
)}
{freeServices.map((service) => (
handleServicePress(service)}
/>
))}
{memberServices.map((service) => (
handleServicePress(service)}
/>
))}
{templates.length > 0 && (
<>
{templates.map((template) => (
))}
>
)}
{faqs.length > 0 && (
<>
{faqs.map((faq) => (
))}
>
)}
{plans.length > 0 && (
<>
{plans.map((plan) => (
))}
>
)}
router.push('/legal/chat')}>
开始法律咨询
)}
);
}
/* ===================== 公共子组件 ===================== */
function SectionTitle({ title }: { title: string }) {
return (
{title}
);
}
const styles = StyleSheet.create({
safeArea: {
flex: 1,
backgroundColor: colors.pageBg,
},
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 8,
height: 48,
backgroundColor: colors.white,
borderBottomWidth: 1,
borderBottomColor: colors.borderLight,
},
headerBtn: {
width: 40,
height: 40,
alignItems: 'center',
justifyContent: 'center',
},
headerTitle: {
fontSize: 17,
fontWeight: '700',
color: colors.textPrimary,
},
scroll: {
flex: 1,
},
content: {
padding: 8,
paddingBottom: 24,
},
brandCard: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.primaryLight,
borderRadius: 8,
padding: 14,
marginBottom: 8,
borderWidth: 1,
borderColor: colors.primaryBorder,
},
brandLogo: {
width: 56,
height: 56,
borderRadius: 28,
backgroundColor: colors.white,
alignItems: 'center',
justifyContent: 'center',
},
brandLogoText: {
fontSize: 28,
},
brandBody: {
flex: 1,
marginLeft: 12,
},
brandName: {
fontSize: 18,
fontWeight: '700',
color: colors.primaryText,
},
brandCompany: {
marginTop: 2,
fontSize: 12,
color: colors.textSecondary,
},
brandSlogan: {
marginTop: 4,
fontSize: 13,
fontWeight: '600',
color: colors.primary,
},
sectionHeader: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 20,
marginBottom: 10,
},
sectionBar: {
width: 4,
height: 16,
borderRadius: 2,
backgroundColor: colors.primary,
marginRight: 8,
},
sectionTitle: {
fontSize: 16,
fontWeight: '700',
color: colors.textPrimary,
},
serviceGrid: {
gap: 8,
},
serviceCard: {
flexDirection: 'row',
alignItems: 'center',
padding: 12,
borderRadius: 8,
backgroundColor: colors.white,
},
serviceCardFree: {
borderLeftWidth: 3,
borderLeftColor: colors.primary,
},
serviceCardMember: {
borderLeftWidth: 3,
borderLeftColor: colors.action,
},
serviceIconWrap: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: colors.pageBg,
alignItems: 'center',
justifyContent: 'center',
},
serviceBody: {
flex: 1,
marginLeft: 12,
marginRight: 8,
},
serviceTitleRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
},
serviceTitle: {
fontSize: 15,
fontWeight: '700',
color: colors.textPrimary,
},
memberTag: {
paddingHorizontal: 6,
paddingVertical: 2,
borderRadius: 4,
backgroundColor: colors.actionLight,
},
memberTagText: {
fontSize: 10,
fontWeight: '700',
color: colors.actionText,
},
serviceDesc: {
marginTop: 2,
fontSize: 12,
color: colors.textSecondary,
lineHeight: 17,
},
templateGrid: {
gap: 8,
},
templateCard: {
flexDirection: 'row',
alignItems: 'center',
padding: 12,
borderRadius: 8,
backgroundColor: colors.white,
},
templateBody: {
flex: 1,
marginLeft: 12,
},
templateName: {
fontSize: 14,
fontWeight: '700',
color: colors.textPrimary,
},
templateDesc: {
marginTop: 2,
fontSize: 12,
color: colors.textSecondary,
},
faqCard: {
backgroundColor: colors.white,
borderRadius: 8,
paddingHorizontal: 12,
},
faqItem: {
paddingVertical: 12,
borderBottomWidth: 1,
borderBottomColor: colors.borderLight,
},
faqRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
faqQ: {
flex: 1,
fontSize: 14,
fontWeight: '600',
color: colors.textPrimary,
marginRight: 8,
},
faqA: {
marginTop: 8,
fontSize: 13,
lineHeight: 19,
color: colors.textSecondary,
},
planGrid: {
flexDirection: 'row',
gap: 8,
},
planCard: {
flex: 1,
padding: 14,
borderRadius: 8,
backgroundColor: colors.white,
borderWidth: 1,
borderColor: colors.border,
},
planCardRecommended: {
borderColor: colors.action,
backgroundColor: colors.actionLight,
},
recommendedTag: {
alignSelf: 'flex-start',
paddingHorizontal: 6,
paddingVertical: 2,
borderRadius: 4,
backgroundColor: colors.action,
marginBottom: 8,
},
recommendedText: {
fontSize: 10,
fontWeight: '700',
color: colors.white,
},
planName: {
fontSize: 15,
fontWeight: '700',
color: colors.textPrimary,
},
planPriceRow: {
flexDirection: 'row',
alignItems: 'baseline',
marginTop: 8,
marginBottom: 10,
},
planCurrency: {
fontSize: 14,
fontWeight: '700',
color: colors.actionText,
},
planPrice: {
fontSize: 28,
fontWeight: '700',
color: colors.actionText,
},
planPeriod: {
fontSize: 13,
color: colors.textSecondary,
},
benefits: {
gap: 6,
},
benefitRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
},
benefitText: {
fontSize: 12,
color: colors.textSecondary,
},
consultBtn: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
marginTop: 20,
height: 48,
borderRadius: 8,
backgroundColor: colors.primaryBtn,
},
consultText: {
fontSize: 15,
fontWeight: '700',
color: colors.white,
},
stateBox: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
stateText: {
marginTop: 12,
fontSize: 14,
color: colors.textSecondary,
},
retryBtn: {
marginTop: 16,
paddingHorizontal: 24,
paddingVertical: 8,
borderRadius: 18,
backgroundColor: colors.primaryBtn,
},
retryText: {
fontSize: 13,
fontWeight: '600',
color: colors.white,
},
});