update tab nhật ký (Lọc, Ngôn ngữ,...)

This commit is contained in:
2025-12-07 20:23:10 +07:00
parent 0672f8adf9
commit e405a0bcfa
17 changed files with 851 additions and 332 deletions

View File

@@ -11,7 +11,33 @@ import {
import { Ionicons } from "@expo/vector-icons";
import StatusDropdown from "./StatusDropdown";
import DateRangePicker from "./DateRangePicker";
import ShipDropdown from "./ShipDropdown";
import { TripStatus } from "./types";
import { useI18n } from "@/hooks/use-i18n";
// Map status number to string - now uses i18n
export function useMapStatusNumberToString() {
const { t } = useI18n();
return (status: TripStatus | null): string => {
switch (status) {
case 0:
return t("diary.tripStatus.created");
case 1:
return t("diary.tripStatus.pending");
case 2:
return t("diary.tripStatus.approved");
case 3:
return t("diary.tripStatus.departed");
case 4:
return t("diary.tripStatus.completed");
case 5:
return t("diary.tripStatus.cancelled");
default:
return "-";
}
};
}
interface FilterModalProps {
visible: boolean;
@@ -19,10 +45,16 @@ interface FilterModalProps {
onApply: (filters: FilterValues) => void;
}
export interface ShipOption {
id: string;
shipName: string;
}
export interface FilterValues {
status: TripStatus | null;
status: TripStatus | null; // number (0-5) hoặc null
startDate: Date | null;
endDate: Date | null;
selectedShip: ShipOption | null; // Tàu được chọn
}
export default function FilterModal({
@@ -30,22 +62,30 @@ export default function FilterModal({
onClose,
onApply,
}: FilterModalProps) {
const { t } = useI18n();
const mapStatusNumberToString = useMapStatusNumberToString();
const [status, setStatus] = useState<TripStatus | null>(null);
const [startDate, setStartDate] = useState<Date | null>(null);
const [endDate, setEndDate] = useState<Date | null>(null);
const [selectedShip, setSelectedShip] = useState<ShipOption | null>(null);
const handleReset = () => {
setStatus(null);
setStartDate(null);
setEndDate(null);
setSelectedShip(null);
};
const handleApply = () => {
onApply({ status, startDate, endDate });
onApply({ status, startDate, endDate, selectedShip });
onClose();
};
const hasFilters = status !== null || startDate !== null || endDate !== null;
const hasFilters =
status !== null ||
startDate !== null ||
endDate !== null ||
selectedShip !== null;
return (
<Modal
@@ -54,12 +94,12 @@ export default function FilterModal({
transparent
onRequestClose={onClose}
>
<TouchableOpacity
<TouchableOpacity
style={styles.overlay}
activeOpacity={1}
onPress={onClose}
>
<TouchableOpacity
<TouchableOpacity
style={styles.modalContainer}
activeOpacity={1}
onPress={(e) => e.stopPropagation()}
@@ -69,7 +109,7 @@ export default function FilterModal({
<TouchableOpacity onPress={onClose} style={styles.closeButton}>
<Ionicons name="close" size={24} color="#111827" />
</TouchableOpacity>
<Text style={styles.title}>Bộ lọc</Text>
<Text style={styles.title}>{t("diary.filter")}</Text>
<View style={styles.placeholder} />
</View>
@@ -85,29 +125,37 @@ export default function FilterModal({
onStartDateChange={setStartDate}
onEndDateChange={setEndDate}
/>
<ShipDropdown value={selectedShip} onChange={setSelectedShip} />
{/* Filter Results Preview */}
{hasFilters && (
<View style={styles.previewContainer}>
<Text style={styles.previewTitle}>Bộ lọc đã chọn:</Text>
{status && (
<Text style={styles.previewTitle}>{t("diary.selectedFilters")}</Text>
{status !== null && (
<View style={styles.filterTag}>
<Text style={styles.filterTagText}>
Trạng thái: {status}
{t("diary.statusLabel")} {mapStatusNumberToString(status)}
</Text>
</View>
)}
{startDate && (
<View style={styles.filterTag}>
<Text style={styles.filterTagText}>
Từ: {startDate.toLocaleDateString("vi-VN")}
{t("diary.fromLabel")} {startDate.toLocaleDateString("vi-VN")}
</Text>
</View>
)}
{endDate && (
<View style={styles.filterTag}>
<Text style={styles.filterTagText}>
Đến: {endDate.toLocaleDateString("vi-VN")}
{t("diary.toLabel")} {endDate.toLocaleDateString("vi-VN")}
</Text>
</View>
)}
{selectedShip && (
<View style={styles.filterTag}>
<Text style={styles.filterTagText}>
{t("diary.shipLabel")} {selectedShip.shipName}
</Text>
</View>
)}
@@ -122,14 +170,14 @@ export default function FilterModal({
onPress={handleReset}
activeOpacity={0.7}
>
<Text style={styles.resetButtonText}>Đt lại</Text>
<Text style={styles.resetButtonText}>{t("diary.reset")}</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.applyButton}
onPress={handleApply}
activeOpacity={0.7}
>
<Text style={styles.applyButtonText}>Áp dụng</Text>
<Text style={styles.applyButtonText}>{t("diary.apply")}</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>