cập nhật phần modal thêm chuyến đi mới
This commit is contained in:
225
components/diary/addTripModal/FishingGearList.tsx
Normal file
225
components/diary/addTripModal/FishingGearList.tsx
Normal file
@@ -0,0 +1,225 @@
|
||||
import React from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
TextInput,
|
||||
} from "react-native";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useI18n } from "@/hooks/use-i18n";
|
||||
import { useThemeContext } from "@/hooks/use-theme-context";
|
||||
|
||||
interface FishingGear {
|
||||
id: string;
|
||||
name: string;
|
||||
number: string;
|
||||
}
|
||||
|
||||
interface FishingGearListProps {
|
||||
items: FishingGear[];
|
||||
onChange: (items: FishingGear[]) => void;
|
||||
}
|
||||
|
||||
export default function FishingGearList({
|
||||
items,
|
||||
onChange,
|
||||
}: FishingGearListProps) {
|
||||
const { t } = useI18n();
|
||||
const { colors } = useThemeContext();
|
||||
|
||||
const handleAddGear = () => {
|
||||
const newGear: FishingGear = {
|
||||
id: Date.now().toString(),
|
||||
name: "",
|
||||
number: "",
|
||||
};
|
||||
onChange([...items, newGear]);
|
||||
};
|
||||
|
||||
const handleRemoveGear = (id: string) => {
|
||||
onChange(items.filter((item) => item.id !== id));
|
||||
};
|
||||
|
||||
const handleDuplicateGear = (gear: FishingGear) => {
|
||||
const duplicatedGear: FishingGear = {
|
||||
id: Date.now().toString(),
|
||||
name: gear.name,
|
||||
number: gear.number,
|
||||
};
|
||||
onChange([...items, duplicatedGear]);
|
||||
};
|
||||
|
||||
const handleUpdateGear = (id: string, field: keyof FishingGear, value: string) => {
|
||||
onChange(
|
||||
items.map((item) =>
|
||||
item.id === id ? { ...item, [field]: value } : item
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const themedStyles = {
|
||||
sectionTitle: { color: colors.text },
|
||||
fieldLabel: { color: colors.text },
|
||||
input: {
|
||||
backgroundColor: colors.card,
|
||||
borderColor: colors.border,
|
||||
color: colors.text,
|
||||
},
|
||||
addButton: {
|
||||
borderColor: colors.primary,
|
||||
},
|
||||
addButtonText: { color: colors.primary },
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={[styles.sectionTitle, themedStyles.sectionTitle]}>
|
||||
{t("diary.fishingGearList")}
|
||||
</Text>
|
||||
|
||||
{/* Gear Items List */}
|
||||
{items.map((gear, index) => (
|
||||
<View key={gear.id} style={styles.gearRow}>
|
||||
{/* Name Input */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={[styles.fieldLabel, themedStyles.fieldLabel]}>
|
||||
{t("diary.gearName")}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={[styles.input, styles.nameInput, themedStyles.input]}
|
||||
value={gear.name}
|
||||
onChangeText={(value) => handleUpdateGear(gear.id, "name", value)}
|
||||
placeholder={t("diary.gearNamePlaceholder")}
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Number Input */}
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={[styles.fieldLabel, themedStyles.fieldLabel]}>
|
||||
{t("diary.gearNumber")}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={[styles.input, styles.numberInput, themedStyles.input]}
|
||||
value={gear.number}
|
||||
onChangeText={(value) => handleUpdateGear(gear.id, "number", value)}
|
||||
placeholder={t("diary.gearNumberPlaceholder")}
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
keyboardType="numeric"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<View style={styles.actionButtons}>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleDuplicateGear(gear)}
|
||||
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
||||
>
|
||||
<Ionicons name="copy-outline" size={20} color={colors.text} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleRemoveGear(gear.id)}
|
||||
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
||||
>
|
||||
<Ionicons name="trash-outline" size={20} color={colors.error} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{/* Add Button */}
|
||||
<TouchableOpacity
|
||||
style={[styles.addButton, themedStyles.addButton]}
|
||||
onPress={handleAddGear}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Ionicons name="add" size={20} color={colors.primary} />
|
||||
<Text style={[styles.addButtonText, themedStyles.addButtonText]}>
|
||||
{t("diary.addFishingGear")}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: "700",
|
||||
marginBottom: 16,
|
||||
fontFamily: Platform.select({
|
||||
ios: "System",
|
||||
android: "Roboto",
|
||||
default: "System",
|
||||
}),
|
||||
},
|
||||
gearRow: {
|
||||
flexDirection: "row",
|
||||
alignItems: "flex-end",
|
||||
gap: 12,
|
||||
marginBottom: 16,
|
||||
},
|
||||
inputGroup: {
|
||||
flex: 1,
|
||||
},
|
||||
fieldLabel: {
|
||||
fontSize: 14,
|
||||
fontWeight: "500",
|
||||
marginBottom: 6,
|
||||
fontFamily: Platform.select({
|
||||
ios: "System",
|
||||
android: "Roboto",
|
||||
default: "System",
|
||||
}),
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1,
|
||||
borderRadius: 8,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 10,
|
||||
fontSize: 15,
|
||||
fontFamily: Platform.select({
|
||||
ios: "System",
|
||||
android: "Roboto",
|
||||
default: "System",
|
||||
}),
|
||||
},
|
||||
nameInput: {
|
||||
flex: 1,
|
||||
},
|
||||
numberInput: {
|
||||
flex: 1,
|
||||
},
|
||||
actionButtons: {
|
||||
flexDirection: "row",
|
||||
gap: 12,
|
||||
alignItems: "center",
|
||||
paddingBottom: 10,
|
||||
},
|
||||
addButton: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
gap: 8,
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
borderWidth: 1.5,
|
||||
borderRadius: 8,
|
||||
borderStyle: "dashed",
|
||||
marginTop: 4,
|
||||
},
|
||||
addButtonText: {
|
||||
fontSize: 14,
|
||||
fontWeight: "600",
|
||||
fontFamily: Platform.select({
|
||||
ios: "System",
|
||||
android: "Roboto",
|
||||
default: "System",
|
||||
}),
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user