diff --git a/app/challenges/[id]/index.tsx b/app/challenges/[id]/index.tsx index 8e07a3e..f72e5a8 100644 --- a/app/challenges/[id]/index.tsx +++ b/app/challenges/[id]/index.tsx @@ -595,7 +595,7 @@ export default function ChallengeDetailScreen() { - {challenge.requirementLabel} + {challenge.requirementLabel ? {challenge.requirementLabel} : null} {t('challengeDetail.shareCard.info.checkInDaily')} @@ -743,7 +743,7 @@ export default function ChallengeDetailScreen() { - {challenge.requirementLabel} + {challenge.requirementLabel ? {challenge.requirementLabel} : null} {t('challengeDetail.detail.requirement')} diff --git a/app/challenges/create-custom.tsx b/app/challenges/create-custom.tsx index 9e093af..12c72de 100644 --- a/app/challenges/create-custom.tsx +++ b/app/challenges/create-custom.tsx @@ -1,3 +1,4 @@ +import i18n from '@/i18n'; import dayjs from 'dayjs'; import { BlurView } from 'expo-blur'; import * as Clipboard from 'expo-clipboard'; @@ -53,6 +54,7 @@ const getTypeOptions = (t: (key: string) => string): { value: ChallengeType; lab { value: ChallengeType.SLEEP, label: t('challenges.createCustom.typeLabels.sleep'), accent: '#7C3AED' }, { value: ChallengeType.MOOD, label: t('challenges.createCustom.typeLabels.mood'), accent: '#F97316' }, { value: ChallengeType.WEIGHT, label: t('challenges.createCustom.typeLabels.weight'), accent: '#22C55E' }, + { value: ChallengeType.CUSTOM, label: t('challenges.createCustom.typeLabels.custom'), accent: '#8B5CF6' }, ]; const FALLBACK_IMAGE = @@ -97,7 +99,7 @@ export default function CreateCustomChallengeScreen() { const [progressUnit, setProgressUnit] = useState(''); const [periodLabel, setPeriodLabel] = useState(''); const [periodEdited, setPeriodEdited] = useState(false); - const [rankingDescription] = useState('连续打卡榜'); + const [rankingDescription] = useState(t('challenges.createCustom.rankingDescription')); const [isPublic, setIsPublic] = useState(true); const [maxParticipants, setMaxParticipants] = useState('100'); const [minimumEdited, setMinimumEdited] = useState(false); @@ -121,7 +123,6 @@ export default function CreateCustomChallengeScreen() { setEndDate(new Date(challenge.endAt || Date.now())); setTargetValue(String(challenge.progress?.target || '')); setMinimumCheckInDays(String(challenge.minimumCheckInDays || '')); - setRequirementLabel(challenge.requirementLabel || ''); setSummary(challenge.summary || ''); setProgressUnit(challenge.unit || ''); setPeriodLabel(challenge.periodLabel || ''); @@ -177,10 +178,6 @@ export default function CreateCustomChallengeScreen() { return; } - if (!requirementLabel.trim()) { - Toast.warning(t('challenges.createCustom.alerts.requirementRequired')); - return; - } const startTimestamp = dayjs(startDate).valueOf(); const endTimestamp = dayjs(endDate).valueOf(); @@ -221,7 +218,7 @@ export default function CreateCustomChallengeScreen() { targetValue: target, minimumCheckInDays: minDays, durationLabel, - requirementLabel: requirementLabel.trim(), + requirementLabel: '', summary: summary.trim() || undefined, progressUnit: progressUnit.trim(), periodLabel: periodLabel.trim() || undefined, @@ -513,16 +510,19 @@ export default function CreateCustomChallengeScreen() { setType(option.value)} + onPress={() => !isEditMode && setType(option.value)} + disabled={isEditMode} style={[ styles.chip, active && { backgroundColor: `${option.accent}1A`, borderColor: option.accent }, + isEditMode && styles.chipDisabled, ]} > {option.label} @@ -531,6 +531,7 @@ export default function CreateCustomChallengeScreen() { ); })} + {t('challenges.createCustom.fields.challengeTypeHelper')} @@ -592,7 +593,6 @@ export default function CreateCustomChallengeScreen() { {renderField(t('challenges.createCustom.fields.minimumCheckInDays'), minimumCheckInDays, handleMinimumDaysChange, t('challenges.createCustom.fields.minimumCheckInDaysPlaceholder'), 'numeric')} - {renderField(t('challenges.createCustom.fields.challengeRequirement'), requirementLabel, setRequirementLabel, t('challenges.createCustom.fields.requirementPlaceholder'))} @@ -675,6 +675,9 @@ export default function CreateCustomChallengeScreen() { minimumDate={pickerType === 'end' ? dayjs(startDate).add(1, 'day').toDate() : dayjs().add(1, 'day').toDate()} onConfirm={handleConfirmDate} onCancel={() => setPickerType(null)} + locale={i18n.language} + confirmTextIOS={t('challenges.createCustom.datePicker.confirm')} + cancelTextIOS={t('challenges.createCustom.datePicker.cancel')} />