This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||
import { View, Text, StyleSheet, FlatList, RefreshControl } from "react-native";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { spacing, fontSize } from "../../theme";
|
||||
import { useTheme } from "../../context/ThemeContext";
|
||||
import { getAdminAlerts } from "../../api/api_admin";
|
||||
import type { Alert as AlertType } from "../../api/types";
|
||||
import LoadingSpinner from "../../components/ui/LoadingSpinner";
|
||||
import Card from "../../components/ui/Card";
|
||||
import Badge from "../../components/ui/Badge";
|
||||
|
||||
export default function AlertsScreen() {
|
||||
const { colors } = useTheme();
|
||||
const [alerts, setAlerts] = useState<AlertType[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const loadData = useCallback(async () => {
|
||||
try {
|
||||
const result = await getAdminAlerts();
|
||||
setAlerts(result.alerts);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
setLoading(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, [loadData]);
|
||||
const onRefresh = async () => {
|
||||
setRefreshing(true);
|
||||
await loadData();
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
const styles = useMemo(
|
||||
() =>
|
||||
StyleSheet.create({
|
||||
container: { flex: 1, backgroundColor: colors.bgPrimary },
|
||||
row: { flexDirection: "row", alignItems: "center" },
|
||||
username: {
|
||||
color: colors.textWhite,
|
||||
fontSize: fontSize.md,
|
||||
fontWeight: "600",
|
||||
},
|
||||
alertMessage: {
|
||||
color: colors.danger,
|
||||
fontSize: fontSize.sm,
|
||||
fontWeight: "600",
|
||||
marginTop: 2,
|
||||
},
|
||||
date: {
|
||||
color: colors.textMuted,
|
||||
fontSize: fontSize.xs,
|
||||
marginTop: 2,
|
||||
},
|
||||
empty: {
|
||||
color: colors.textMuted,
|
||||
textAlign: "center",
|
||||
marginTop: spacing.xxl,
|
||||
fontSize: fontSize.md,
|
||||
},
|
||||
}),
|
||||
[colors],
|
||||
);
|
||||
|
||||
const renderAlert = ({ item }: { item: AlertType }) => (
|
||||
<Card style={{ marginBottom: spacing.m }}>
|
||||
<View style={styles.row}>
|
||||
<Ionicons
|
||||
name="alert-circle"
|
||||
size={24}
|
||||
color={
|
||||
item.status === "true"
|
||||
? colors.danger
|
||||
: colors.textMuted
|
||||
}
|
||||
/>
|
||||
<View style={{ flex: 1, marginLeft: spacing.m }}>
|
||||
<Text style={styles.username}>
|
||||
Livreur: {item.username}
|
||||
</Text>
|
||||
{item.message ? (
|
||||
<Text style={styles.alertMessage}>{item.message}</Text>
|
||||
) : null}
|
||||
<Text style={styles.date}>
|
||||
{new Date(item.created_at).toLocaleString("fr-FR")}
|
||||
</Text>
|
||||
</View>
|
||||
<Badge
|
||||
label={item.status === "true" ? "Active" : "Terminée"}
|
||||
color={
|
||||
item.status === "true" ? colors.danger : colors.success
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
|
||||
if (loading) return <LoadingSpinner message="Chargement alertes..." />;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlatList
|
||||
data={alerts}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
renderItem={renderAlert}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={onRefresh}
|
||||
tintColor={colors.accent}
|
||||
/>
|
||||
}
|
||||
contentContainerStyle={{ padding: spacing.l }}
|
||||
ListEmptyComponent={
|
||||
<Text style={styles.empty}>Aucune alerte</Text>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user